Python Client Library

Installation#

Authzed ships a client library for Python at https://github.com/authzed/authzed-py, which can be installed via pip:

pip install authzed

Defining Models#

The Authzed Python client supports an ORM-like mechanism for easier interaction with the Authzed API..

Models can be defined in the Python code via class defintions, and then used to directly issue Check and Write calls, without having to call the API directly.

Example: Simple namespaces#

Starting with a simple set of namespace configurations:

Namespace configurations#

name: "mytenant/user"
name: "mytenant/document"
relation { name: "viewer" }
relation {
name: "writer"
userset_rewrite { .... }
}

We can translate them into model definitions:

from arrakisclient.types.namespace import ArrakisNamespace, Relation
class ReferenceableNamespace(ArrakisNamespace):
ellipsis = Relation(relation_name="...")
class User(ReferenceableNamespace):
__namespace__ = "mytenant/user"
class Document(ReferenceableNamespace):
__namespace__ = "mytenant/document"
viewer = Relation(User)
writer = Relation(User)

Note here that the Relation references are well-typed: we indicate the kind of objects that can be applied in the relation.

Setting up the client#

All API requests to Authzed in the Python client must be made via a ArrakisClient instance, which keeps a reference to the authentication token for the calling application:

from arrakisclient.client import ArrakisClient
... model definitions ...
token = "t_your_token_here_1234567deadbeef"
client = ArrakisClient(User, Document, access_token=token)

Note that we include the created model definitions in the constructor to ArrakisClient.

Checking#

To Check, the client provides the check call.

Checking Example#

Let's say we wanted to check if a user has viewer permission on a document.

To do so via the Python client, we would first construct the objects we are referencing (here, the document and the user):

somedocument = Document("somedocument")
someuser = User("someuser")

Next, we would load the most recently stored Zookie for the document from our database:

document_revision = somedocument_db_row.revision

Finally, we'd issue the check result:

from arrakisclient.types.tuple import ArrakisUserset
... load the document row from our database ...
document_revision = somedocument_db_row.revision
somedocument = Document("somedocument")
someuser = User("someuser")
can_view = client.check(somedocument.read,
ArrakisUserset.from_onr(someuser.ellipsis), document_revision)

can_view is an object that can be implicitly converted to bool:

from arrakisclient.types.tuple import ArrakisUserset
... load the document row from our database ...
document_revision = somedocument_db_row.revision
somedocument = Document("somedocument")
someuser = User("someuser")
can_view = client.check(somedocument.read,
ArrakisUserset.from_onr(someuser.ellipsis),
document_revision)
if can_view:
# User can view the document.

Writing some tuples#

To Write, the client provides the batch_write call.

Writing Example#

Let's say we wanted to write some permissions for users on some documents:

mytenant/document:somedocument#viewer@mytenant/user:someuser#...
mytenant/document:somedocument#writer@mytenant/user:anotheruser#...

To do so via the Python client, we would first construct the objects we are referencing (here, the document and the users):

somedocument = Document("somedocument")
someuser = User("someuser")
anotheruser = User("anotheruser")

Next, we can call batch_write to write the permission tuples:

somedocument = Document("somedocument")
someuser = User("someuser")
anotheruser = User("anotheruser")
with client.batch_write() as w:
w.create(somedocument.viewer(someuser.ellipsis))
w.create(somedocument.writer(anotheruser.ellipsis))

Finally, we save the returned Zookie on the document:

somedocument = Document("somedocument")
someuser = User("someuser")
anotheruser = User("anotheruser")
with client.batch_write() as w:
w.create(somedocument.viewer(someuser.ellipsis))
w.create(somedocument.writer(anotheruser.ellipsis))
# Store the updated revision for the document (in our database).
somedocument_db_row.revision = w.revision
somedocument_db_row.save()

Full Example#

A full example can be found at https://github.com/authzed/authzed-py/tree/main/examples