{"id":13787796,"url":"https://github.com/Turall/OPA-python-client","last_synced_at":"2025-05-12T02:30:27.596Z","repository":{"id":38359430,"uuid":"225400958","full_name":"Turall/OPA-python-client","owner":"Turall","description":"Python client for Open Policy Agent ","archived":false,"fork":false,"pushed_at":"2024-12-11T06:21:37.000Z","size":140,"stargazers_count":49,"open_issues_count":3,"forks_count":13,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-04T19:09:38.294Z","etag":null,"topics":["opa","opa-client","open-policy-agent","open-policy-agent-python","policy","python","python-opa-client"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Turall.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-02T15:00:23.000Z","updated_at":"2025-04-03T01:50:01.000Z","dependencies_parsed_at":"2025-01-11T19:11:39.608Z","dependency_job_id":"ad537c10-e69a-4f96-943d-4053f184e3df","html_url":"https://github.com/Turall/OPA-python-client","commit_stats":{"total_commits":49,"total_committers":8,"mean_commits":6.125,"dds":"0.36734693877551017","last_synced_commit":"10d5e42a8c52062cbabb5746aa1f68ebbccd87fe"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Turall%2FOPA-python-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Turall%2FOPA-python-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Turall%2FOPA-python-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Turall%2FOPA-python-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Turall","download_url":"https://codeload.github.com/Turall/OPA-python-client/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253662519,"owners_count":21944090,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["opa","opa-client","open-policy-agent","open-policy-agent-python","policy","python","python-opa-client"],"created_at":"2024-08-03T21:00:31.360Z","updated_at":"2025-05-12T02:30:27.210Z","avatar_url":"https://github.com/Turall.png","language":"Python","funding_links":[],"categories":["Language and Platform Integrations"],"sub_categories":["Python"],"readme":"\n# OpaClient - Open Policy Agent Python Client\n[![MIT licensed](https://img.shields.io/github/license/Turall/OPA-python-client)](https://raw.githubusercontent.com/Turall/OPA-python-client/master/LICENSE)\n[![GitHub stars](https://img.shields.io/github/stars/Turall/OPA-python-client.svg)](https://github.com/Turall/OPA-python-client/stargazers)\n[![GitHub forks](https://img.shields.io/github/forks/Turall/OPA-python-client.svg)](https://github.com/Turall/OPA-python-client/network)\n[![GitHub issues](https://img.shields.io/github/issues-raw/Turall/OPA-python-client)](https://github.com/Turall/OPA-python-client/issues)\n[![Downloads](https://pepy.tech/badge/opa-python-client)](https://pepy.tech/project/opa-python-client)\n\nOpaClient is a Python client library designed to interact with the [Open Policy Agent (OPA)](https://www.openpolicyagent.org/). It supports both **synchronous** and **asynchronous** requests, making it easy to manage policies, data, and evaluate rules in OPA servers.\n\n## Features\n\n- **Manage Policies**: Create, update, retrieve, and delete policies.\n- **Manage Data**: Create, update, retrieve, and delete data in OPA.\n- **Evaluate Policies**: Use input data to evaluate policies and return decisions.\n- **Synchronous \u0026 Asynchronous**: Choose between sync or async operations to suit your application.\n- **SSL/TLS Support**: Communicate securely with SSL/TLS, including client certificates.\n- **Customizable**: Use custom headers, timeouts, and other configurations.\n\n## Installation\n\nYou can install the OpaClient package via `pip`:\n\n```bash\npip install opa-python-client\n```\n\n## Quick Start\n\n### Synchronous Client Example\n\n```python\nfrom opa_client.opa import OpaClient\n\n# Initialize the OPA client\nclient = OpaClient(host='localhost', port=8181)\n\n# Check the OPA server connection\ntry:\n    print(client.check_connection())  # True\nfinally:\n    client.close_connection()\n```\nor with client factory\n\n```python\nfrom opa_client import create_opa_client\n\nclient = create_opa_client(host=\"localhost\", port=8181)\n\n```\n\nCheck OPA healthy. If you want check bundels or plugins, add query params for this.\n\n```python\nfrom opa_client.opa import OpaClient\n\nclient = OpaClient()\n\nprint(client.check_health()) # response is  True or False\nprint(client.check_health({\"bundle\": True})) # response is  True or False\n# If your diagnostic url different than default url, you can provide it.\nprint(client.check_health(diagnostic_url=\"http://localhost:8282/health\"))  # response is  True or False\nprint(client.check_health(query={\"bundle\": True}, diagnostic_url=\"http://localhost:8282/health\"))  # response is  True or False\n```\n\n### Asynchronous Client Example\n\n```python\nimport asyncio\nfrom opa_client.opa_async import AsyncOpaClient\n\nasync def main():\n    async with AsyncOpaClient(host='localhost', port=8181) as client:\n        result = await client.check_connection()\n        print(result)\n\n# Run the async main function\nasyncio.run(main())\n```\nor with clien factory\n\n```python\nfrom opa_client import create_opa_client\n\nclient = create_opa_client(async_mode=True,host=\"localhost\", port=8181)\n\n```\n\n## Secure Connection with SSL/TLS\n\nYou can use OpaClient with secure SSL/TLS connections, including mutual TLS (mTLS), by providing a client certificate and key.\n\n### Synchronous Client with SSL/TLS\n\n```python\nfrom opa_client.opa import OpaClient\n\n# Path to your certificate and private key\ncert_path = '/path/to/client_cert.pem'\nkey_path = '/path/to/client_key.pem'\n\n# Initialize the OPA client with SSL/TLS\nclient = OpaClient(\n    host='your-opa-server.com',\n    port=443,  # Typically for HTTPS\n    ssl=True,\n    cert=(cert_path, key_path)  # Provide the certificate and key as a tuple\n)\n\n# Check the OPA server connection\ntry:\n    result = client.check_connection()\n    print(result)\nfinally:\n    client.close_connection()\n```\n\n### Asynchronous Client with SSL/TLS\n\n```python\nimport asyncio\nfrom opa_client.opa_async import AsyncOpaClient\n\n# Path to your certificate and private key\ncert_path = '/path/to/client_cert.pem'\nkey_path = '/path/to/client_key.pem'\n\nasync def main():\n    # Initialize the OPA client with SSL/TLS\n    async with AsyncOpaClient(\n        host='your-opa-server.com',\n        port=443,  # Typically for HTTPS\n        ssl=True,\n        cert=(cert_path, key_path)  # Provide the certificate and key as a tuple\n    ) as client:\n        # Check the OPA server connection\n        result = await client.check_connection()\n        print(result)\n\n# Run the async main function\nasyncio.run(main())\n```\n\n## Usage\n\n### Policy Management\n\n#### Create or Update a Policy\n\nYou can create or update a policy using the following syntax:\n\n- **Synchronous**:\n\n```python\npolicy_name = 'example_policy'\npolicy_content = '''\npackage example\n\ndefault allow = false\n\nallow {\n    input.user == \"admin\"\n}\n'''\n\nclient.update_policy_from_string(policy_content, policy_name)\n```\n\n- **Asynchronous**:\n\n```python\nawait client.update_policy_from_string(policy_content, policy_name)\n```\n\nOr from url:\n\n- **Synchronous**:\n\n```python\npolicy_name = 'example_policy'\n\nclient.update_policy_from_url(\"http://opapolicyurlexample.test/example.rego\", policy_name) \n\n```\n\n- **Asynchronous**:\n\n```python\nawait client.update_policy_from_url(\"http://opapolicyurlexample.test/example.rego\", policy_name) \n```\n\nUpdate policy from rego file\n\n```python\nclient.update_opa_policy_fromfile(\"/your/path/filename.rego\", endpoint=\"fromfile\") # response is True\n\nclient.get_policies_list()\n```\n\n- **Asynchronous**:\n```python\nawait client.update_opa_policy_fromfile(\"/your/path/filename.rego\", endpoint=\"fromfile\") # response is True\n\nawait client.get_policies_list()\n```\n\n#### Retrieve a Policy\n\nAfter creating a policy, you can retrieve it:\n\n- **Synchronous**:\n\n```python\npolicy = client.get_policy('example_policy')\nprint(policy)\n# or\npolicies = client.get_policies_list()\nprint(policies)\n```\n\n- **Asynchronous**:\n\n```python\npolicy = await client.get_policy('example_policy')\nprint(policy)\n\n# or\npolicies = await client.get_policies_list()\nprint(policies)\n```\n\nSave policy to file from OPA service\n\n```python\nclient.policy_to_file(policy_name=\"example_policy\",path=\"/your/path\",filename=\"example.rego\")\n\n```\n\n- **Asynchronous**:\n\n```python\n\nawait client.policy_to_file(policy_name=\"example_policy\",path=\"/your/path\",filename=\"example.rego\")\n\n```\n\nInformation about policy path and rules\n\n```python\n\nprint(client.get_policies_info())\n#{'example_policy': {'path': 'http://localhost:8181/v1/data/example', 'rules': ['http://localhost:8181/v1/data/example/allow']}}\n\n```\n- **Asynchronous**:\n\n\n```python\n\nprint(await client.get_policies_info())\n#{'example_policy': {'path': 'http://localhost:8181/v1/data/example', 'rules': ['http://localhost:8181/v1/data/example/allow']}}\n\n```\n\n#### Delete a Policy\n\nYou can delete a policy by name:\n\n- **Synchronous**:\n\n```python\nclient.delete_policy('example_policy')\n```\n\n- **Asynchronous**:\n\n```python\nawait client.delete_policy('example_policy')\n```\n\n### Data Management\n\n#### Create or Update Data\n\nYou can upload arbitrary data to OPA:\n\n- **Synchronous**:\n\n```python\ndata_name = 'users'\ndata_content = {\n    \"users\": [\n        {\"name\": \"alice\", \"role\": \"admin\"},\n        {\"name\": \"bob\", \"role\": \"user\"}\n    ]\n}\n\nclient.update_or_create_data(data_content, data_name)\n```\n\n- **Asynchronous**:\n\n```python\nawait client.update_or_create_data(data_content, data_name)\n```\n\n#### Retrieve Data\n\nYou can fetch the data stored in OPA:\n\n- **Synchronous**:\n\n```python\ndata = client.get_data('users')\nprint(data)\n# You can use query params for additional info\n# provenance - If parameter is true, response will include build/version info in addition to the result.\n# metrics - Return query performance metrics in addition to result \ndata = client.get_data('users',query_params={\"provenance\": True})\nprint(data) # {'provenance': {'version': '0.68.0', 'build_commit': 'db53d77c482676fadd53bc67a10cf75b3d0ce00b', 'build_timestamp': '2024-08-29T15:23:19Z', 'build_hostname': '3aae2b82a15f'}, 'result': {'users': [{'name': 'alice', 'role': 'admin'}, {'name': 'bob', 'role': 'user'}]}}\n\n\ndata = client.get_data('users',query_params={\"metrics\": True})\nprint(data) # {'metrics': {'counter_server_query_cache_hit': 0, 'timer_rego_external_resolve_ns': 7875, 'timer_rego_input_parse_ns': 875, 'timer_rego_query_compile_ns': 501083, 'timer_rego_query_eval_ns': 50250, 'timer_rego_query_parse_ns': 199917, 'timer_server_handler_ns': 1031291}, 'result': {'users': [{'name': 'alice', 'role': 'admin'}, {'name': 'bob', 'role': 'user'}]}}\n\n\n```\n\n- **Asynchronous**:\n\n```python\ndata = await client.get_data('users')\nprint(data)\n```\n\n#### Delete Data\n\nTo delete data from OPA:\n\n- **Synchronous**:\n\n```python\nclient.delete_data('users')\n```\n\n- **Asynchronous**:\n\n```python\nawait client.delete_data('users')\n```\n\n### Policy Evaluation\n\n#### Check Permission (Policy Evaluation)\n\nYou can evaluate policies with input data using `check_permission`.\n\n- **Synchronous**:\n\n```python\ninput_data = {\"user\": \"admin\"}\npolicy_name = 'example_policy'\nrule_name = 'allow'\n\nresult = client.check_permission(input_data, policy_name, rule_name)\nprint(result)\n```\n\n- **Asynchronous**:\n\n```python\ninput_data = {\"user\": \"admin\"}\npolicy_name = 'example_policy'\nrule_name = 'allow'\n\nresult = await client.check_permission(input_data, policy_name, rule_name)\nprint(result)\n```\n\nQueries a package rule with the given input data\n\n```python\n\nrego = \"\"\"\npackage play\n\ndefault hello = false\n\nhello {\n    m := input.message\n    m == \"world\"\n}\n\"\"\"\n\ncheck_data = {\"message\": \"world\"}\n\nclient.update_policy_from_string(rego, \"test\")\nprint(client.query_rule(input_data=check_data, package_path=\"play\", rule_name=\"hello\")) # {'result': True}\n\n```\n\n- **Asynchronous**:\n\n```python\n\nrego = \"\"\"\npackage play\n\ndefault hello = false\n\nhello {\n    m := input.message\n    m == \"world\"\n}\n\"\"\"\n\ncheck_data = {\"message\": \"world\"}\n\nawait client.update_policy_from_string(rego, \"test\")\nprint(await client.query_rule(input_data=check_data, package_path=\"play\", rule_name=\"hello\")) # {'result': True}\n\n```\n\n### Ad-hoc Queries\n\nExecute ad-hoc queries directly:\n\n- **Synchronous**:\n\n```python\ndata = {\n    \"user_roles\": {\n        \"alice\": [\n            \"admin\"\n        ],\n        \"bob\": [\n            \"employee\",\n            \"billing\"\n        ],\n        \"eve\": [\n            \"customer\"\n        ]\n    }\n}\ninput_data = {\"user\": \"admin\"}\nclient.update_or_create_data(data, \"userinfo\")\n\nresult = client.ad_hoc_query(query=\"data.userinfo.user_roles[name]\")\nprint(result) # {'result': [{'name': 'alice'}, {'name': 'bob'}, {'name': 'eve'}]}\n```\n\n- **Asynchronous**:\n\n```python\ndata = {\n    \"user_roles\": {\n        \"alice\": [\n            \"admin\"\n        ],\n        \"bob\": [\n            \"employee\",\n            \"billing\"\n        ],\n        \"eve\": [\n            \"customer\"\n        ]\n    }\n}\ninput_data = {\"user\": \"admin\"}\nawait client.update_or_create_data(data, \"userinfo\")\n\nresult = await client.ad_hoc_query(query=\"data.userinfo.user_roles[name]\")\nprint(result) # {'result': [{'name': 'alice'}, {'name': 'bob'}, {'name': 'eve'}]}\n```\n\n## API Reference\n\n### Synchronous Client (OpaClient)\n\n- `check_connection()`: Verify connection to OPA server.\n- `get_policies_list()`: Get a list of all policies.\n- `get_policies_info()`: Returns information about each policy, including policy path and policy rules.\n- `get_policy(policy_name)`: Fetch a specific policy.\n- `policy_to_file(policy_name)`: Save an OPA policy to a file..\n- `update_policy_from_string(policy_content, policy_name)`: Upload or update a policy using its string content.\n- `update_policy_from_url(url,endpoint)`: Update OPA policy by fetching it from a URL.\n- `update_policy_from_file(filepath,endpoint)`: Update OPA policy using a policy file.\n- `delete_policy(policy_name)`: Delete a specific policy.\n- `update_or_create_data(data_content, data_name)`: Create or update data in OPA.\n- `get_data(data_name)`: Retrieve data from OPA.\n- `delete_data(data_name)`: Delete data from OPA.\n- `check_permission(input_data, policy_name, rule_name)`: Evaluate a policy using input data.\n- `query_rule(input_data, package_path, rule_name)`: Query a specific rule in a package.\n- `ad_hoc_query(query, input_data)`: Run an ad-hoc query.\n\n### Asynchronous Client (AsyncOpaClient)\n\nSame as the synchronous client, but all methods are asynchronous and must be awaited.\n\n## Contributing\n\nContributions are welcome! Feel free to open issues, fork the repo, and submit pull requests.\n\n## License\n\nThis project is licensed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTurall%2FOPA-python-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FTurall%2FOPA-python-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTurall%2FOPA-python-client/lists"}