{"id":22787403,"url":"https://github.com/aserto-dev/aserto-python","last_synced_at":"2025-09-10T23:39:58.863Z","repository":{"id":44569019,"uuid":"394559554","full_name":"aserto-dev/aserto-python","owner":"aserto-dev","description":"Aserto Python SDK","archived":false,"fork":false,"pushed_at":"2023-12-19T13:15:38.000Z","size":490,"stargazers_count":4,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2023-12-19T16:03:54.489Z","etag":null,"topics":["authorization","authorization-middleware","flask-middleware","python3"],"latest_commit_sha":null,"homepage":"https://docs.aserto.com/docs/software-development-kits/python/api-client","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aserto-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-08-10T07:14:00.000Z","updated_at":"2023-12-21T14:07:35.317Z","dependencies_parsed_at":"2023-12-19T16:02:55.136Z","dependency_job_id":null,"html_url":"https://github.com/aserto-dev/aserto-python","commit_stats":{"total_commits":15,"total_committers":3,"mean_commits":5.0,"dds":0.4,"last_synced_commit":"508661f5ad9bab42b3c16cf7f3f9e1843c8981b2"},"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aserto-dev%2Faserto-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aserto-dev%2Faserto-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aserto-dev%2Faserto-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aserto-dev%2Faserto-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aserto-dev","download_url":"https://codeload.github.com/aserto-dev/aserto-python/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229313608,"owners_count":18053714,"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":["authorization","authorization-middleware","flask-middleware","python3"],"created_at":"2024-12-12T00:56:44.858Z","updated_at":"2024-12-12T00:56:45.340Z","avatar_url":"https://github.com/aserto-dev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Aserto API client\n\nHigh-level client interface to Aserto's APIs.\n\n## Authorizer\nThe client can be used for interacting with Aserto's [Authorizer service](https://docs.aserto.com/docs/authorizer-guide/overview).\n\n## Installation\n\n### Using Pip\n\n```sh\npip install aserto\n```\n\n### Using Poetry\n\n```sh\npoetry add aserto\n```\n\n## Usage\n\n```py\nfrom aserto.client import AuthorizerOptions, Identity\nfrom aserto.client.authorizer import AuthorizerClient\n\n\nclient = AuthorizerClient(\n    identity=Identity(type=\"NONE\"),\n    options=AuthorizerOptions(\n        api_key=ASERTO_API_KEY,\n        tenant_id=ASERTO_TENANT_ID,\n    ),\n)\n\nresult = await client.decision_tree(\n    decisions=[\"visible\", \"enabled\", \"allowed\"],\n    policy_instance_name=ASERTO_POLICY_INSTANCE_NAME,\n    policy_instance_label=ASERTO_POLICY_INSTANCE_LABEL,\n    policy_path_root=ASERTO_POLICY_PATH_ROOT,\n    policy_path_separator=\"DOT\",\n)\n\nassert result == {\n    \"GET.your.policy.path\": {\n        \"visible\": True,\n        \"enabled\": True,\n        \"allowed\": False,\n    },\n}\n```\n\n## Directory\n\nThe Directory APIs can be used to interact with the aserto directory services.\nIt provides CRUD operations on objects and relations, including bulk import and export.\nThe client can also be used to check whether a user has a permission or relation on an object instance.\n\n### Directory Client\n\nYou can initialize a directory client as follows:\n\n```py\nfrom aserto.client.directory.v3 import Directory\n\nds = Directory(api_key=\"my_api_key\", tenant_id=\"1234\", address=\"localhost:9292\")\n```\n\n- `address`: hostname:port of directory service (_required_)\n- `api_key`: API key for directory service (_required_ if using hosted directory)\n- `tenant_id`: Aserto tenant ID (_required_ if using hosted directory)\n- `cert`: Path to the grpc service certificate when connecting to local topaz instance.\n\n#### `get_object`\n\nGet a directory object instance with the type and the id, optionally with the object's relations.\n\n```py\n# without relations:\nuser = ds.get_object(object_type=\"user\", object_id=\"euang@acmecorp.com\")\n\n# with relations:\npage = PaginationRequest(size=10)\nwhile True:\n    resp = ds.get_object(object_type=\"user\", object_id=\"euang@acmecorp.com\", with_relations=True, page=page)\n    user = resp.result               # The returned object.\n    relations_page = resp.relations  # A page of relations.\n\n    if not resp.page.next_token:\n        # we've reached the last page.\n        break\n\n    # request the next page.\n    page.token = resp.page.next_token\n\n```\n\n#### `get_objects_many`\n\nSimilar to `get_object` but can retrieve multiple object instances in a single request.\n```py\nobjects = ds.get_object_many(\n    [\n        ObjectIdentifier(type=\"user\", id=\"euan@acmecorp.com\"),\n        ObjectIdentifier(type=\"group\", id=\"marketing\"),\n    ]\n)\n```\n\n#### `get_objects`\n\nGet object instances with an object type type pagination info (page size and pagination token).\n\n```py\nfrom aserto.client.directory.v3 import PaginationRequest\n\nusers = ds.get_objects(object_type=\"user\", page=PaginationRequest(size=10))\n```\n\n\n#### `set_object`\n\nCreate an object instance with the specified properties. If an `etag` is specified and is different from the current\nobject's etag, the call raises an `ETagMismatchError`.\n\n```py\n# pass object fields as arguments:\nuser = ds.set_object(\n    object_type=\"user\",\n    object_id=\"new-user@acmecorp.com\",\n    display_name=\"John Doe\",\n    \"properties\": {\"active\": True, \"department\": \"Engineering\"},\n}\n\n# set_object can also take an Object parameter:\nuser.display_name = \"Jane Doe\"\nuser.properties[\"title\"] = \"Senior Engineer\"\nupdated_user = ds.set_object(object=user)\n```\n\n#### `delete_object`\n\nDelete an object instance and optionally its relations, using its type and id:\n\n```py\n# delete an object\nds.delete_object(object_type=\"user\", object_id=\"test-object\")\n\n# delete an object and all its relations\nds.delete_object(object_type=\"user\", object_id=\"test-object\", with_relations=True)\n```\n\n#### `get_relation`\n\nRetrieve a single relation from the directory or raise a `NotFoundError` if no matching relation exists.\n\n```py\n# get the manager of euang@acmecorp.com:\nrelation = ds.get_relation(\n    object_type=\"user\",\n    relation=\"manager\",\n    subject_type=\"user\",\n    subject_id=\"euang@acmecorp.com\",\n)\n\nassert relation.object_id\n\n# include the relation's object and subject in the response:\nresponse = ds.get_relation(\n    object_type=\"user\",\n    relation=\"manager\",\n    subject_type=\"user\",\n    subject_id=\"euang@acmecorp.com\",\n    with_relations=True,\n)\n\nassert response.relation.object_id\nassert response.subject.display_name == \"Euan Garden\"\nassert response.object.properties[\"department\"] == \"Sales\"\n#\n```\n\n#### `get_relations`\n\nSearches the directory for relations matching the specified criteria, optionally including the object and subject\nof each returned relation.\n\n```py\n# find all groups a user is a member of:\npage = PaginationRequest(size=10)\n\nwhile True:\n    response = ds.get_relations(\n        object_type=\"group\",\n        \"relation\"=\"member\",\n        \"subject_type\": \"user\",\n        \"subject_id\": \"euang@acmecorp.com\",\n        with_objects=True,\n        page=page,\n    )\n\n    if not response.page.next_token:\n        break\n\n    page.token = response.page.next_token\n```\n\n#### `set_relation`\n\nCreate a new relation.\n\n```py\nds.set_relation(\n    object_type=\"group\",\n    object_id=\"admin\",\n    relation=\"member\",\n    subject_type=\"user\",\n    subject_id=\"euang@acmecorp.com\",\n)\n```\n\n#### `delete_relation`\n\nDelete a relation.\n\n```py\nds.delete_relation(\n    object_type=\"group\",\n    object_id=\"admin\",\n    relation=\"member\",\n    subject_type=\"user\",\n    subject_id=\"euang@acmecorp.com\",\n)\n```\n\n#### `check`\n\nCheck if a subject has a given relation or permission on an object.\n\n```py\nallowed = ds.check(\n    object_type=\"folder\",\n    object_id=\"/path/to/folder\",\n    relation=\"can_delete\",\n    subject_type=\"user\",\n    subject_id=\"euang@acmecorp.com\",\n)\n```\n\n#### `find_subjects`\n\nFind subjects that have a given relation to or permission on a specified object.\n\n```py\nreponse = ds.find_subjects(\n    object_type=\"folder\",\n    object_id=\"/path/to/folder\",\n    relation=\"can_delete\",\n    subject_type=\"user\"\n)\n\nassert ObjectIdentifier(\"user\", \"euang@acmecorp.com\") in response.results\n```\n\n#### `find_objects`\n\nFind objects that a given subject has a specified relation to or permission on.\n\n```py\nreponse = ds.find_objects(\n    object_type=\"folder\",\n    relation=\"can_delete\",\n    subject_type=\"user\"\n    subjecct_id=\"euang@acmecorp.com\"\n)\n\nassert ObjectIdentifier(\"folder\", \"/path/to/folder\") in response.results\n```\n\n#### `get_manifest `\n\nDownload the directory manifest.\n\n```py\nmanifest = ds.get_manifest()\n\nprint(manifest.body)    # yaml manifest\n\n# conditionally get the manifest if its etag has changed\nnew_manifest = ds.get_manifest(etag=manifest.etag)\n\nassert new_manifest is None   # the manifest hasn't changed\n```\n\n#### `set_manifest`\n\nUpload a new directory manifest.\n\n```py\nwith open(\"manifest.yaml\", \"rb\") as f:\n    manifest = f.read()\n\nds.set_manifest(manifest)\n```\n\n#### `import_data`\n\nBulk-insert objects and/or relations to the directory. Returns a summary of the number of objects/relations affected.\n\n```py\n# import an object and a relation.\ndata = [\n    Object(type=\"user\", id=\"test@acmecorp.com\"),\n    Relation(\n        object_type=\"user\",\n        object_id=\"euang@acmecorp.com\",\n        relation=\"manager\",\n        subject_type=\"user\",\n        subject_id=\"test@acmecorp.com\",\n    ),\n]\n\nresponse = ds.import_data(data)\n\nassert response.objects.set == 1\nassert response.object.error == 0\nassert response.relations.set == 1\nassert response.relations.error == 0\n```\n\n#### `export_data`\n\nBulk-retrieve objects and/or relations from the directory.\n\n\n```py\nfrom aserto.client.directory.v3 import ExportOption, Object, Relation\n\n# export all objects and relations\nfor item in ds.export(ExportOption.OPTION_DATA):\n    if isinstance(item, Object):\n        print(\"object:\", item)\n    elif isinstance(item, Relation):\n        print(\"relation:\", item)\n```\n\n### Async Directory Client\n\nYou can initialize an asynchronous directory client as follows:\n\n```py\nfrom aserto.client.directory.v3.aio import Directory\n\nds = Directory(api_key=\"my_api_key\", tenant_id=\"1234\", address=\"localhost:9292\")\n```\n\nThe methods on the async directory have the same signatures as their synchronous counterparts.\n\n## License\n\nThis project is licensed under the MIT license. See the [LICENSE](https://github.com/aserto-dev/aserto-python/blob/main/LICENSE) file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faserto-dev%2Faserto-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faserto-dev%2Faserto-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faserto-dev%2Faserto-python/lists"}