# SMART FHIR Client
This is _fhirclient_, a flexible Python client for [FHIR][] servers supporting the [SMART on FHIR][smart] protocol.
Client versioning is not identical to FHIR versioning.
The `main` branch is usually on the latest version of the client, as shown below, and possibly on their bugfix releases.
The `develop` branch should be on recent freezes, and the `feature/latest-ci` branch is periodically updated to the latest FHIR continuous integration builds.
Version | FHIR |
-----------|--------------|---------
**4.2.0** | `4.0.1` | (R4)
**4.0.0** | `4.0.0` | (R4)
**3.0.0** | `3.0.0` | (STU-3)
**x.x** | `1.8.0` | (STU-3 Ballot, Jan 2017)
**x.x** | `1.6.0` | (STU-3 Ballot, Sep 2016)
**1.0.3** | `1.0.2` | (DSTU 2)
**1.0** | `1.0.1` | (DSTU 2)
**0.5** | `0.5.0.5149` | (DSTU 2 Ballot, May 2015)
**0.0.4** | `0.0.82.2943` | (DSTU 1)
**0.0.3** | `0.0.82.2943` | (DSTU 1)
**0.0.2** | `0.0.82.2943` | (DSTU 1)
## Installation
pip install fhirclient
## Documentation
Technical documentation is available at [docs.smarthealthit.org/client-py/][docs].
### Client Use
To connect to a SMART on FHIR server (or any open FHIR server), you can use the `FHIRClient` class.
It will initialize and handle a `FHIRServer` instance, your actual handle to the FHIR server you'd like to access.
##### Read Data from Server
To read a given patient from an open FHIR server, you can use:
```python
from fhirclient import client
from fhirclient.models.patient import Patient
settings = {
'app_id': 'my_web_app',
'api_base': 'https://r4.smarthealthit.org'
}
smart = client.FHIRClient(settings=settings)
patient = Patient.read('2cda5aad-e409-4070-9a15-e1c35c46ed5a', smart.server)
print(patient.birthDate.isostring)
# '1992-07-03'
print(smart.human_name(patient.name[0]))
# 'Mr. steve Smith'
```
If this is a protected server, you will first have to send your user to the authorization endpoint to log in.
Just call `smart.authorize_url` to obtain the correct URL.
You can use `smart.prepare()`, which will return `False` if the server is protected and you need to authorize.
The `smart.ready` property has the same purpose. However, it will not retrieve the server's _CapabilityStatement_ resource and hence is only fit as a quick check whether the server instance is ready.
```python
from fhirclient import client
settings = {
'app_id': 'my_web_app',
'api_base': 'https://r4.smarthealthit.org'
}
smart = client.FHIRClient(settings=settings)
smart.ready
# prints `False`
smart.prepare()
# prints `True` after fetching CapabilityStatement
smart.ready
# prints `True`
smart.prepare()
# prints `True` immediately
smart.authorize_url
# is `None`
```
You can work with the `FHIRServer` class directly without using `FHIRClient`. But this is not recommended:
```python
from fhirclient import server
from fhirclient.models.patient import Patient
smart = server.FHIRServer(None, 'https://r4.smarthealthit.org')
patient = Patient.read('2cda5aad-e409-4070-9a15-e1c35c46ed5a', smart)
print(patient.name[0].given)
# ['steve']
```
##### Search Records on Server
You can also search for resources matching a particular set of criteria:
```python
from fhirclient import client
from fhirclient.models.encounter import Encounter
from fhirclient.models.procedure import Procedure
settings = {
'app_id': 'my_web_app',
'api_base': 'https://r4.smarthealthit.org'
}
smart = client.FHIRClient(settings=settings)
search = Encounter.where(struct={'subject': '2cda5aad-e409-4070-9a15-e1c35c46ed5a', 'status': 'finished'})
print({res.type[0].text for res in search.perform_resources_iter(smart.server)})
# {'Encounter for symptom', 'Encounter for check up (procedure)'}
# to include the resources referred to by the encounter via `subject` in the results
search = search.include('subject')
print({res.resource_type for res in search.perform_resources_iter(smart.server)})
# {'Encounter', 'Patient'}
# to include the Procedure resources which refer to the encounter via `encounter`
search = search.include('encounter', Procedure, reverse=True)
print({res.resource_type for res in search.perform_resources_iter(smart.server)})
# {'Encounter', 'Patient', 'Procedure'}
# to get the raw Bundles instead of resources only, you can use:
bundles = search.perform_iter(smart.server)
print({entry.resource.resource_type for bundle in bundles for entry in bundle.entry})
# {'Encounter', 'Patient', 'Procedure'}
```
### Data Model Use
The client contains data model classes, built using [fhir-parser][], that handle (de)serialization and allow you to work with FHIR data in a Pythonic way. From version 1.0.5, the validity of the data model is enforced to a certain extent.
#### Initialize Data Model
```python
from fhirclient.models.patient import Patient
from fhirclient.models.humanname import HumanName
patient = Patient({'id': 'patient-1'})
print(patient.id)
# patient-1
name = HumanName()
name.given = ['Peter']
name.family = 'Parker'
patient.name = [name]
print(patient.as_json())
# {'id': 'patient-1', 'name': [{'family': 'Parker', 'given': ['Peter']}], 'resourceType': 'Patient'}
name.given = 'Peter'
print(patient.as_json())
# throws FHIRValidationError:
# {root}:
# name.0:
# given:
# Expecting property "given" on <class 'fhirclient.models.humanname.HumanName'> to be list, but is <class 'str'>
```
#### Initialize from JSON
```python
import json
from fhirclient.models.patient import Patient
pjs = json.loads('{"name": [{"given": ["Peter"]}], "resourceType": "Patient"}')
patient = Patient(pjs)
print(patient.name[0].given)
# ['Peter']
```
### Flask App
Take a look at
[flask_app.py](https://github.com/smart-on-fhir/client-py/blob/main/demos/flask/flask_app.py)
to see how you can use the client in a simple (Flask) app.
This demo requires a server that is capable of SMART OAuth logins for patients,
so make sure you have such a server ready first.
This app will start a web server,
listen on [_localhost:8000_](http://localhost:8000),
and prompt you to log in to our sandbox server and select a patient.
It then retrieves the selected patient's demographics and med prescriptions
and lists them on a simple HTML page.
The Flask demo app has separate requirements.
Clone the _client-py_ repository,
then create a virtual environment (not compulsory but recommended)
and install the needed packages as shown:
git clone https://github.com/smart-on-fhir/client-py.git
cd client-py/demos/flask
python3 -m venv env
. env/bin/activate
pip install -r requirements.txt
# Edit flask_app.py and put your own server's URL as api_base.
./flask_app.py
## See Also
- [cumulus-fhir-support](https://github.com/smart-on-fhir/cumulus-fhir-support/): similar network
client, with more authentication options and built-in retries, but no FHIR classes
- [fhir.resources](https://github.com/nazrulworld/fhir.resources): similar FHIR classes,
but has no network client
- [fhirpy](https://github.com/beda-software/fhir-py): similar FHIR classes and network client,
with async options, but has no OAuth support
- [smart-fetch](https://github.com/smart-on-fhir/smart-fetch): is a CLI command instead of a Python
library, but supports bulk export and REST requests
[fhir]: http://www.hl7.org/implement/standards/fhir/
[smart]: http://docs.smarthealthit.org
[fhir-parser]: https://github.com/smart-on-fhir/fhir-parser
[docs]: https://smart-on-fhir.github.io/client-py
Raw data
{
"_id": null,
"home_page": null,
"name": "fhirclient",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "smart, fhir, healthcare, medical-informatics, clinical-informatics, biomedical-informatics",
"author": null,
"author_email": "SMART Platforms Team <support@smarthealthit.org>",
"download_url": "https://files.pythonhosted.org/packages/0c/49/bdd28783dc1a48205d1221b205f402525bd7aa669d32d90ba8cabfa8c059/fhirclient-4.3.2.tar.gz",
"platform": null,
"description": "# SMART FHIR Client\n\nThis is _fhirclient_, a flexible Python client for [FHIR][] servers supporting the [SMART on FHIR][smart] protocol.\n\nClient versioning is not identical to FHIR versioning.\nThe `main` branch is usually on the latest version of the client, as shown below, and possibly on their bugfix releases.\nThe `develop` branch should be on recent freezes, and the `feature/latest-ci` branch is periodically updated to the latest FHIR continuous integration builds.\n\n Version | FHIR | \n-----------|--------------|---------\n **4.2.0** | `4.0.1` | (R4)\n **4.0.0** | `4.0.0` | (R4)\n **3.0.0** | `3.0.0` | (STU-3)\n **x.x** | `1.8.0` | (STU-3 Ballot, Jan 2017)\n **x.x** | `1.6.0` | (STU-3 Ballot, Sep 2016)\n **1.0.3** | `1.0.2` | (DSTU 2)\n **1.0** | `1.0.1` | (DSTU 2)\n **0.5** | `0.5.0.5149` | (DSTU 2 Ballot, May 2015)\n **0.0.4** | `0.0.82.2943` | (DSTU 1)\n **0.0.3** | `0.0.82.2943` | (DSTU 1)\n **0.0.2** | `0.0.82.2943` | (DSTU 1)\n\n\n## Installation\n\n pip install fhirclient\n\n\n## Documentation\n\nTechnical documentation is available at [docs.smarthealthit.org/client-py/][docs].\n\n### Client Use\n\nTo connect to a SMART on FHIR server (or any open FHIR server), you can use the `FHIRClient` class.\nIt will initialize and handle a `FHIRServer` instance, your actual handle to the FHIR server you'd like to access.\n\n##### Read Data from Server\n\nTo read a given patient from an open FHIR server, you can use:\n\n```python\nfrom fhirclient import client\nfrom fhirclient.models.patient import Patient\n\nsettings = {\n 'app_id': 'my_web_app',\n 'api_base': 'https://r4.smarthealthit.org'\n}\nsmart = client.FHIRClient(settings=settings)\n\npatient = Patient.read('2cda5aad-e409-4070-9a15-e1c35c46ed5a', smart.server)\nprint(patient.birthDate.isostring)\n# '1992-07-03'\nprint(smart.human_name(patient.name[0]))\n# 'Mr. steve Smith'\n```\nIf this is a protected server, you will first have to send your user to the authorization endpoint to log in.\nJust call `smart.authorize_url` to obtain the correct URL.\nYou can use `smart.prepare()`, which will return `False` if the server is protected and you need to authorize.\nThe `smart.ready` property has the same purpose. However, it will not retrieve the server's _CapabilityStatement_ resource and hence is only fit as a quick check whether the server instance is ready.\n\n```python\nfrom fhirclient import client\n\nsettings = {\n 'app_id': 'my_web_app',\n 'api_base': 'https://r4.smarthealthit.org'\n}\nsmart = client.FHIRClient(settings=settings)\n\nsmart.ready\n# prints `False`\nsmart.prepare()\n# prints `True` after fetching CapabilityStatement\nsmart.ready\n# prints `True`\nsmart.prepare()\n# prints `True` immediately\nsmart.authorize_url\n# is `None`\n```\n\nYou can work with the `FHIRServer` class directly without using `FHIRClient`. But this is not recommended:\n\n```python\nfrom fhirclient import server\nfrom fhirclient.models.patient import Patient\n\nsmart = server.FHIRServer(None, 'https://r4.smarthealthit.org')\npatient = Patient.read('2cda5aad-e409-4070-9a15-e1c35c46ed5a', smart)\nprint(patient.name[0].given)\n# ['steve']\n```\n\n##### Search Records on Server\n\nYou can also search for resources matching a particular set of criteria:\n\n```python\nfrom fhirclient import client\nfrom fhirclient.models.encounter import Encounter\nfrom fhirclient.models.procedure import Procedure\n\nsettings = {\n 'app_id': 'my_web_app',\n 'api_base': 'https://r4.smarthealthit.org'\n}\nsmart = client.FHIRClient(settings=settings)\n\nsearch = Encounter.where(struct={'subject': '2cda5aad-e409-4070-9a15-e1c35c46ed5a', 'status': 'finished'})\nprint({res.type[0].text for res in search.perform_resources_iter(smart.server)})\n# {'Encounter for symptom', 'Encounter for check up (procedure)'}\n\n# to include the resources referred to by the encounter via `subject` in the results\nsearch = search.include('subject')\nprint({res.resource_type for res in search.perform_resources_iter(smart.server)})\n# {'Encounter', 'Patient'}\n\n# to include the Procedure resources which refer to the encounter via `encounter`\nsearch = search.include('encounter', Procedure, reverse=True)\nprint({res.resource_type for res in search.perform_resources_iter(smart.server)})\n# {'Encounter', 'Patient', 'Procedure'}\n\n# to get the raw Bundles instead of resources only, you can use:\nbundles = search.perform_iter(smart.server)\nprint({entry.resource.resource_type for bundle in bundles for entry in bundle.entry})\n# {'Encounter', 'Patient', 'Procedure'}\n```\n\n### Data Model Use\n\nThe client contains data model classes, built using [fhir-parser][], that handle (de)serialization and allow you to work with FHIR data in a Pythonic way. From version 1.0.5, the validity of the data model is enforced to a certain extent.\n\n#### Initialize Data Model\n\n```python\nfrom fhirclient.models.patient import Patient\nfrom fhirclient.models.humanname import HumanName\n\npatient = Patient({'id': 'patient-1'})\nprint(patient.id)\n# patient-1\n\nname = HumanName()\nname.given = ['Peter']\nname.family = 'Parker'\npatient.name = [name]\nprint(patient.as_json())\n# {'id': 'patient-1', 'name': [{'family': 'Parker', 'given': ['Peter']}], 'resourceType': 'Patient'}\n\nname.given = 'Peter'\nprint(patient.as_json())\n# throws FHIRValidationError:\n# {root}:\n# name.0:\n# given:\n# Expecting property \"given\" on <class 'fhirclient.models.humanname.HumanName'> to be list, but is <class 'str'>\n```\n\n#### Initialize from JSON\n\n```python\nimport json\nfrom fhirclient.models.patient import Patient\n\npjs = json.loads('{\"name\": [{\"given\": [\"Peter\"]}], \"resourceType\": \"Patient\"}')\npatient = Patient(pjs)\nprint(patient.name[0].given)\n# ['Peter']\n```\n\n### Flask App\n\nTake a look at\n[flask_app.py](https://github.com/smart-on-fhir/client-py/blob/main/demos/flask/flask_app.py)\nto see how you can use the client in a simple (Flask) app.\n\nThis demo requires a server that is capable of SMART OAuth logins for patients,\nso make sure you have such a server ready first.\n\nThis app will start a web server,\nlisten on [_localhost:8000_](http://localhost:8000),\nand prompt you to log in to our sandbox server and select a patient.\nIt then retrieves the selected patient's demographics and med prescriptions\nand lists them on a simple HTML page.\n\nThe Flask demo app has separate requirements.\nClone the _client-py_ repository,\nthen create a virtual environment (not compulsory but recommended)\nand install the needed packages as shown:\n\n git clone https://github.com/smart-on-fhir/client-py.git\n cd client-py/demos/flask\n python3 -m venv env\n . env/bin/activate\n pip install -r requirements.txt\n # Edit flask_app.py and put your own server's URL as api_base.\n ./flask_app.py\n\n\n## See Also\n\n- [cumulus-fhir-support](https://github.com/smart-on-fhir/cumulus-fhir-support/): similar network\n client, with more authentication options and built-in retries, but no FHIR classes\n- [fhir.resources](https://github.com/nazrulworld/fhir.resources): similar FHIR classes,\n but has no network client\n- [fhirpy](https://github.com/beda-software/fhir-py): similar FHIR classes and network client,\n with async options, but has no OAuth support\n- [smart-fetch](https://github.com/smart-on-fhir/smart-fetch): is a CLI command instead of a Python\n library, but supports bulk export and REST requests\n\n\n[fhir]: http://www.hl7.org/implement/standards/fhir/\n[smart]: http://docs.smarthealthit.org\n[fhir-parser]: https://github.com/smart-on-fhir/fhir-parser\n[docs]: https://smart-on-fhir.github.io/client-py\n\n",
"bugtrack_url": null,
"license": null,
"summary": "A flexible client for FHIR servers supporting the SMART on FHIR protocol",
"version": "4.3.2",
"project_urls": {
"Documentation": "https://docs.smarthealthit.org/client-py/",
"Homepage": "https://github.com/smart-on-fhir/client-py"
},
"split_keywords": [
"smart",
" fhir",
" healthcare",
" medical-informatics",
" clinical-informatics",
" biomedical-informatics"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "51cbc3176d7973bd085127005618feadb947bac9fd552413e7743d7007965a4d",
"md5": "d02c6740c3532666589d26fc875c1830",
"sha256": "7718869d4ddfd8d9d148991290276f6337b86a385dfa69ad6d1bd703074b06d2"
},
"downloads": -1,
"filename": "fhirclient-4.3.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d02c6740c3532666589d26fc875c1830",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 425660,
"upload_time": "2025-08-01T11:49:12",
"upload_time_iso_8601": "2025-08-01T11:49:12.669373Z",
"url": "https://files.pythonhosted.org/packages/51/cb/c3176d7973bd085127005618feadb947bac9fd552413e7743d7007965a4d/fhirclient-4.3.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "0c49bdd28783dc1a48205d1221b205f402525bd7aa669d32d90ba8cabfa8c059",
"md5": "a4482913581065a1d9375c590fbe0fa4",
"sha256": "e71881a06167681e53d780c1a581d3e18cca3a93e789ca21acf2d8374a3c59a6"
},
"downloads": -1,
"filename": "fhirclient-4.3.2.tar.gz",
"has_sig": false,
"md5_digest": "a4482913581065a1d9375c590fbe0fa4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 264522,
"upload_time": "2025-08-01T11:49:15",
"upload_time_iso_8601": "2025-08-01T11:49:15.277954Z",
"url": "https://files.pythonhosted.org/packages/0c/49/bdd28783dc1a48205d1221b205f402525bd7aa669d32d90ba8cabfa8c059/fhirclient-4.3.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-01 11:49:15",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "smart-on-fhir",
"github_project": "client-py",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"lcname": "fhirclient"
}