feat: Add support for opaque Schema handles in Python - #103
Conversation
## Summary Adds `Schema`, `Schema.from_str`, and `Schema.from_json_str`, following the same pattern as `PolicySet` and `Entities`. ## Motivation The same schema is usually passed to many different function calls, and each call parses it again. Pre-parsing the schema *once* into the (already existing) Rust `Schema` object lets us deduplicate this effort.
|
@swenger Looking good. Are you intending updates to the README documentation? |
Thanks :)
Good idea - give me a minute and I'll get back to you. |
|
Thank you for the PR @swenger! I think this is a good idea. I will review my morning. |
|
Thanks @swenger — overall this PR looks good and is a strong performance win. The There are a few issues to resolve first:
Do you have any questions about the requested changes? Or would you like me to take care of any of them? |
|
Thanks @skuenzli for the detailed feedback! Glad you caught the
I don't think so, your explanations were great! Do the following commits address your concerns? |
Schema was the only handle that could not render itself: PolicySet.__str__ returns Cedar policy text and Entities.__str__ returns Cedar entities JSON, but str(schema) fell back to the static repr. cedar_policy::Schema is a one-way compilation with no render-back API, so the handle now parses to a SchemaFragment first (which round-trips via to_cedarschema), compiles the Schema from that fragment, and keeps the fragment for __str__. Rendering failures report as <unrenderable Schema: ...> rather than raising, matching Entities.__str__. __repr__ now reports entity-type/action counts, matching the other handles' count-style reprs. Also makes the CHANGELOG's str() claim accurate and precise, documents __str__ in the typed API stub, and adds render/round-trip tests. Co-Authored-By: Claude <noreply@anthropic.com>
…le changelog entry Co-Authored-By: Claude <noreply@anthropic.com>
|
Looks great @swenger - thank you! I upgraded the Schema I also credited you in the changelog entry. |
|
Verified the clone fix locally — the handle path's per-call cost is now flat regardless of schema size. Before the fix it scaled linearly, because each call paid a deep copy of the Measured with release builds, pre-parsed
The metrics are honest now too: |
|
Thanks @skuenzli for the review and your additions! Could you tag a release? I'd then package it for conda-forge. |
|
Yes, kicking off the release process now. |
Add two Cedar API gotchas: Schema::clone() is a deep copy (borrow Option<&Schema> on hot paths) and Schema has no render-back API while SchemaFragment round-trips (how PySchema.__str__ works). Add the five-surface checklist for public API changes and the shared handle-trio pattern to Conventions, and a benchmark load-sensitivity note. Remove the Follow-on work section: GH #62 (supply-chain hardening) and GH #69 (benchmark process) are both complete and closed. The durable gate-on-medians finding from #69 moves to the Benchmarks bullets. Co-Authored-By: Claude <noreply@anthropic.com>
|
@swenger the new Schema handle is now available in the new cedar-py v4.8.7 release |
Awesome, thanks @skuenzli! |
|
Thank you @swenger ! Have a great weekend! |
Summary
Adds
Schema,Schema.from_str, andSchema.from_json_str, following the same pattern asPolicySetandEntities.Motivation
The same schema is usually passed to many different function calls, and each call parses it again. Pre-parsing the schema once into the (already existing) Rust
Schemaobject lets us deduplicate this effort.