Skip to main content

No project description provided

Project description

Cedar Python

CI (main)  PyPI version

cedarpy helps you use the (Rust) Cedar Policy library from Python. You can use cedarpy to:

  • check whether a request is authorized by the Cedar Policy engine
  • validate policies against a schema
  • format policies

cedarpy releases correspond to the following Cedar Policy engine versions:

Cedar Policy (engine) releasecedarpy releasecedarpy branch
v4.8.2v4.8.6main
v4.7.2v4.7.1release/4.7.x
v4.1.0v4.1.0release/4.1.x
v2.2.0v0.4.1release/2.2.x

Beginning with v4.1.0, cedarpy's version number indicates the Cedar Policy engine major and minor version that it is based on. cedarpy increases the patch number when releasing backwards-compatible changes and bug fixes. So the cedarpy and Cedar Engine patch versions can and will diverge. Select the cedarpy version that provides the Cedar Policy language and engine features you need.

cedarpy packages are available for the following platforms:

Operating SystemProcessor ArchitecturesPython
Linuxx86_64, aarch643.9 - 3.14
Macx86_64, aarch643.11 - 3.14
Windowsx86_643.9 - 3.14

Note: This project is not officially supported by AWS or the Cedar Policy team.

Using the library

Releases of cedarpy are available on PyPi. You can install the latest release with:

pip install cedarpy

(See the Developing section for how to use artifacts you've built locally.)

Authorizing access with Cedar policies in Python

Now you can use the library to authorize access with Cedar from your Python project using the is_authorized function. Here's an example of basic use:

from cedarpy import is_authorized, AuthzResult, Decision

policies: str = "//a string containing cedar policies"
entities: list = [  # a list of Cedar entities; can also be a json-formatted string of Cedar entities
    {"uid": {"__entity": { "type" : "User", "id" : "alice" }}, "attrs": {}, "parents": []}
    # ...
]
request = {
    "principal": 'User::"bob"',
    "action": 'Action::"view"',
    "resource": 'Photo::"1234-abcd"',
    "context": {}
}

authz_result: AuthzResult = is_authorized(request, policies, entities)

# so you can assert on the decision like:
assert Decision.Allow == authz_result.decision

# or use the 'allowed' convenience method 
assert authz_result.allowed

# or even via AuthzResult's attribute subscripting support 
assert authz_result['allowed']

The AuthzResult class also provides diagnostics and metrics for the access evaluation request.

See the unit tests for more examples of use and expected behavior.

Authorize a batch of requests

You can also authorize a batch of requests with the is_authorized_batch function. is_authorized_batch accepts a list of requests to evaluate against shared policies, entities, and schema.

Batch authorization is often much more efficient (+10x) than processing authorization requests one by one with is_authorized. This is because the most expensive part of the authorization process is transforming the policies, entities, and schema into objects that Cedar can evaluate. See RFC: support batch authorization requests for details.

Here's an example of how to use is_authorized_batch and the optional request-result correlation_id:

batch_id:str = randomstr()
requests: List[dict] = []
for action_name in action_names:
    requests.append({
        "principal": f'User::"{user_id}"',
        "action": f'Action::"{action_name}"',
        "resource": f'Resource::"{resource_id}"',
        "context": context_keys,
        "correlation_id": f"authz_req::{batch_id}-{action_name}"
    })

# ... resolve get policies, entities, schema ...

# process authorizations in batch
authz_results: List[AuthzResult] = is_authorized_batch(requests=requests, policies=policies, entities=entities, schema=schema)

# ... verify results came back in correct order via correlation_id ...
for request, result, in zip(requests, authz_results):
    assert request.get('correlation_id') == result.correlation_id

cedar-py returns the list of AuthzResult objects in the same order as the list of requests provided in the batch.

The above example also supplies an optional correlation_id in the request so that you can verify results are returned in the correct order or otherwise map a request to a result.

Reusing parsed policies for performance

Parsing the policy set (PolicySet::from_str) is the dominant per-call cost in is_authorized. When your policies are static, for example a code-checked policy set loaded once at startup in a long-running service or AWS Lambda, you can parse them a single time into a reusable PolicySet handle and pass that handle wherever you'd pass a policies string. This skips the re-parse on every call.

from cedarpy import PolicySet, is_authorized, is_authorized_batch, Decision

policies: str = "// a string containing cedar policies"

# Parse once (e.g. at process/Lambda cold start). Parse errors raise ValueError here,
# rather than being folded into an authorization result.
policy_set = PolicySet.from_str(policies)

# Reuse the handle across many requests — no re-parse per call:
authz_result = is_authorized(request, policy_set, entities)
authz_results = is_authorized_batch(requests, policy_set, entities)

The PolicySet handle is accepted anywhere a policies string is accepted: is_authorized, is_authorized_batch, and is_authorized_partial. Passing a plain string still works exactly as before; the handle is purely opt-in and fully backwards compatible. The handle's memory is released automatically when the last Python reference is dropped.

A PolicySet can also be built from the Cedar JSON (EST) policy format with PolicySet.from_json_str(...), and supports len(policy_set) (number of policies) and str(policy_set) (the policy set rendered back to Cedar text).

This complements batch authorization: batching amortizes entity/schema parsing across a set of requests evaluated together, while a reusable PolicySet amortizes policy parsing across calls made at different times. The two compose. The speedup grows with policy size — in the project's benchmark suite (release build, ~10-entity calls) reuse is ~1.3x on a single-rule policy but ~9x on a typical production-scale policy (~16 KB / 60 rules), where it removes ~1.4 ms of policy parsing per call.

On a successful evaluation the result's metrics reflect the reuse: parse_policies_duration_micros measures only the (near-zero) borrow rather than the original parse, and metrics["policies_pre_parsed"] is 1 (it is 0 when policies are passed as a string and parsed on that call). As with all metrics, these keys are present only on successful evaluations — an error result carries an empty metrics map.

Advanced: adding per-request policies to a static base. Most callers reuse a single static PolicySet as above. If, however, your policy set is mostly static but a few policies vary per request, you don't have to re-parse the whole base text each time — PolicySet.with_added_str(fragment) clones the compiled base and parses only the fragment, returning a new handle (the base is left unchanged):

base = PolicySet.from_str(static_policies)        # parse the large static base once

# per request: add only the small dynamic fragment — the base is not re-parsed
for_request = base.with_added_str(per_request_policies)
authz_result = is_authorized(request, for_request, entities)

The result is equivalent to authorizing against the concatenated base-plus-fragment text. (Cedar assigns surface-syntax policies a positional PolicyIdpolicy0, policy1, … — per parse, so a fragment parsed on its own restarts at policy0; with_added_str renumbers the fragment's colliding ids to follow the base, exactly as concatenation would, and any @id("...") annotations are preserved and still resolve via diagnostics.id_annotations_by_reason.)

Reusing parsed entities for performance

Entities are parsed on each call too: is_authorized deserializes the entities JSON and computes the transitive closure of the parents graph. When you authorize many requests against a large, stable entity graph, you can parse it once into a reusable Entities handle and pass it wherever you'd pass an entities string or list:

from cedarpy import Entities, PolicySet, is_authorized

base = Entities.from_json_str(entities_json)       # parse the stable graph once
authz_result = is_authorized(request, policy_set, base)

The common shape is a large, stable base graph (your organization's users and groups, say) plus a small set of entities that are specific to each request (the resources being acted on). Build the base once and merge the per-request delta with with_added_json_str, which parses only the delta and returns a new handle — the base is immutable and reused across every request:

base = Entities.from_json_str(org_graph_json)      # users, groups: parsed once, reused

for request in requests:
    # add only this request's entities (e.g. the documents involved); base is not re-parsed
    for_request = base.with_added_json_str(request_entities_json)
    is_authorized(request, policy_set, for_request)

with_added_json_str is a disjoint union: a delta entity whose uid already exists in the base (and is not identical) raises ValueError. An optional schema argument to from_json_str / with_added_json_str validates the entities at construction. The handle is accepted anywhere an entities string/list is accepted (is_authorized, is_authorized_batch, is_authorized_partial), supports len() and str(), and sets metrics["entities_pre_parsed"] to 1 on the reuse path. As with the PolicySet handle, passing a string or list still works unchanged — the handle is purely opt-in.

Note: the Entities and PolicySet handles are independent and compose — reuse whichever inputs are stable for your workload, or both. Schema is still parsed on each call.

Linking policy templates

A Cedar policy template is a policy with ?principal / ?resource slots. A slot is a placeholder that marks where a principal or resource is filled in later, when the template is linked to concrete entities to produce a real, evaluatable policy. So a template is a rule written once and linked per use. The canonical case is per-principal and per-resource grants — allow this person to view this photo while their subscription is active. You write that rule once as a template, then link it per grant.

PolicySet.from_str already parses templates; they just authorize nothing until linked. with_linked fills a template's slots and returns a new PolicySet handle (immutable, like with_added_str — the base is left unchanged):

from cedarpy import PolicySet, is_authorized, Decision

# two grant rules: an active subscriber may view a granted photo, and
# editing also requires a non-free plan (trial users included)
base = PolicySet.from_str("""
    @id("photo-access")
    permit (
      principal == ?principal,
      action == Action::"view",
      resource == ?resource
    )
    when { principal.subscriptionActive };

    @id("photo-edit")
    permit (
      principal == ?principal,
      action == Action::"edit",
      resource == ?resource
    )
    when
    { principal.subscriptionActive && (!principal.freePlan || principal.inTrial) };
""")

# fill the slots to grant alice access to one photo
linked = base.with_linked(
    template_id="photo-access",          # which template to fill in
    new_id="alice-vacation",             # id for this link (the filled slots, which act as a policy)
    values={"?principal": 'User::"alice"', "?resource": 'Photo::"vacation.jpg"'},
)

# alice's subscription is active, so she may view the photo
entities = [{"uid": {"type": "User", "id": "alice"},
             "attrs": {"subscriptionActive": True}, "parents": []}]
request = {"principal": 'User::"alice"', "action": 'Action::"view"', "resource": 'Photo::"vacation.jpg"'}

result = is_authorized(request, linked, entities)
assert result.decision == Decision.Allow

# the decision points at the link's own id; the template's @id comes alongside it
result.diagnostics.reasons                    # ['alice-vacation']
result.diagnostics.id_annotations_by_reason   # {'alice-vacation': 'photo-access'}

Linking produces a template-linked policy — the slots filled with concrete values, which evaluates as a policy in its own right — and new_id is the id assigned to it. Linking does not rename or consume the template: the template stays in the set, so you can link it again under a different new_id to grant another principal (that's the whole point — one template, many grants). new_id is yours to choose; it is neither a template id nor a principal. (This mirrors the Cedar CLI's link --template-id … --new-id ….)

To create many template-linked policies at once, use with_linked_batch. This is the primary linking path: in a single call it fills the slots of any templates in the PolicySet — the same one repeatedly or several different ones — with the entities you choose. If any link in the batch fails, the whole call raises and no handle is returned. It clones the base once rather than per link:

linked = base.with_linked_batch([
    # the same template, linked twice — two view grants
    {
        "template_id": "photo-access",
        "new_id": "alice-vacation",
        "values": {
            "?principal": 'User::"alice"',
            "?resource": 'Photo::"vacation.jpg"',
        },
    },
    {
        "template_id": "photo-access",
        "new_id": "bob-skyline",
        "values": {
            "?principal": 'User::"bob"',
            "?resource": 'Photo::"skyline.jpg"',
        },
    },
    # a different template, but using dict assignment — an edit grant
    {
        "template_id": "photo-edit",
        "new_id": "alice-edit-vacation",
        "values": {
            "?principal": {"type": "User", "id": "alice"},
            "?resource": {"type": "Photo", "id": "vacation.jpg"},
        },
    },
])

A slot value is given as a Cedar string ('User::"alice"') or a {"type": ..., "id": ...} dict — the same two forms is_authorized accepts for a request principal/resource. A linked PolicySet is still just a PolicySet, so it works everywhere a policies string or handle does (is_authorized, is_authorized_batch, is_authorized_partial), and existing callers are untouched. Note that the slots fill only the principal and resource; the when { principal.subscriptionActive } condition is fixed in the template and shared by every link — write the rule (and its conditions) once, vary only who and what.

Identify a template by its @id, not its positional id. Cedar assigns a policy id by position — policy0, policy1, … — per parse. That position can shift: with_added_str, for example, renumbers an incoming fragment's ids when it layers them onto a base. A template's @id annotation is invariant across parsing and merging, so it is the stable key to link against. with_linked accepts either — it matches the literal id first, then the @id — but prefer the @id. The match must be unambiguous; two templates sharing one @id raises rather than guessing. (An @id is otherwise inert and is not the template's id; cedarpy resolves it the way the Cedar CLI's link command does.)

templates() returns the full picture — each template's ids, the slots it needs, and the links (fillings) produced from it:

linked.templates()
# [{'id': 'policy0',                       # positional id (the fragile one)
#   'id_annotation': 'photo-access',       # the @id — the stable key to link by
#   'slots': ['?principal', '?resource'],  # the slot keys a link must fill
#   'links': [                             # the concrete policies produced from this template
#       {'id': 'alice-vacation',
#        'values': {'?principal': 'User::"alice"', '?resource': 'Photo::"vacation.jpg"'}},
#       {'id': 'bob-skyline',
#        'values': {'?principal': 'User::"bob"', '?resource': 'Photo::"skyline.jpg"'}}]},
#  {'id': 'policy1',                        # the second template, linked once
#   'id_annotation': 'photo-edit',
#   'slots': ['?principal', '?resource'],
#   'links': [
#       {'id': 'alice-edit-vacation',
#        'values': {'?principal': 'User::"alice"', '?resource': 'Photo::"vacation.jpg"'}}]}]

# the link ids live under each template's 'links'; pass one to without_linked
# to revoke that grant — returns a NEW handle; `linked` is unchanged
revoked = linked.without_linked("bob-skyline")
# revoked.templates()[0]['links'] now lists only alice-vacation

templates() is the one introspection call you need: each template's id / id_annotation / slots, and the links produced from it (each link's id and bound values). To act on a single grant — e.g. revoke it — read its id from links and pass it to without_linked(link_id). (Order within templates and links is not guaranteed.)

A linked policy carries two distinct labels, which matters when you read diagnostics. Its id is the new_id you gave it (alice-vacation) — unique to that link, and what appears in result.diagnostics.reasons when it fires. Its @id is inherited from the template (photo-access) — so every link of one template shares the same @id while keeping a distinct id. That is why a matched policy is identified by its id, not its @id: link a template for ten grants and ten policies share the @id, but each has its own id.

Because an unlinked template is inert — the authorizer only ever evaluates linked and static policies, never the templates themselves — you can parse a whole catalogue of templates into the base once and link only the ones a given request needs; the unused templates cost nothing at evaluation time.

Should you reach for templates? It depends on your policies and scale, and it's worth measuring rather than assuming. You would be right to suspect that at small scale and low complexity, generating a policy string per principal and parsing it is the more efficient choice — lower CPU and lower memory than linking, since parsing a short policy is cheaper than the per-link work of binding entity uids and cloning the rule's form. The two reach parity once the policy carries a few conditions, and templates pull ahead from there as the body gets richer — the rule is parsed and held once instead of copied per grant. In a quick build benchmark at 200 grants, a one-condition policy (like the subscription rule above) still favored generate-and-parse, a ~4-condition policy was about even, and a rich ~10-condition grant built about 2× faster and used about 2.5× less memory as a template. So profile your own policy shapes and grant counts, and take whichever approach gives the best result for your use case.

Partially authorizing a request with unknowns

Sometimes you can't fully evaluate a request up front. A resource entity may not be loaded from the database yet, the caller may not have picked a resource, or context may be filled in by a downstream service. is_authorized_partial evaluates whatever is known and returns residual policies for the parts that aren't.

is_authorized_partial returns either:

  • Decision.Allow or Decision.Deny when the unknowns can't change the outcome, or
  • Decision.NoDecision plus residual policies for the caller to re-evaluate once the unknowns are bound.
from cedarpy import is_authorized_partial, PartialAuthzResult, Decision

# Allow access to all principals when the resource is public
policies: str = 'permit(principal, action, resource) when { resource.public == true };'

# Resource entity hasn't been loaded from the database yet
entities: list = []

request = {
    "principal": 'User::"alice"',
    "action": 'Action::"view"',
    "resource": 'Photo::"photo1"',
    "context": {},
}

result: PartialAuthzResult = is_authorized_partial(request, policies, entities)

# Cedar can't decide yet: the policy depends on resource.public,
# but Photo::"photo1" hasn't been loaded.
assert result.decision == Decision.NoDecision

# Which entities Cedar needs you to load before it can decide:
assert result.diagnostics.unknown_entities == ['Photo::"photo1"']

# Which policies are still unresolved, identified by the auto-generated policy id:
assert result.diagnostics.nontrivial_residuals == ['policy0']

Now you can load the unknown entities and re-evaluate access with is_authorized to get a final decision:

from cedarpy import is_authorized

# Load Photo::"photo1" from the database and transform to its Cedar entity representation
entities = [
    {"uid": {"__entity": {"type": "Photo", "id": "photo1"}},
     "attrs": {"public": True}, "parents": []}
]

final_result = is_authorized(request, policies, entities) # new entities; same request and policies
assert final_result.decision == Decision.Allow

Note: A partial-eval result is not a final authorization decision. Always re-run is_authorized once unknowns are bound.

See the Partial Authorization Guide for edge cases, residual structure, and advanced patterns (SQL translation, Cedar text re-evaluation).

Validating policies against a schema

You can use validate_policies to validate Cedar policies against a schema before deploying them. Validation catches common mistakes like typos in entity types, invalid actions, type mismatches, and unsafe access to optional attributes—errors that would otherwise cause policies to silently fail at runtime.

This is particularly useful in CI/CD pipelines to catch policy errors before they reach production. See the Cedar validation documentation for details on what the validator checks.

Here's an example of basic use:

from cedarpy import validate_policies, ValidationResult

policies: str = "// a string containing Cedar policies"
schema: str = "// a Cedar schema as JSON string, Cedar schema string, or Python dict"

result: ValidationResult = validate_policies(policies, schema)

# so you can check validation passed like:
assert result.validation_passed

# or use ValidationResult in a boolean context
assert result  # True if validation passed

# and if validation fails, iterate over errors:
for error in result.errors:
    print(f"error: {error}")

The ValidationResult class provides the validation outcome and a list of ValidationError objects when validation fails.

See the unit tests for more examples of use and expected behavior.

Formatting Cedar policies

You can use format_policies to pretty-print Cedar policies according to convention.

from cedarpy import format_policies

policies: str = """
    permit(
        principal,
        action == Action::"edit",
        resource
    )
    when {
        resource.owner == principal
    };
"""

print(format_policies(policies))
# permit (
#   principal,
#   action == Action::"edit",
#   resource
# )
# when { resource.owner == principal };

Developing

You'll need a few things to get started:

  • Python +3.9
  • Rust and cargo

This project is built on the PyO3 and maturin projects. These projects are designed to enable Python to use Rust code and vice versa.

The most common development commands are in the Makefile

Create virtual env

First create a Python virtual environment for this project with: make venv-dev

In addition to creating a dedicated virtual environment, this will install cedar-py's dependencies.

If this works you should be able to run the following command:

maturin --help

Build and run cedar-py tests

Ensure the cedar-py virtual environment is active by sourcing it in your shell:

source venv-dev/bin/activate

Now run:

make quick

The make quick command will build the Rust source code with maturin and run the project's tests with pytest.

If all goes well, you should see output like:

(venv-dev) swedish-chef:cedar-py skuenzli$ make quick
Performing quick build
set -e ;\
	maturin develop ;\
	pytest
📦 Including license file "/path/to/cedar-py/LICENSE"
🔗 Found pyo3 bindings
🐍 Found CPython 3.9 at /path/to/cedar-py/venv-dev/bin/python
📡 Using build options features from pyproject.toml
Ignoring maturin: markers 'extra == "dev"' don't match your environment
Ignoring pip-tools: markers 'extra == "dev"' don't match your environment
Ignoring pytest: markers 'extra == "dev"' don't match your environment
💻 Using `MACOSX_DEPLOYMENT_TARGET=11.0` for aarch64-apple-darwin by default
   Compiling cedarpy v0.1.0 (/path/to/cedar-py)
    Finished dev [unoptimized + debuginfo] target(s) in 3.06s
📦 Built wheel for CPython 3.9 to /var/folders/k2/tnw8n1c54tv8nt4557pfx3440000gp/T/.tmpO6aj6c/cedarpy-0.1.0-cp39-cp39-macosx_11_0_arm64.whl
🛠 Installed cedarpy-0.1.0
================================================================================================ test session starts ================================================================================================
platform darwin -- Python 3.9.12, pytest-7.4.0, pluggy-1.2.0
rootdir: /path/to/cedar-py
configfile: pyproject.toml
testpaths: tests/unit
collected 10 items

tests/unit/test_authorize.py::AuthorizeTestCase::test_authorize_basic_ALLOW PASSED                                                                                                                            [ 10%]
tests/unit/test_authorize.py::AuthorizeTestCase::test_authorize_basic_DENY PASSED                                                                                                                             [ 20%]

... snip ... # a bunch of tests passing - please write more!
tests/unit/test_import_module.py::InvokeModuleTestFunctionTestCase::test_invoke_parse_test_policy PASSED                                                                                                      [100%]

================================================================================================ 10 passed in 0.51s =================================================================================================

Integration tests

This project supports validating correctness with official Cedar integration tests. To run those tests you'll need to retrieve the cedar-integration-tests data with:

make submodules

Then you can run:

make integration-tests

cedar-py currently passes all 74 tests defined in the example_use_cases, multi, ip, and decimal suites. The integration tests also validate policies against schemas when shouldValidate is set in the test definition. See test_cedar_integration_tests.py for details.

Corpus tests

The upstream cedar-integration-tests repository also ships a fuzzer-generated corpus (corpus-tests.tar.gz) — 7,462 test files containing 59,696 individual request cases. cedar-py passes all 59,696. Runs are kept in a separate target since the suite takes a few minutes:

make corpus-tests

The runner mirrors the leniency rules used by the upstream Rust runner (cedar-testing/tests/cedar-policy/corpus_tests.rs) and cedar-java's SharedIntegrationTests: reasons compared as a set, errors compared by count, and policy/schema parse failures (cedarpy's NoDecision) soft-pass when the fixture's expected decision is Deny. See test_cedar_corpus_tests.py for details.

Using locally-built artifacts

If you used make quick above, then a development build of the cedarpy module will already be installed in the virtual environment.

If you want to use your local cedarpy changes in another Python environment, you'll need to build a release with:

make release

The release process will build a wheel and output it into target/wheels/

Now you can install that file with pip, e.g.:

pip install --force-reinstall /path/to/cedar-py/target/wheels/ccedarpy-*.whl

Contributing

This project is in its early stages and contributions are welcome. Please check the project's GitHub issues for work we've already identified.

Some ways to contribute are:

  • Use the project and report experience and issues
  • Document usage and limitations
  • Enhance the library with additional functionality you need
  • Add test cases, particularly those from cedar-integration-tests

You can reach people interested in this project in the #cedar-py channel of the Cedar Policy Slack workspace.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cedarpy-4.8.6.tar.gz (456.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

cedarpy-4.8.6-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

cedarpy-4.8.6-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARM64

cedarpy-4.8.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ x86-64

cedarpy-4.8.6-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARM64

cedarpy-4.8.6-cp314-cp314-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.14Windows x86-64

cedarpy-4.8.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

cedarpy-4.8.6-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARM64

cedarpy-4.8.6-cp314-cp314-macosx_11_0_arm64.whl (4.1 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

cedarpy-4.8.6-cp314-cp314-macosx_10_12_x86_64.whl (4.2 MB view details)

Uploaded CPython 3.14macOS 10.12+ x86-64

cedarpy-4.8.6-cp313-cp313-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.13Windows x86-64

cedarpy-4.8.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

cedarpy-4.8.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

cedarpy-4.8.6-cp313-cp313-macosx_11_0_arm64.whl (4.1 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

cedarpy-4.8.6-cp313-cp313-macosx_10_12_x86_64.whl (4.2 MB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

cedarpy-4.8.6-cp312-cp312-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.12Windows x86-64

cedarpy-4.8.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

cedarpy-4.8.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

cedarpy-4.8.6-cp312-cp312-macosx_11_0_arm64.whl (4.1 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

cedarpy-4.8.6-cp312-cp312-macosx_10_12_x86_64.whl (4.2 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

cedarpy-4.8.6-cp311-cp311-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.11Windows x86-64

cedarpy-4.8.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

cedarpy-4.8.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

cedarpy-4.8.6-cp311-cp311-macosx_11_0_arm64.whl (4.1 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

cedarpy-4.8.6-cp311-cp311-macosx_10_12_x86_64.whl (4.2 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

cedarpy-4.8.6-cp310-cp310-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.10Windows x86-64

cedarpy-4.8.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

cedarpy-4.8.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64

cedarpy-4.8.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

cedarpy-4.8.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ ARM64

File details

Details for the file cedarpy-4.8.6.tar.gz.

File metadata

  • Download URL: cedarpy-4.8.6.tar.gz
  • Upload date:
  • Size: 456.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.14.1

File hashes

Hashes for cedarpy-4.8.6.tar.gz
Algorithm Hash digest
SHA256 56f731da0a6818d24cea5f2c258eccfb6cc47dcaec794eeb889ce5b6c0eb7ec4
MD5 248f37d4be6a49ee3d7d121e46c38965
BLAKE2b-256 fc8697723db2d92fe41ee1dd84de2348e2ccf250b341bb579d2f988601fdbc49

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 adc1a25d526843bf68b344440d58525916fef5d554fcd9fc811b32a317d1ad55
MD5 4426b1538d263dcf34a8b7d633e2e5e7
BLAKE2b-256 0332be83c2e7c8ba7de8bb3425db6de88f02e3672f7fa87ed488a56c93cb7687

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 516b277e4638e8b430709f914d99356f48c71059cc6a13c3d2b1cd0540e8c06c
MD5 0e329e806fa111b49710c87c759d6698
BLAKE2b-256 350b3cee4872c0781671c7cbe9c023e81178f680d00e225247331d2ac62b83dc

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 34fd732008941b5347fc79e00d340c3fb0ff6f60f3efc13fa1de58b01da1ca82
MD5 ac53928d91d133619e7b5d3908caf265
BLAKE2b-256 10dc6da6ae67ac88e696f69b9f4c3e78678815609040a6916a451d84246e6144

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 7d6a47bab1dcfe4b9a29694892f560c1dd81025dc6bd1cb440bf3184a50b1ef1
MD5 b360e68174d8e420379ac5e38647647b
BLAKE2b-256 0892b33d11a2c3c4764bff2d7f13e44fa7ef7094ecd370461cabe2d3c561982e

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: cedarpy-4.8.6-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 4.0 MB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.14.1

File hashes

Hashes for cedarpy-4.8.6-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 6f349228bb6485aaf7af32a9c93e6d6b6699faa0e5ad23b6a7cf9f625b1491ed
MD5 8680a7ac70e59704327cc432e2f615cf
BLAKE2b-256 afd2c3a949c8ea48cdbb81092f309c331f5684e966db00782ef1506c85b8ff47

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f27716851916d1b3254b64d52462f3def870b057a3495b84a55e265b0076f4d4
MD5 b7e967e5f7dd295ad0e041e57ffffd24
BLAKE2b-256 94f0f94ad5dcd7bdd694e07001445954ac56edaae82f01ddd3dd414cc1db2ad0

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 65494f77e4bc6a78543aa82b41334c9f397fa106914faf2d0d258174dfcdda0e
MD5 be997796fe4ee11c708763ace87bb051
BLAKE2b-256 d49684668099d220a6d145deea484f4ea34d2aafaedf446dc0c43ea64e3251df

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0d15bfd4027383d4ab628c9bfec017ce6ceeeb41dc3c771724329c0f11d187f2
MD5 093e140d92cef5519cf51711d4b39080
BLAKE2b-256 13276fe584d1799362ee7d422d5648286bb60b11017af5319bd8b9c9b8c8f2d0

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp314-cp314-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 8c3332ce4dc71ae280e544c9dd9d588ab513c6353b17bbe4f46ea84be6251267
MD5 4209e8257f850613bd503a0e111fbf15
BLAKE2b-256 193df4a70d16c57a21b32efc1a29e93f95f61eb9a80324aa820d66ded286c3b1

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: cedarpy-4.8.6-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 4.0 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.14.1

File hashes

Hashes for cedarpy-4.8.6-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 5684fd0c59d5b1ef88b060f335940efe508c06a319fbb3d2aa71c2c0684e2bf9
MD5 2301d6b668c01e58f10c57af0ef045b2
BLAKE2b-256 33767cb9555697dfed238ed5bf50024e9598bbfa037f4888f327ef171ba22647

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5a475c74e3e31065cca7506c77ed08200c7c42da1d49ccce1798cb51bde35a73
MD5 719dd0e4f97876323c8bccc0328acf03
BLAKE2b-256 70d9b85e36944a208719665fb51a93725e43f07c1c357d611ae743258cba9623

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c5f5ff46a2bdcf63d8d049bd42c27f69d7fbb93ad0e0cc017508e6fd99fcdcda
MD5 406797cc8675b4d1a123b80e0c8f93ac
BLAKE2b-256 e9b91b02919ebe7d31d9c0704e5d6d11648cdf6c62d43c0569bc9650f49eb631

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 489031d13474dab60d385c1365c14510ae4b8cef00b8cc3c6fe321b6eaced38a
MD5 d5d7b1cc03486f35d1be83230fe199ca
BLAKE2b-256 c6dbbaf65c8497dcb24846b708cc19da9439c9372c925f2dff4c5154720307f5

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 3ccf7a49454cab575c79b8a8285bed948a933a9a5103007aa246ab3cd58d3108
MD5 90969f660021f4991fb24139e01e9cb1
BLAKE2b-256 7fb50041e9f1085b176d9135d4a4438511545d7079c6b3235b4dc82bab59e8f3

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: cedarpy-4.8.6-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 4.0 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.14.1

File hashes

Hashes for cedarpy-4.8.6-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 7ff946c3e48faf2ef649245fa80a54ef1e2b58687ec873742928e370049326ed
MD5 00530eb09f8917803567e17fe6cea31e
BLAKE2b-256 725c8e84c73e1d4dc4d759294a5d612896b02fca4546cf10fdf8887b8307bc19

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 60539e83979176902343f984bbdcc49a7569e8c4ca4d88ceb8c57acec3027508
MD5 57751e02d00f59b57210bc844ce63c25
BLAKE2b-256 2716a530a02ec48a4f1a7427ff966802f86b5e70673c3ff83a3d07c3e0bb6311

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e8ea0d07cda1615457ecf03cd160b5894255fb1a549401827fd6b5c2d0fd8e89
MD5 20c0963078468bee9b3a7423cd78a0f0
BLAKE2b-256 a4c20bd390b9329266ceed807128b8f23d6432ff4e997c3a8358ef29a6ef7330

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a8a592d48bcc6c5780f1fcb1c6a2cb02448c328e0e6bbdff3ba6e6ff023600eb
MD5 d59883a33c0f6aaa5be954a4def35228
BLAKE2b-256 7aceb9fe2fd4e956591756bcf6bff17e4f92f2b1b413fc3eef0eef17af390638

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 d4146ce63616d5a746dc0cfecf5f3fbf3a6bb601b6da37ab4d338fa379ef5136
MD5 8f197797f6abcc3c6d4d0fabe5aa48a2
BLAKE2b-256 96e43703435900c3e37c0816aaa13b5d702f609d21e1fa1bf4eea36272b1da6a

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: cedarpy-4.8.6-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 4.0 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.14.1

File hashes

Hashes for cedarpy-4.8.6-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 d1417ea9477e8b802b8a01ed68eb5a5cf40e3c82790a563bf80674d8ebfca978
MD5 f2342ea1d86206970ca37303241eddce
BLAKE2b-256 05fb4a1b9cea37e03e6331479b23bb0004c795b62efa5eca27cf26b3acd8a900

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a02391dffc98ff1940ba1a98c9ba94c4ea30fd04b0b34b957e7a06b9fad86e22
MD5 482bca1db616061312c069ecd91a218a
BLAKE2b-256 d986a84e710b349a29e1f0ae08637a8d4c51d4b7695ecc3e2be22448b6ca3679

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0eeb14aa10c0e0d3de43523ebffee50c7bd96f3ad076e07fb776b5cf38fe85a5
MD5 70208138196b5ec96c2f426863584b00
BLAKE2b-256 d3ffc8fd689f66fd16a454a6e2ab0cef8d20b40b42ffa62ef48f2373d7b86383

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5984f634f14d86f3a19202ce218675ec4f41153db434d5c8cc0fe11c1d68e604
MD5 4df5f9c6a58f770ac2e5b3e3361c264c
BLAKE2b-256 3c0dde88654f0a7fd5b5fe7a88c6a36083c3594710c101d85c0e8b54eb7fa0c7

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 87737ae12d8280c10e3814386be8b8c5f88d0bc39af36e81c4d7d682c2a78b2b
MD5 1996f4f6b0763c40d886487675c2344f
BLAKE2b-256 5f99b206c5110f6d7822663de8f76d24e8133aa98b075ebaa80a3bc31121c6ee

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: cedarpy-4.8.6-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 4.0 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.14.1

File hashes

Hashes for cedarpy-4.8.6-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 33762f26bed7d8b885792e006d9031f7db965a1d7b24e5727b0f844844ec7a50
MD5 54fe6e44e061150eb07ed44b233a70dc
BLAKE2b-256 6da437b36f4c5368ca90e6dc0e84ce1a5ccf56b44ac143a0e842ba943b0b819d

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 13c759ea5b05b214c474948e089373cb61f2020a90970a51c8e47e47b536eb72
MD5 1a3a74d1f92f3f62463e78586c7fa2b0
BLAKE2b-256 86cd70b6276ee38b465e5fe68ca6c425e5e88b28c5bab31d7281c96454996441

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 80049fed4d1f69f395fecc44faee72304a1ba390b1491b67f643892b0d65c21f
MD5 d9c6addd9c73fdc02639d252ff645a35
BLAKE2b-256 ca013c735f7fbbf904e102770e95532fcf10fd6db003ccdf33f8755d46c7af19

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 482b6e0206d12a8fb856310dc07bd34d16d2b350be4ebb92f465ec49cd9be633
MD5 68fa5aa97fed1a1b956eba619dfa47a3
BLAKE2b-256 f96160b0737efad7c48278b76523887432e1084bd4c2b3ed0f10114a1bb14fb8

See more details on using hashes here.

File details

Details for the file cedarpy-4.8.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for cedarpy-4.8.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c7145204c8d510206011805d4f6d08bedf24d375c537287c4de1f5f6dff5efe0
MD5 9cbfdeb7f5ae1e6c4d64c561a30e65ce
BLAKE2b-256 bb2566625b00085ff3eadbb5035dff2a2c29606cc2f71574275a6680590f5f12

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page