caselaw-access
Client SDK for the Case Law Explorer access service. One call decides authentication, endpoint scope, and rate limit, so a product does not implement any of them itself.
Install
pip install caselaw-access
Until the package is on PyPI, build a wheel from this directory and vendor it:
pip wheel . --no-deps -w dist
cp dist/caselaw_access-*.whl ../../../<your-project>/vendor/
and reference it from requirements.txt:
./vendor/caselaw_access-0.1.0-py3-none-any.whl
Bump the version in pyproject.toml whenever the contents change — pip caches
wheels by version and will silently reuse a stale copy otherwise.
Configuration
Everything comes from the environment:
| Variable | Meaning | Default |
|---|---|---|
ACCESS_SERVICE_URL |
Base URL of the access service. Empty disables all checks. | — |
ACCESS_PROJECT |
Project slug registered in the access console. | citations-api |
ACCESS_SERVICE_TIMEOUT_SECONDS |
Per-check timeout. | 5 |
ACCESS_FAIL_OPEN |
Allow traffic when the service is unreachable. | false |
REQUIRE_AUTH / ACCESS_ENFORCE |
Master switch for enforcement. | false |
Checks are only sent when the service URL is set and enforcement is on. That combination is what lets a service run locally, and its tests run in CI, without the control plane.
Direct use
from caselaw_access import AccessClient, RateLimited, PermissionDenied
client = AccessClient.from_env()
try:
decision = client.check(token, endpoint="echr", method="POST")
except RateLimited as exc:
... # exc.status == 429, exc.headers() has Retry-After
except PermissionDenied as exc:
... # exc.status == 403
An allowed Decision carries the resolved principal, the matched plan,
the granted scopes, and the remaining quota. decision.headers() returns
the X-RateLimit-Remaining-* headers to attach to the response.
http.server handlers
from caselaw_access.http_server import AccessGuard
guard = AccessGuard(send_error=my_json_writer)
class handler(BaseHTTPRequestHandler):
@guard.protect("echr", methods=["POST"])
def do_POST(self):
...
The decorated method runs only when the call is allowed; a denial is written
before the body executes. The decision is attached to the handler as
access_decision and access_principal, and the headers to emit as
access_headers.
The verb reported to the service is the request's real method
(handler.command). methods only shapes the CORS header on an error
response.
Failure semantics
| Situation | Result |
|---|---|
No or malformed Authorization header |
401, service never called |
| Service answers 401 | 401 with the service's code |
Service answers 403, or allowed: false with a scope error |
403 |
Service answers 429, or allowed: false with rate_limit_exceeded |
429 with Retry-After |
| Service unreachable, times out, or answers 4xx/5xx it cannot decide on | 503, or allowed when ACCESS_FAIL_OPEN=true |
Connection failures are retried because the request provably never arrived. Read timeouts are not retried: the service may already have counted the call against the caller's quota, and a retry would charge them twice.
Behaviour is pinned by the shared conformance suite in
../contract, which this package runs in tests/test_conformance.py.
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 caselaw_access-0.1.0.tar.gz.
File metadata
- Download URL: caselaw_access-0.1.0.tar.gz
- Upload date:
- Size: 14.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f5f761181109b92fc89cbb8f3dd97577185972a9cf1d2d36b1d405a7f19fb22
|
|
| MD5 |
2fb3d74d5893644c03378f8e95a5515b
|
|
| BLAKE2b-256 |
eb0f48e0090496a3de1012c5069bd6e852619d530c9076d8edb0a59c6b89008c
|
Provenance
The following attestation bundles were made for caselaw_access-0.1.0.tar.gz:
Publisher:
publish-python.yml on davidwickerhf/caselaw-access
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
caselaw_access-0.1.0.tar.gz -
Subject digest:
6f5f761181109b92fc89cbb8f3dd97577185972a9cf1d2d36b1d405a7f19fb22 - Sigstore transparency entry: 2256260731
- Sigstore integration time:
-
Permalink:
davidwickerhf/caselaw-access@3d644014ca9ca3d038bb0c21b37c5bdfcc29999d -
Branch / Tag:
refs/tags/python-v0.1.0 - Owner: https://github.com/davidwickerhf
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python.yml@3d644014ca9ca3d038bb0c21b37c5bdfcc29999d -
Trigger Event:
push
-
Statement type:
File details
Details for the file caselaw_access-0.1.0-py3-none-any.whl.
File metadata
- Download URL: caselaw_access-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef9a7c84b2cf69bb288175130d46a24c2f9e25f61d412eb3a70d7b16039d15b0
|
|
| MD5 |
f69970174c1e70c7a93569bee8c7c2f8
|
|
| BLAKE2b-256 |
90d29ec52eac0ff66011371bf26cbd27cf38ed9221542e6cd222ff874f79926a
|
Provenance
The following attestation bundles were made for caselaw_access-0.1.0-py3-none-any.whl:
Publisher:
publish-python.yml on davidwickerhf/caselaw-access
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
caselaw_access-0.1.0-py3-none-any.whl -
Subject digest:
ef9a7c84b2cf69bb288175130d46a24c2f9e25f61d412eb3a70d7b16039d15b0 - Sigstore transparency entry: 2256260744
- Sigstore integration time:
-
Permalink:
davidwickerhf/caselaw-access@3d644014ca9ca3d038bb0c21b37c5bdfcc29999d -
Branch / Tag:
refs/tags/python-v0.1.0 - Owner: https://github.com/davidwickerhf
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python.yml@3d644014ca9ca3d038bb0c21b37c5bdfcc29999d -
Trigger Event:
push
-
Statement type: