fhirsnake is a minimalistic FHIR server that serve yaml and json files as FHIR resources
The server reads all yaml and json files from an input directory (resources by default).
The input directory should have subdirectories with names equal to resource types:
resources/
├── Patient/
│ ├── example.yaml
│ ├── john-doe.json
│ └── patient3.yaml
├── Questionnaire/
│ ├── questionnaire1.yaml
│ ├── questionnaire2.yaml
│ └── subdir/
│ └── questionnaire3.yamlUse the --input flag to specify a custom input directory. For export and watch commands, --input can be passed multiple times to load resources from several directories.
The resource type always comes from the subdirectory name. By default the resource id is derived from the file name without extension (Patient/example.yaml → Patient/example); an id declared inside the file that differs from it is overridden with a warning. Pass --prefer-resource-id (available on server, export, and watch) to make the declared id win instead, still falling back to the filename-derived id when no id is declared. A declared id may contain an environment variable placeholder, which export resolves before building bundle entry URLs.
Questionnaires that share the same url (or id when url is missing) and differ by language are merged into a single resource during export and watch startup. On watch, editing any language file for a Questionnaire re-merges the group and PUTs the merged baseline resource.
Rely only on Questionnaire.language and Questionnaire.url — filenames are ignored for grouping.
- Baseline:
languagemissing oren(defaults toenwhen omitted) - Variants: other languages (
de,fr, …) - A single questionnaire per url/id is left unchanged
- Flat and nested
itemtrees in language files are both supported (linkIduniqueness) - Only baseline
linkIds are translated; extralinkIds in a variant are skipped - Translations are stored as FHIR primitive extensions (
_text,_title,_description,_displayonanswerOption.valueCoding) usinghttp://hl7.org/fhir/StructureDefinition/translation answerOptionentries are matched byvalueCoding.codealone; variant files may omitsystem
Example layout:
Questionnaire/
demo-questionnaire.yaml # language: en (or omitted)
demo-questionnaire.de.yaml # language: de
demo-questionnaire.fr.yaml # language: fr (items may be flat)To use environment variables in resources, you can use the syntax ${VAR_NAME}.
In the case of missing environment variable, the exception will be raised.
NOTE: The syntax $VAR without braces is not supported because it might be used in resources.
Important
All created and updated resources persist in runtime only. All changes are vanished after service restart
- read, create and update operations are supported
- search - limied support without any search params
GET /$indexoperation returns a map of all resources in format<resource_type>:<id>
- Organize resources in a directory
docker run \
-p 8002:8000 \
-v ./resources:/resources \
bedasoftware/fhirsnake server --input /resourcesOr build a custom image with Dockerfile.resources:
docker build -t bedasoftware/fhirsnake -f Dockerfile.resources .
docker run -p 8000:8000 fhirsnake-resourcesExport resources as .json (Bundle), .ndjson, or .ndjson.gz:
docker run \
-v ./resources:/resources \
-v ./output:/output \
bedasoftware/fhirsnake export \
--input /resources \
--output /output/seeds.ndjson.gzMultiple input directories:
docker run \
-v ./resources1:/resources1 \
-v ./resources2:/resources2 \
-v ./output:/output \
bedasoftware/fhirsnake export \
--input /resources1 \
--input /resources2 \
--output /output/seeds.ndjson.gzWith external FCE->FHIR converter:
docker run \
-v ./resources:/resources \
-v ./output:/output \
bedasoftware/fhirsnake export \
--input /resources \
--output /output/seeds.ndjson.gz \
--external-questionnaire-fce-fhir-converter-url http://host.docker.internal:3000/to-fhirWatch resources for changes and send as PUT requests to an external FHIR server:
docker run \
-v ./resources:/resources \
bedasoftware/fhirsnake watch \
--input /resources \
--external-fhir-server-url http://host.docker.internal:8080With auth headers:
docker run \
-v ./resources:/resources \
bedasoftware/fhirsnake watch \
--input /resources \
--external-fhir-server-url http://host.docker.internal:8080 \
--external-fhir-server-header "Authorization: Token token"Multiple input directories:
docker run \
-v ./resources1:/resources1 \
-v ./resources2:/resources2 \
bedasoftware/fhirsnake watch \
--input /resources1 \
--input /resources2 \
--external-fhir-server-url http://host.docker.internal:8080The image bedasoftware/questionnaire-fce-fhir-converter:latest provides a /to-fhir endpoint that can be used with the --external-questionnaire-fce-fhir-converter-url flag in export and watch commands.
Please, use Issues
ruff format
ruff check . --fixIssue new version - run semantic release locally
npx semantic-release --no-cipoetry build
poetry publish