Python connector for the IntaOps SMART-on-FHIR R4 network
Project description
IntaOps Connector — Python
Drop-in Python SDK for the IntaOps SMART-on-FHIR R4 network.
pip install intaops
Prerequisites
Before the SDK can call IntaOps, you need OAuth credentials — client_id + client_secret. Get them from the IntaOps Dashboard:
- Sign in → Developer Portal → Applications (
https://infra.intaops.io/applications) - Create an Application — pick
client_credentialsfor backend services, orauthorization_codefor provider / patient-facing apps - Copy the
client_secretwhen shown — it's revealed once. Keep it server-side, never in browser code.
The SDK handles the OAuth token exchange (POST /oauth/token) for you — IntaOpsClient(client_id=…, client_secret=…) is enough. Access tokens are short-lived (~5 min) and refreshed automatically.
Backend (system-to-system)
from intaops import IntaOpsClient
client = IntaOpsClient(
client_id="app_live_…",
client_secret="secret_live_…",
environment="live", # or "sandbox"
scopes=["system/Patient.read", "system/Observation.read"],
)
patient = client.fhir.get("Patient", "u123")
for obs in client.fhir.search_iter("Observation", patient="u123"):
print(obs["valueQuantity"]["value"])
Provider / patient app (SMART user grant)
from intaops import IntaOpsClient
# Step 1 — generate PKCE + redirect the user
pkce = IntaOpsClient.generate_pkce()
client = IntaOpsClient(
client_id="app_live_…", environment="live",
scopes=["patient/Observation.read", "patient/MedicationRequest.read"],
)
url = client.authorize_url(
redirect_uri="https://yourapp.com/cb",
code_challenge=pkce.challenge,
)
# … redirect the user to `url`, capture `code` on the callback …
# Step 2 — exchange the code for tokens
client = IntaOpsClient.from_authorization_code(
code=code_from_callback,
redirect_uri="https://yourapp.com/cb",
code_verifier=pkce.verifier,
client_id="app_live_…",
environment="live",
scopes=["patient/Observation.read", "patient/MedicationRequest.read"],
)
obs = client.fhir.get("Observation", "obs-1")
Errors
from intaops import (
IntaOpsError, OAuthError, OperationOutcomeError,
ConsentRequiredError, RateLimitedError,
)
try:
client.fhir.get("Observation", "obs-1")
except ConsentRequiredError as e:
# First call to any patient/* scope ALWAYS returns this — consent is OFF
# by default. The IntaOps backend auto-pushes a prompt to the individual's
# IntaOps app; surface e.consent_url to them (push, email, in-app deep-link)
# and retry once they approve.
notify_user(e.user_id, e.consent_url)
except RateLimitedError as e:
time.sleep(e.retry_after or 30)
except OperationOutcomeError as e:
log(e.status_code, e.issue_code, e.location, e.outcome)
except OAuthError as e:
refresh_credentials(e.error)
Scope ↔ industry gating — the scopes your app can request are bounded by your entity's industry. Healthcare entities can request patient/* (consent-gated) and system/* (broad read) FHIR scopes; other industries are scoped to their own data surfaces (financial → financial data, retail → shopping, etc.). Requesting a scope outside your industry raises OAuthError("invalid_scope") at client instantiation.
API
IntaOpsClient(client_id, client_secret=, environment=, scopes=)IntaOpsClient.from_authorization_code(code, redirect_uri, code_verifier, …)IntaOpsClient.generate_pkce()→PKCEPairIntaOpsClient.authorize_url(redirect_uri, code_challenge, state=)→ strclient.fhir.get(resource_type, resource_id)→ dictclient.fhir.search(resource_type, **params)→ Bundle dictclient.fhir.search_iter(resource_type, **params)→ iterator of resourcesclient.fhir.create(resource_type, resource)→ dictclient.fhir.update(resource_type, resource_id, resource)→ dictclient.fhir.capability_statement()→ dict
License
Apache-2.0.
Project details
Release history Release notifications | RSS feed
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 intaops-0.1.1.tar.gz.
File metadata
- Download URL: intaops-0.1.1.tar.gz
- Upload date:
- Size: 18.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
515d4f58aec2bd2dee4a4afa49fafecdb92905471dd01b90e6c17369f4be58bc
|
|
| MD5 |
a2cb2084075483488a719ce3be905b5d
|
|
| BLAKE2b-256 |
3fd04bb43fc3e764060dcfc2158ba82cdb1a1777e95d282e4e0e9bdf55e2663a
|
File details
Details for the file intaops-0.1.1-py3-none-any.whl.
File metadata
- Download URL: intaops-0.1.1-py3-none-any.whl
- Upload date:
- Size: 20.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1f771d7ced52a575a9188683b0c91bf9b799535fa621e4e1e30e7990e825fcd
|
|
| MD5 |
2fc0e016c504f5573e6c8c63d8b28c08
|
|
| BLAKE2b-256 |
74cffc63362ecf4bc30e2a0f5c53758126799d3bd3c04c72624940cc1518b523
|