Python SDK for the AtlaSent authorization API
Project description
AtlaSent Python SDK
Execution-time authorization for AI agents. One call before a sensitive action runs. Fail-closed by design — no action proceeds without an explicit, verified permit.
pip install atlasent
Quickstart
from atlasent import protect
permit = protect(
agent="deploy-bot",
action="deploy_to_production",
context={"commit": commit, "approver": approver},
)
# If we got here, the action is authorized end-to-end.
# Otherwise protect() raised and the action never ran.
Set ATLASENT_API_KEY in the environment, or call
atlasent.configure(api_key=...). That's the whole setup.
The protect() contract
atlasent.protect() is the category primitive. On allow, it returns a
verified Permit. On anything else, it raises:
| Outcome | Raises |
|---|---|
Policy DENY |
AtlaSentDeniedError |
| Permit failed verification | AtlaSentDeniedError |
| HTTP 401 / 403 / 4xx / 5xx | AtlaSentError (with .code) |
| Timeout / network failure | AtlaSentError (code="timeout" / "network") |
| Rate limit (429) | RateLimitError (subclass of AtlaSentError, .retry_after) |
There is no permitted=False return path to forget. The action cannot
execute unless a Permit is in hand.
from atlasent import protect, AtlaSentDeniedError, AtlaSentError
try:
permit = protect(agent=agent, action=action, context=context)
# Run the action. permit.permit_id + permit.audit_hash go in your log.
except AtlaSentDeniedError as exc:
# Policy said no. exc.decision, exc.reason, exc.evaluation_id.
log.warning("Denied: %s (evaluation_id=%s)", exc.reason, exc.evaluation_id)
except AtlaSentError as exc:
# Transport / auth / server failure. exc.code, exc.status_code.
log.error("AtlaSent unavailable: %s", exc)
AtlaSentDeniedError subclasses AtlaSentDenied, so
except AtlaSentDenied: still catches protect() denials. Use
except AtlaSentDeniedError: when you need to distinguish a policy
decision from a transport error.
Async
from atlasent import AsyncAtlaSentClient
async with AsyncAtlaSentClient(api_key="ask_live_...") as client:
permit = await client.protect(
agent="clinical-data-agent",
action="modify_patient_record",
context={"user": "dr_smith", "patient_id": "PT-001"},
)
Full feature parity with the sync surface — same return type, same exceptions, same fail-closed contract.
What a Permit gives you
@dataclass(frozen=True)
class Permit:
permit_id: str # opaque decision id (use for audit lookup)
permit_hash: str # verification hash bound to the permit
audit_hash: str # hash-chained audit-trail entry (21 CFR Part 11)
reason: str # policy engine's explanation
timestamp: str # ISO 8601 of the verification
Log permit_id + audit_hash for every action your code performs —
they're the two fields a regulator or support ticket will ask for.
Framework integration
FastAPI
from fastapi import FastAPI, HTTPException
from atlasent import AsyncAtlaSentClient, AtlaSentDeniedError, AtlaSentError
app = FastAPI()
client = AsyncAtlaSentClient(api_key="ask_live_...")
@app.post("/modify-record")
async def modify_record(patient_id: str, agent_id: str):
try:
permit = await client.protect(
agent=agent_id,
action="modify_patient_record",
context={"patient_id": patient_id},
)
except AtlaSentDeniedError as exc:
raise HTTPException(403, detail=exc.reason) from None
except AtlaSentError as exc:
raise HTTPException(503, detail=str(exc)) from None
return {"permit_id": permit.permit_id, "audit_hash": permit.audit_hash}
Flask
from flask import Flask, jsonify, abort, request
from atlasent import AtlaSentClient, AtlaSentDeniedError, AtlaSentError
app = Flask(__name__)
client = AtlaSentClient(api_key="ask_live_...")
@app.post("/modify-record")
def modify_record():
try:
permit = client.protect(
agent="flask-agent",
action="modify_patient_record",
context={"patient_id": request.json["patient_id"]},
)
except AtlaSentDeniedError as exc:
abort(403, description=exc.reason)
except AtlaSentError as exc:
abort(503, description=str(exc))
return jsonify(permit_id=permit.permit_id, audit_hash=permit.audit_hash)
Decorator shortcuts — atlasent_guard for sync views,
async_atlasent_guard for async ones — remain available for the
pre-protect() gate() + GateResult idiom. See
examples/fastapi_integration.py
and examples/flask_integration.py.
configure()
import atlasent
atlasent.configure(
api_key="ask_live_...", # else reads ATLASENT_API_KEY
base_url="https://api.atlasent.io", # default
)
Or pass the same settings to AtlaSentClient(...) / AsyncAtlaSentClient(...)
directly for per-client configuration:
from atlasent import AtlaSentClient
client = AtlaSentClient(
api_key="ask_live_...",
base_url="https://api.atlasent.io", # default
timeout=10, # seconds, default
max_retries=2, # on 5xx / timeouts, default
retry_backoff=0.5, # seconds, doubles each retry
)
Lower-level primitives
protect() is built on top of the raw two-endpoint surface. If you
need to branch on the decision rather than raise, use these directly:
client.evaluate(action, agent, context)— policy decision; raisesAtlaSentDeniedon deny, otherwise returnsEvaluateResult.client.verify(permit_token, ...)— verify a previously-issued permit end-to-end.client.gate(action, agent, context)— evaluate + verify; returns aGateResultwith both response objects.authorize(agent, action, context)— data-not-exception variant: returns anAuthorizationResultwithpermitted: boolinstead of raising on deny. Preferprotect()unless you have a specific reason to branch on a return value.
Design choices
- Fail-closed by construction.
protect()either returns aPermitor raises. No ambiguous return values, no silent permits. - Sync + async feature parity. Every public method exists on
both
AtlaSentClientandAsyncAtlaSentClient. - Wire-compatible with the TypeScript SDK. A permit issued by one SDK verifies from the other.
- PEP 561 typed. Ships a
py.typedmarker; every public function and type is annotated.
API endpoints
The SDK calls:
POST https://api.atlasent.io/v1-evaluatePOST https://api.atlasent.io/v1-verify-permit
Override with the base_url argument.
Requirements
- Python 3.10+ (for
str | Noneunions anddatetime.UTC). httpx >= 0.24,pydantic >= 2.0.
Related
- TypeScript SDK:
../typescript/. Same wire contract, same fail-closed philosophy, sameprotect()verb. - Shared contract:
../contract/— schemas, vectors, and the CI drift detector that keeps both SDKs honest.
Get an API key
Sign up at atlasent.io → Settings → API Keys.
License
MIT — see LICENSE.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file atlasent-1.4.1.tar.gz.
File metadata
- Download URL: atlasent-1.4.1.tar.gz
- Upload date:
- Size: 62.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9a30983a73d093df78b4451f280a135e3c00d2e3a596f7ee2a2fd830d356330
|
|
| MD5 |
b928d1e3ee5d90bc52bc3b206e718a2e
|
|
| BLAKE2b-256 |
82b907e6c210823752cada43803230d24d195708edd54aea58ca0222c3f9a180
|
Provenance
The following attestation bundles were made for atlasent-1.4.1.tar.gz:
Publisher:
publish-pypi.yml on AtlaSent-Systems-Inc/atlasent-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
atlasent-1.4.1.tar.gz -
Subject digest:
b9a30983a73d093df78b4451f280a135e3c00d2e3a596f7ee2a2fd830d356330 - Sigstore transparency entry: 1390790627
- Sigstore integration time:
-
Permalink:
AtlaSent-Systems-Inc/atlasent-sdk@bdd77bcd7c261f1a29c1296c312fa972317674de -
Branch / Tag:
refs/tags/python-v1.4.1 - Owner: https://github.com/AtlaSent-Systems-Inc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@bdd77bcd7c261f1a29c1296c312fa972317674de -
Trigger Event:
push
-
Statement type:
File details
Details for the file atlasent-1.4.1-py3-none-any.whl.
File metadata
- Download URL: atlasent-1.4.1-py3-none-any.whl
- Upload date:
- Size: 37.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1483d8bd7d2e6f5567cdcebb9cda6a8554c3b678f6ca98941f8254461fe938b
|
|
| MD5 |
34d47c7c800adb5c7106de6330d2c79f
|
|
| BLAKE2b-256 |
cce02317fcf66bb5f16fee9c694e64b7131eee085ea62f5a0c370163b7962edd
|
Provenance
The following attestation bundles were made for atlasent-1.4.1-py3-none-any.whl:
Publisher:
publish-pypi.yml on AtlaSent-Systems-Inc/atlasent-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
atlasent-1.4.1-py3-none-any.whl -
Subject digest:
e1483d8bd7d2e6f5567cdcebb9cda6a8554c3b678f6ca98941f8254461fe938b - Sigstore transparency entry: 1390790718
- Sigstore integration time:
-
Permalink:
AtlaSent-Systems-Inc/atlasent-sdk@bdd77bcd7c261f1a29c1296c312fa972317674de -
Branch / Tag:
refs/tags/python-v1.4.1 - Owner: https://github.com/AtlaSent-Systems-Inc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@bdd77bcd7c261f1a29c1296c312fa972317674de -
Trigger Event:
push
-
Statement type: