Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more realistic bulk import example #219

Merged
merged 7 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion examples/v1/bulk_import_export_relationships.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
"""
This demonstrates the simplest possible usage of the bulk
import and export functionality. See import_bulk_relationships.py
for a more realistic example of batching.
"""

from authzed.api.v1 import (
BulkExportRelationshipsRequest,
BulkImportRelationshipsRequest,
Expand Down Expand Up @@ -60,7 +66,7 @@
)
]

import_reps = client.BulkImportRelationships(((req for req in reqs)))
import_reps = client.BulkImportRelationships((req for req in reqs))
assert import_reps.num_loaded == 2

export_resp = client.BulkExportRelationships(
Expand Down
79 changes: 79 additions & 0 deletions examples/v1/import_bulk_relationships.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"""
This is intended to be a (slightly) more real-world example
that demonstrates the two levels of batching in making BulkImportRelationships
requests.

This example makes use of itertools.batched to break up an iterator of relationships
into chunks. Documentation for itertools.batched can be found here:
https://docs.python.org/3/library/itertools.html#itertools.batched
"""

from itertools import batched

from authzed.api.v1 import (
Client,
ObjectReference,
Relationship,
SubjectReference,
WriteSchemaRequest,
)
from authzed.api.v1.permission_service_pb2 import ImportBulkRelationshipsRequest
from grpcutil import insecure_bearer_token_credentials

TOKEN = "sometoken"

# Stand up a client
client = Client(
"localhost:50051",
insecure_bearer_token_credentials(TOKEN),
)

# Write a simple schema
schema = """
definition user {}
definition resource {
relation viewer: user
permission view = viewer
}
"""

client.WriteSchema(WriteSchemaRequest(schema=schema))


# A generator that we can use to create an arbitrarily-long list of relationships
# In your own application, this would be whatever's generating the list of imported
# relationships.
def relationship_generator(num_relationships):
idx = 0
while idx < num_relationships:
idx += 1
yield Relationship(
resource=ObjectReference(object_type="resource", object_id=str(idx)),
relation="viewer",
subject=SubjectReference(
object=ObjectReference(object_type="user", object_id="our_user")
),
)


TOTAL_RELATIONSHIPS_TO_WRITE = 1_000

RELATIONSHIPS_PER_TRANSACTION = 100
RELATIONSHIPS_PER_REQUEST_CHUNK = 10

# NOTE: batched takes a larger iterator and makes an iterator of smaller chunks out of it.
# We iterate over chunks of size RELATIONSHIPS_PER_TRANSACTION, and then we break each request into
# chunks of size RELATIONSHIPS_PER_REQUEST_CHUNK.
transaction_chunks = batched(
relationship_generator(TOTAL_RELATIONSHIPS_TO_WRITE), RELATIONSHIPS_PER_TRANSACTION
)
for relationships_for_request in transaction_chunks:
request_chunks = batched(relationships_for_request, RELATIONSHIPS_PER_REQUEST_CHUNK)
response = client.ImportBulkRelationships(
(
ImportBulkRelationshipsRequest(relationships=relationships_chunk)
for relationships_chunk in request_chunks
)
)
print("request successful")
print(response.num_loaded)
Loading