We’re excited to announce a new major version of our Python client. We’ve been hard at work on this new vision for the Oso SDK, centered around these features:
- A simplified Fact Management API
- A powerful Query Builder API
Simplified Fact Management API
Fact Representation and Input Types
Facts are now tuples instead of dicts. You can replace old dict formats like {"name": "has_role", args: [...]}
with ("has_role", user, "member", repo)
. For example, to migrate from tell
to insert
, convert the arguments from dicts
to values
and wrap them in a tuple.
Fact arguments should now use the oso_cloud.Value
type, improving consistency across the API. Type hinting has been updated as well. Instead of oso_cloud.Value
and oso_cloud.Fact
, use oso_cloud.IntoValue
and oso_cloud.IntoFact
, supporting native Python types alongside custom objects.
Management API
The Management API has been condensed from 6 methods to 4: insert
, delete
, get
, and batch
.
The new insert
API replaces tell
. With insert
, you can add facts to Oso Cloud:
oso.insert((
"has_role",
Value("User", "bob"),
"owner",
Value("Organization", "acme")
))
With delete
, you can delete a fact or facts with an argument of a particular type. Deleting a single fact would look like below:
oso.delete((
"has_role",
Value("User", "bob"),
"maintainer",
Value("Repository", "anvils")
))
With get
, you can check the existence of a particular fact or fetch all facts that have a particular argument.
# Get one fact
oso.get(("has_role", bob, "admin", anvils))
# List all role-related facts on the `anvils` repo
oso.get(("has_role", None, None, anvils))
The new batch
API replaces the bulk
, bulk_delete
, and bulk_tell
APIs.
Additionally, the new batch
function supports deleting all facts matching a pattern:
user1 = Value("User", "1")
user2 = Value("User", "2")
# Remove all roles for User 1 and User 2 across the entire system.
with oso.batch() as tx:
tx.delete(("has_role", user1, None, None))
tx.delete(("has_role", user2, None, None))
Powerful Query Builder API
We've replaced the Query API with a more powerful and flexible oso.build_query() API with a fluent interface. We've also dropped the authorize_resources APIs in favor of the Query Builder. Queries with wildcards now use typed_var(my_type)
, while multiple results can be returned as dictionaries for easier processing. If you want to migrate your existing queries as-is, check out the section of queries with no wildcards, queries with type-constrained wildcards, and queries with unconstrained wildcards for more information.
Here's an example of using the Query Builder to filter unauthorized resources from a collection:
repos = ["anvil", "acme"]
actor = Value("User", "bob")
repo = typed_var("Repository")
results = (
oso
.build_query(("allow", actor, "read", repo))
.in_(repo, repos)
.evaluate(repo)
)
# => Returns the subset of `repos` that bob can read- eg.
# ["anvil"]
See here for how it can support any use case your application demands.
Get started with the v2 Python client
You can install the v2 Python on PyPI by running: pip install oso-cloud
. The full docs are here. If you’re upgrading from v1, check out the Migration Guide.
These changes will be coming to the other language SDKs soon. Let us know if you’re interested in trying RC versions!