GraphQL service for exposing OMOP CDM records.
Exported scripts
load-omop-cdm-db-records
run-omop-cdm-graphql-app
Step 1 - Create Python virtual environment
python3 -m venv venv
Step 2 - Activate Python virtual environment
source venv/bin/activate
Step 3 - Install
pip install omop-cdm-graphql
Step 4 - Update the configuration file
---
port: 8081
url: http://localhost
database_file: /tmp/omop-cdm-graphql/omop-cdm-v1.db
Step 5 - Copy configuration file to launch directory
cp venv/lib/python3.10/site-packages/omop_cdm_graphql/conf/config.yaml .
Step 6 - Load the database
Run the loader to load mock records.
load-omop-cdm-db-records
Step 7 - Run the app
run-omop-cdm-graphql-app
Step 8 - Open browser
Step 9 - Execute queries
Query 1 - Retrieve person 1
query {
person(personId: 1) {
personId
genderConceptId
birthDatetime
observations {
observationId
observationConceptId
observationDate
}
conditions {
conditionOccurrenceId
conditionConceptId
conditionStartDate
}
}
}
Result:
{
"data": {
"person": {
"personId": 1,
"genderConceptId": 8507,
"birthDatetime": "1990-01-01T00:00:00",
"observations": [
{
"observationId": 1,
"observationConceptId": 123,
"observationDate": "2023-01-01T00:00:00"
},
{
"observationId": 7,
"observationConceptId": 129,
"observationDate": "2023-07-10T00:00:00"
}
],
"conditions": [
{
"conditionOccurrenceId": 1,
"conditionConceptId": 456,
"conditionStartDate": "2023-02-01T00:00:00"
},
{
"conditionOccurrenceId": 7,
"conditionConceptId": 462,
"conditionStartDate": "2023-08-20T00:00:00"
}
]
}
}
}
Query 2 - Retrieve all persons
query {
allPersons {
personId
genderConceptId
birthDatetime
}
}
Result:
{
"data": {
"allPersons": [
{
"personId": 1,
"genderConceptId": 8507,
"birthDatetime": "1990-01-01T00:00:00"
},
{
"personId": 2,
"genderConceptId": 8532,
"birthDatetime": "1985-05-15T00:00:00"
},
{
"personId": 3,
"genderConceptId": 8507,
"birthDatetime": "1978-03-22T00:00:00"
},
{
"personId": 4,
"genderConceptId": 8532,
"birthDatetime": "1995-07-10T00:00:00"
},
{
"personId": 5,
"genderConceptId": 8507,
"birthDatetime": "1982-11-30T00:00:00"
},
{
"personId": 6,
"genderConceptId": 8532,
"birthDatetime": "2000-04-15T00:00:00"
}
]
}
}
Query 3 - Filter Persons by Gender
Purpose: Shows how GraphQL lets clients filter data without needing a separate endpoint.
query {
personsByGender(genderConceptId: 8532) {
personId
birthDatetime
observations {
observationId
observationDate
}
}
}
Returns only female persons (gender_concept_id = 8532) with their observations. Client specifies exactly what fields they want (e.g., skipping conditions or genderConceptId), avoiding over-fetching.
Result:
{
"data": {
"personsByGender": [
{
"personId": 2,
"birthDatetime": "1985-05-15T00:00:00",
"observations": [
{
"observationId": 2,
"observationDate": "2023-03-15T00:00:00"
}
]
},
{
"personId": 4,
"birthDatetime": "1995-07-10T00:00:00",
"observations": [
{
"observationId": 4,
"observationDate": "2023-05-20T00:00:00"
}
]
},
{
"personId": 6,
"birthDatetime": "2000-04-15T00:00:00",
"observations": [
{
"observationId": 6,
"observationDate": "2023-06-01T00:00:00"
}
]
}
]
}
}
Query 4 - Recent Observations
Purpose: Demonstrates time-based filtering and standalone access to related entities.
query {
recentObservations(afterDate: "2023-03-01") {
observationId
observationConceptId
observationDate
}
}
Returns observations after March 1, 2023 (e.g., observation IDs 2, 4, 6, 7). No need to fetch persons first; GraphQL lets you query related data directly, reducing round trips.
Result:
{
"data": {
"recentObservations": [
{
"observationId": 2,
"observationConceptId": 124,
"observationDate": "2023-03-15T00:00:00"
},
{
"observationId": 4,
"observationConceptId": 126,
"observationDate": "2023-05-20T00:00:00"
},
{
"observationId": 6,
"observationConceptId": 128,
"observationDate": "2023-06-01T00:00:00"
},
{
"observationId": 7,
"observationConceptId": 129,
"observationDate": "2023-07-10T00:00:00"
}
]
}
}
Query 5 - Persons with a Specific Condition
Purpose: Highlights nested relationship traversal and conditional filtering.
query {
personsWithCondition(conditionConceptId: 456) {
personId
genderConceptId
conditions {
conditionOccurrenceId
conditionStartDate
}
observations {
observationId
}
}
}
Returns persons with condition_concept_id 456 (just person 1) and their conditions and observations. Combines filtering with flexible field selection across relationships in one request—impossible in REST without multiple calls or a custom endpoint.
Query - Nested Data with Selective Fields
Purpose: Shows how clients can pick and choose fields across relationships.
query {
allPersons {
personId
birthDatetime
observations {
observationDate
}
conditions {
conditionConceptId
}
}
}
Returns all 6 persons with only their birth dates, observation dates, and condition concept IDs. Avoids over-fetching unused fields (e.g., gender_concept_id, observation_id) and simplifies frontend logic—no need to parse bloated responses.
Results:
{
"data": {
"allPersons": [
{
"personId": 1,
"birthDatetime": "1990-01-01T00:00:00",
"observations": [
{
"observationDate": "2023-01-01T00:00:00"
},
{
"observationDate": "2023-07-10T00:00:00"
}
],
"conditions": [
{
"conditionConceptId": 456
},
{
"conditionConceptId": 462
}
]
},
{
"personId": 2,
"birthDatetime": "1985-05-15T00:00:00",
"observations": [
{
"observationDate": "2023-03-15T00:00:00"
}
],
"conditions": [
{
"conditionConceptId": 457
}
]
},
{
"personId": 3,
"birthDatetime": "1978-03-22T00:00:00",
"observations": [
{
"observationDate": "2022-12-10T00:00:00"
}
],
"conditions": [
{
"conditionConceptId": 458
}
]
},
{
"personId": 4,
"birthDatetime": "1995-07-10T00:00:00",
"observations": [
{
"observationDate": "2023-05-20T00:00:00"
}
],
"conditions": [
{
"conditionConceptId": 459
}
]
},
{
"personId": 5,
"birthDatetime": "1982-11-30T00:00:00",
"observations": [
{
"observationDate": "2023-01-25T00:00:00"
}
],
"conditions": [
{
"conditionConceptId": 460
}
]
},
{
"personId": 6,
"birthDatetime": "2000-04-15T00:00:00",
"observations": [
{
"observationDate": "2023-06-01T00:00:00"
}
],
"conditions": [
{
"conditionConceptId": 461
}
]
}
]
}
}
Query - Single Person Deep Dive
Purpose: Demonstrates deep nesting and customization.
query {
person(personId: 1) {
personId
birthDatetime
observations {
observationId
observationConceptId
observationDate
}
conditions {
conditionOccurrenceId
conditionConceptId
conditionStartDate
}
}
}
Returns person 1 with all observation and condition details. Replaces multiple REST calls (e.g., /persons/1, /persons/1/observations, /persons/1/conditions) with one precise query.
Result:
{
"data": {
"person": {
"personId": 1,
"birthDatetime": "1990-01-01T00:00:00",
"observations": [
{
"observationId": 1,
"observationConceptId": 123,
"observationDate": "2023-01-01T00:00:00"
},
{
"observationId": 7,
"observationConceptId": 129,
"observationDate": "2023-07-10T00:00:00"
}
],
"conditions": [
{
"conditionOccurrenceId": 1,
"conditionConceptId": 456,
"conditionStartDate": "2023-02-01T00:00:00"
},
{
"conditionOccurrenceId": 7,
"conditionConceptId": 462,
"conditionStartDate": "2023-08-20T00:00:00"
}
]
}
}
}
Step 10 - Execute queries via CLI using httpie
Query 1 - Retrieve person 1
http POST http://localhost:8081/graphql query=@examples/query1.graphql
Result:
Query 2 - Retrieve all persons
http POST http://localhost:8081/graphql query=@examples/query2.graphql
Query 3 - Filter Persons by Gender
http POST http://localhost:8081/graphql query=@examples/query3.graphql
Query 4 - Recent Observations
http POST http://localhost:8081/graphql query=@examples/query4.graphql
Query 5 - Persons with a Specific Condition
http POST http://localhost:8081/graphql query=@examples/query5.graphql
Query 6 - Nested Data with Selective Fields
http POST http://localhost:8081/graphql query=@examples/query6.graphql
Query 7 - Single Person Deep Dive
http POST http://localhost:8081/graphql query=@examples/query7.graphql
References
Metadata
Release files for omop-cdm-graphql 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| omop_cdm_graphql-0.6.0.tar.gz | 19.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| omop_cdm_graphql-0.6.0-py2.py3-none-any.whl | Python 2, Python 3 | none | any | Details |
Total release size: 32.8 kB
Release files / omop_cdm_graphql-0.6.0.tar.gz
| Download URL | omop_cdm_graphql-0.6.0.tar.gz |
|---|---|
| Size | 19.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ecaf70444096721ab92f19e9284a2edb289678c4751ac874bc81a507033fb58f
|
|
BLAKE2b-256 checksum How to use checksums |
5c775c35eab98437380e15e5f4f5de6e7c4f3362cc5aead8d31019518db98aec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.12
|
Release files / omop_cdm_graphql-0.6.0-py2.py3-none-any.whl
| Download URL | omop_cdm_graphql-0.6.0-py2.py3-none-any.whl |
|---|---|
| Size | 13.3 kB |
| Tags | Python 2 Python 3 |
|
SHA-256 checksum How to use checksums |
2bfdcaacc420c95bc55a4464a7297a8fc74cd87af4b28f5a536ff667b3d98047
|
|
BLAKE2b-256 checksum How to use checksums |
f983d3b23b9a46d82a7db393424801c2859a115ce16e5ce7aba9a3914ffb0079
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.12
|