Metadata-Version: 2.1
Name: fhir.resources
Version: 6.0.0b4
Summary: FHIR Resources as Model Class
Home-page: https://github.com/nazrulworld/fhir.resources
Author: Md Nazrul Islam
Author-email: email2nazrul@gmail.com
License: BSD license
Keywords: fhir,resources,python,hl7,health IT,healthcare
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Natural Language :: English
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Education
Classifier: Intended Audience :: Healthcare Industry
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Typing :: Typed
Requires-Python: >=3.6
Requires-Dist: pydantic[email]
Requires-Dist: orjson
Provides-Extra: all
Requires-Dist: coverage ; extra == 'all'
Requires-Dist: pytest-runner ; extra == 'all'
Requires-Dist: Jinja2 (==2.11.1) ; extra == 'all'
Requires-Dist: MarkupSafe (==1.1.1) ; extra == 'all'
Requires-Dist: requests (==2.23.0) ; extra == 'all'
Requires-Dist: colorlog (==2.10.0) ; extra == 'all'
Requires-Dist: certifi ; extra == 'all'
Requires-Dist: flake8 (==3.8.3) ; extra == 'all'
Requires-Dist: flake8-isort (==3.0.0) ; extra == 'all'
Requires-Dist: flake8-bugbear (==20.1.4) ; extra == 'all'
Requires-Dist: isort (==4.3.21) ; extra == 'all'
Requires-Dist: black ; extra == 'all'
Requires-Dist: mypy ; extra == 'all'
Requires-Dist: zest-releaser[recommended] ; extra == 'all'
Requires-Dist: pytest (>5.4.0) ; (python_version >= "3.6") and extra == 'all'
Requires-Dist: pytest-cov (>=2.10.0) ; (python_version >= "3.6") and extra == 'all'
Provides-Extra: test
Requires-Dist: coverage ; extra == 'test'
Requires-Dist: pytest-runner ; extra == 'test'
Requires-Dist: pytest (>5.4.0) ; (python_version >= "3.6") and extra == 'test'
Requires-Dist: pytest-cov (>=2.10.0) ; (python_version >= "3.6") and extra == 'test'

=================================
FHIR® Resources (R4, STU3, DSTU2)
=================================


.. image:: https://img.shields.io/pypi/v/fhir.resources.svg
        :target: https://pypi.python.org/pypi/fhir.resources

.. image:: https://img.shields.io/pypi/pyversions/fhir.resources.svg
        :target: https://pypi.python.org/pypi/fhir.resources
        :alt: Supported Python Versions

.. image:: https://img.shields.io/travis/nazrulworld/fhir.resources.svg
        :target: https://travis-ci.org/nazrulworld/fhir.resources

.. image:: https://codecov.io/gh/nazrulworld/fhir.resources/branch/master/graph/badge.svg
        :target: https://codecov.io/gh/nazrulworld/fhir.resources

.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
    :target: https://github.com/psf/black

.. image:: https://fire.ly/wp-content/themes/fhir/images/fhir.svg
        :target: https://www.hl7.org/implement/standards/product_brief.cfm?product_id=449
        :alt: HL7® FHIR®



Powered by pydantic_, all `FHIR Resources <https://www.hl7.org/fhir/resourcelist.html>`_ are available as python class with built-in
data validation, faster in performance and by default ``orjson`` is included as performance booster! Written in modern python.

* Easy to construct, easy to extended validation, easy to export.
* By inheriting behaviour from pydantic_, compatible with `ORM <https://en.wikipedia.org/wiki/Object-relational_mapping>`_.
* Full support of FHIR® Extensibility for Primitive Data Types are available.
* Previous release of FHIR® Resources are available.
* Free software: BSD license


FHIR® Version Info
------------------

FHIR® (Release R4, version 4.0.1) is available as default. Also previous versions are available as Python sub-package
(each release name string becomes sub-package name, i.e ``STU3`` ).

**Available Previous Versions**:

* ``STU3`` (3.0.2)
* ``DSTU2`` (1.0.2) [partially see `issue#13 <https://github.com/nazrulworld/fhir.resources/issues/13>`_]


Installation
------------

Just a simple ``pip install fhir.resources`` or ``easy_install fhir.resources`` is enough. But if you want development
version, just clone from https://github.com/nazrulworld/fhir.resources and ``pip install -e .[all]``.


Usages
------

**Example: 1**: Construct Resource Model object::

    >>> from fhir.resources.organization import Organization
    >>> from fhir.resources.address import Address
    >>> data = {
    ...     "id": "f001",
    ...     "active": True,
    ...     "name": "Acme Corporation",
    ...     "address": [{"country": "Swizterland"}]
    ... }
    >>> org = Organization(**data)
    >>> org.resource_type == "Organization"
    True
    >>> isinstance(org.address[0], Address)
    >>> True
    >>> org.address[0].country == "Swizterland"
    True
    >>> org.dict()['active'] is True
    True

**Example: 2**: Resource object created from json string::

    >>> from fhir.resources.organization import Organization
    >>> from fhir.resources.address import Address
    >>> json_str = '''{"resourceType": "Organization",
    ...     "id": "f001",
    ...     "active": True,
    ...     "name": "Acme Corporation",
    ...     "address": [{"country": "Swizterland"}]
    ... }'''
    >>> org = Organization.parse_raw(json_str)
    >>> isinstance(org.address[0], Address)
    >>> True
    >>> org.address[0].country == "Swizterland"
    True
    >>> org.dict()['active'] is True
    True


**Example: 3**: Resource object created from json object(py dict)::

    >>> from fhir.resources.patient import Patient
    >>> from fhir.resources.humanname import HumanName
    >>> from datetime import date
    >>> json_obj = {"resourceType": "Patient",
    ...     "id": "p001",
    ...     "active": True,
    ...     "name": [
    ...         {"text": "Adam Smith"}
    ...      ],
    ...     "birthDate": "1985-06-12"
    ... }
    >>> pat = Patient.parse_obj(json_obj)
    >>> isinstance(pat.name[0], HumanName)
    >>> True
    >>> org.birthDate == date(year=1985, month=6, day=12)
    True
    >>> org.active is True
    True


**Example: 4**: Construct Resource object from json file::

    >>> from fhir.resources.patient import Patient
    >>> import os
    >>> import pathlib
    >>> filename = pathlib.Path("foo/bar.json")
    >>> pat = Patient.parse_file(filename)
    >>> pat.resource_type == "Patient"
    True


**Example: 5**: Construct resource object in python way::

    >>> from fhir.resources.organization import Organization
    >>> from fhir.resources.address import Address
    >>> json_obj = {"resourceType": "Organization",
    ...     "id": "f001",
    ...     "active": True,
    ...     "name": "Acme Corporation",
    ...     "address": [{"country": "Swizterland"}]
    ... }

    >>> org = Organization.construct()
    >>> org.id = "f001"
    >>> org.active = True
    >>> org.name = "Acme Corporation"
    >>> org.address = list()
    >>> address = Address.construct()
    >>> address.country = "Swizterland"
    >>> org.address.append(address)
    >>> org.dict() == json_obj
    True


**Example: 4**: Using Resource Factory Function::

    >>> from fhir.resources import construct_fhir_element
    >>> json_dict = {"resourceType": "Organization",
    ...     "id": "mmanu",
    ...     "active": True,
    ...     "name": "Acme Corporation",
    ...     "address": [{"country": "Swizterland"}]
    ... }
    >>> org = construct_fhir_element('Organization', json_dict)
    >>> org.address[0].country == "Swizterland"
    True
    >>> org.dict()['active'] is True
    True


**Example: 5**: Auto validation while providing wrong datatype::

    >>> try:
    ...     org = Organization({"id": "fmk", "address": ["i am wrong type"]})
    ...     raise AssertionError("Code should not come here")
    ... except ValueError:
    ...     pass



Advanced Usages
---------------

Custom Validators
~~~~~~~~~~~~~~~~~

``fhir.resources`` is providing extensive API to create and attach custom validator into any model. See more `about root validator <https://pydantic-docs.helpmanual.io/usage/validators/#root-validators>`_
Some convention you have to follow while creating a root validator.

1. Number of arguments are fixed, as well as names are also. i.e ``(cls, values)``.
2. Should return ``values``, unless any exception need to be raised.
3. Validator should be attached only one time for individual Model.

Example 1: Validator for Patient::

    from typing import Dict
    from fhir.resources.patient import Patient

    import datetime

    def validate_birthdate(cls, values: Dict):
        if not values:
            return values
        if "birthDate" not in values:
            raise ValueError("Patient's ``birthDate`` is required.")

        minimum_date = datetime.date(2002, 1, 1)
        if values["birthDate"] > minimum_date:
            raise ValueError("Minimum 18 years patient is allowed to use this system.")
        return values
    # we want this validator to execute after data evaluating by individual field validators.
    Patient.add_root_validator(validate_gender, pre=False)



ENUM Validator
~~~~~~~~~~~~~~

``fhir.resources`` is providing API for enum constraint for each field (where applicable), but it-self doesn't
enforce enum based validation! see `discussion here <https://github.com/nazrulworld/fhir.resources/issues/23>`_.
If you want to enforce enum constraint, you have to create a validator for that.

Example: Gender Enum::

    from typing import Dict
    from fhir.resources.patient import Patient

    def validate_gender(cls, values: Dict):
        if not values:
            return values
        enums = cls.__fields__["gender"].field_info.extra["enum_values"]
        if "gender" in values and values["gender"] not in enums:
            raise ValueError("write your message")
        return values

    Patient.add_root_validator(validate_gender, pre=True)


Reference Validator
~~~~~~~~~~~~~~~~~~~

``fhir.resources`` is also providing enum like list of permitted resource types through field property ``enum_reference_types``.
You can get that list by following above (Enum) approaches  ``resource_types = cls.__fields__["managingOrganization"].field_info.extra["enum_reference_types"]``


Migration (from later than ``6.X.X``)
-------------------------------------

This migration guide states some underlying changes of ``API`` and replacement, those are commonly used from later than ``6.X.X`` version.


``fhir.resources.fhirelementfactory.FHIRElementFactory::instantiate``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Replacement:** ``fhir.resources.construct_fhir_element``

- First parameter value is same as previous, the Resource name.

- Second parameter is more flexible than previous! it is possible to provide not only json ``dict`` but also
  json string or json file path.

- No third parameter, what was in previous version.


``fhir.resources.fhirabstractbase.FHIRAbstractBase::__init__``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Replacement:** ``fhir.resources.fhirabstractmodel.FHIRAbstractModel::parse_obj<classmethod>``

- First parameter value is same as previous, json dict.

- No second parameter, what was in previous version.


``fhir.resources.fhirabstractbase.FHIRAbstractBase::as_json``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Replacement:** ``fhir.resources.fhirabstractmodel.FHIRAbstractModel::dict``

- Output are almost same previous, but there has some difference in case of some date type, for example py date,
  datetime, Decimal are in object representation.

- It is possible to use ``fhir.resources.fhirabstractmodel.FHIRAbstractModel::json`` as replacement, when
  json string is required (so not need further, json dumps from dict)


Note:

All resources/classes are derived from ``fhir.resources.fhirabstractmodel.FHIRAbstractModel`` what was previously
from ``fhir.resources.fhirabstractbase.FHIRAbstractBase``.


Release and Version Policy
--------------------------

Starting from  version ``5.0.0`` we are following our own release policy and we although follow Semantic Versioning scheme like FHIR® version.
Unlike previous statement (bellow), releasing now is not dependent on FHIR®.


**removed statement**

    This package is following `FHIR® release and versioning policy <https://www.hl7.org/fhir/versions.html>`_, for example say, FHIR releases next version 4.0.1,
    we also release same version here.


Credits
-------

All FHIR® Resources (python classes) are generated using fhir-parser_ which is forked from https://github.com/smart-on-fhir/fhir-parser.git.


This package skeleton was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.

.. _Cookiecutter: https://github.com/audreyr/cookiecutter
.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage
.. _`fhir-parser`: https://github.com/nazrulworld/fhir-parser
.. _`pydantic`: https://pydantic-docs.helpmanual.io/r

© Copyright HL7® logo, FHIR® logo and the flaming fire are registered trademarks
owned by `Health Level Seven International <https://www.hl7.org/legal/trademarks.cfm?ref=https://pypi.org/project/fhir-resources/>`_

.. role:: strike
    :class: strike


=======
History
=======

6.0.0b4 (2020-09-24)
--------------------

Improvements

- `orjson <https://github.com/ijl/orjson>`_ supports have been available as default json ``dumps`` and ``loads`` for Model.

- ``FHIRAbstractModel::get_json_encoder`` class method now available, which return pydantic compatible json encoder callable, can be used with any json serializer.

- More DSTU2 FHIR Resources have added, https://github.com/nazrulworld/fhir.resources/issues/21. Thanks to [mmabey].

Fixes

- Fixes URL validation in the case where a primitive type is used as URL (which is allowed in StructureDefinition). [simonvadee]

- Fixes `Issue#19 <https://github.com/nazrulworld/fhir.resources/issues/19>`_ Getting validation errors that don't make sense.


6.0.0b3 (2020-08-07)
--------------------

- ``FHIRAbstractModel::get_resource_type`` class method now available, which returning name of the resource.


6.0.0b2 (2020-07-09)
--------------------

- ``FHIRAbstractModel::element_properties`` class method now available, which returning generator of ``ModelField``,
  those are elements of the resource.

- Minor fixes on ``enum_values``.

6.0.0b1 (2020-07-05)
--------------------

Revolutionary evolution has been made, now fully rewritten with modern python, underlying APIs (almost all) have been changed.
Please have look at readme section, for howto.

Improvements

- Full support of FHIR `Extensibility <https://www.hl7.org/fhir/extensibility.html>`_ for `Primitive Data Types <https://www.hl7.org/fhir/datatypes.html#primitive>`_

Breaking

- Drop support for python 2.7.



5.1.0 (2020-04-11)
------------------

Improvements

- FHIR ``STU3`` release version upgraded from ``3.0.1`` to ``3.0.2``, Please find changes history here https://www.hl7.org/fhir/history.html.

- FHIR ``R4`` release version upgraded from ``4.0.0`` to ``4.0.1``, find changes history here https://www.hl7.org/fhir/history.html.


5.0.1 (2019-07-18)
------------------

Bugfixes:

- `Issue#5 <https://github.com/nazrulworld/fhir.resources/issues/5>`_ confusing error message "name 'self' is not defined" [nazrulworld]


5.0.0 (2019-06-08)
------------------

- Nothing but release stable version.


5.0.0b3 (2019-05-14)
--------------------

New features

- Isuue#1 `Add DSTU2 Support <https://github.com/nazrulworld/fhir.resources/issues/1>`_


5.0.0b2 (2019-05-13)
--------------------

Breaking or Improvments

- ``elementProperties``: element now has extra property ``type_name``. Now format like ``(name, json_name, type, type_name, is_list, "of_many", not_optional)``
  The ``type_name`` refers original type name (code) from FHIR Structure Definition and it would be very helpful while
  making fhir search, fhirpath navigator.



5.0.0b1 (2019-01-19)
--------------------

New features

- Implemented own build policy, now previous version of FHIR® resources are available as python sub-package.

Build info

- Default version is ``R4`` (see version info at `4.0.0b1 (2019-01-13)` section)

- ``STU3`` (see version info at `3.0.1 (2019-01-13)` section)


4.0.0 (2019-01-14)
------------------

- see version info at ``4.0.0b1`` section.


4.0.0b1 (2019-01-13)
--------------------

`Version Info (R4)`_ ::

    [FHIR]
    FhirVersion=4.0.0-a53ec6ee1b
    version=4.0.0
    buildId=a53ec6ee1b
    date=20181227223754



3.0.1 (2019-01-13)
------------------

`Version Info (STU3)`_ ::

    [FHIR]
    FhirVersion=3.0.1.11917
    version=3.0.1
    revision=11917
    date=20170419074443


.. _`Version Info (STU3)`: http://hl7.org/fhir/stu3/
.. _`Version Info (R4)`: http://hl7.org/fhir/R4/


