<jupyter_start><jupyter_text>🔥 FHIR 101 - A Practical Guide  Hello! What is this Guide? If any of the following statements applies to you or you've had any of the questions below, then this guide is for you!- 🤷‍♀️ I've heard the term FHIR. But is it a server? A database? A data model? Rapid oxidation?- 🙀 I understand what FHIR is but have no idea how to begin implementing it!- 😕 I tried reading through [HL7 FHIR](https://www.hl7.org/fhir/), but it is confusing and difficult to navigate.- 🤔 How does FHIR modeling compare to relational database design?The primary purpose of this notebook is to quickly educate you on what FHIR is and to walk you through practical exercises that will teach you the FHIR basics:1. Create and validate a FHIR data model for an entity2. Add/remove attributes to/from an entity in the model3. Create attributes which are constrained by ontologies3. Make entity attributes searchable in the FHIR server4. Deploy the FHIR data model into a FHIR server5. Load data into the FHIR server which conforms to the model6. Search for data in the FHIR server**If you don't care to know background information and want to get right to development, skip to the [Tutorial](Tutorial) section!**  Icons in this Guide📘 A link to a useful external reference related to the section the icon appears in⚡️ A key takeaway for the section that this icon appears in🖐 A hands-on section where you will code something or interact with the server  What is FHIR? Let's start with understanding exactly what FHIR is. FHIR stands for `Fast Healthcare Interoperability Resources` and was created by the `Health Level 7` organization or `HL7`.There is a large, active international community that helps develop the specification. You can read more about it here: 📘 Learn more about [FHIR](http://hl7.org/fhir/index.html)📘 Learn more about [HL7](http://hl7.org)  FHIR is ...A specification that includes all of the following:- A loosely defined [base data model](https://www.hl7.org/fhir/resourcelist.html) describing things in healthcare (e.g. Patient, Specimen) and how they relate to     each other. The base data model also includes definitions and restrictions on server functionality- How to extend or change the base data model to fit different healthcare use cases- A database agnostic domain specific language (DSL) for developing files that make up the FHIR data model- A [RESTful web API specification](https://www.hl7.org/fhir/exchange-module.html) to create, read, update, delete, and search FHIR data in a FHIR server- A RESTful query language that describes how to construct search queries for a FHIR server- Standards for how consumers of FHIR data should be authenticated and authorized access to health data.  FHIR is NOT ...- A database- A database schema- A serverIt is important to understand that the FHIR specification is completely technology agnostic. Thus, it does not depend on programming languages or include things like relational database schemas. It is up to the implementers to decide how to implement the data model (i.e. relational database, nosql database, etc) and RESTful API.   Concepts The FHIR spec is large and daunting, so this tutorial cannot cover all of the major concepts in FHIR. However, this section and the next should give you all that you need in order to understand what you're doing in the tutorial. 📘 A good resource to learn [FHIR Basics](https://smilecdr.com/docs/tutorial_and_tour/fhir_basics.htmlfhir-basics)  FHIR Resource  The term "Resource" can be confusing, as it is sometimes used to describe different concepts in FHIR. This diagram should help illustrate the difference between a Resource, type of Resource, and group/category of Resource types:![FHIR Concepts](static/images/resource-breakdown.png)  Resource Instances, Types, and Groups**Resource** - an instance of a type of thing. A Resource has an identifier. Example resources are:- Patient `PT-001`- Specimen `SP-001`- StructureDefinition `KidsFirst-Patient`- SearchParameter `patient-race`- ...**Resource Type** - a type of a thing. Example resource types are:- Patient- Specimen- StructureDefinition- SearchParameter- ...**Resource Type Category/Group** - a logical grouping of Resources. Examples are:- [Conformance Resources](Conformance-Resources)- [Terminology Resources](Terminology-Resources)- ...The most important categories of resource types for the purposes of this tutorial are `Conformance Resources` and `Terminology Resources`, because these are the ones we will create in order to build a FHIR data model. You will learn about them in the [Model Development](Model-Development) section**A `Patient` resource might look like this:**```json{    "resourceType":"Patient",    "id": "PT-001",    "meta": {        "profile": ["http://fhir.kids-first.io/StructureDefinition/Patient"]    },    "gender": "male",    "name": [        {            "use": "usual",            "family":"Smith",            "given": "Jack",            "period": {                "end": "2001-01-01"            }        }    ]}``` 📘 Learn more about [FHIR Resources](https://www.hl7.org/fhir/resource.html)  FHIR Data Types FHIR resource models use a set of data types for holding their values. Data types can be primitive, meaning that they hold a simple value (typically a string, a number, etc.). Other data types are composite, meaning they are a structure containing several elements. Some examples are:**Primitive Data Types**- String - some text - `female`- Decimal - decimal representation of a rational number with significant precision - `1.240`**Composite Data Types**- HumanName - A person's complete name, broken into individual parts```json{   "family": "Smith",   "given": [ "John", "Frank" ],   "suffix": [ "Jr" ]}```📘 Learn about all [FHIR Data Types](https://www.hl7.org/fhir/datatypes.html)  FHIR Versions Changes to the FHIR specification are tracked via different versions. A FHIR version has a name and a semantic version number. The biggest differences among versions are usually structural and contentchanges in the FHIR base model definitions.The most current and commonly used versions are:- STU3 or version 3.0.2- R4 or version 4.0.1The FHIR version names do not change, but the semantic version numbers can. For example, the `R4` version started with a semantic version number of `4.0.0`. When minor changes were made to `R4`, a new semantic version, `4.0.1` was created to track those changes.**This tutorial will always use version R4 of the FHIR specification**📘 Learn more about [FHIR Versions](https://www.hl7.org/fhir/versions.htmlversions)  Model Development What does it mean to develop a FHIR data model? Well, its not entirely different from developing any kind of data model. Developing a data model usually consists of the following steps: 1. Define entities in the model and their attributes2. Define relationships between entities3. Define constraints on entity attributes (i.e. types, min/max, one of, etc)4. Define constraints on entity relationships (i.e. Specimen must have one Patient, DiagnosticReport must have one      Patient, etc.)5. Validate the modelMore concretely, developing a data model in FHIR means:1. Authoring XML/JSON files containing `Conformance Resource` and `Terminology Resource` payloads2. Validating `Conformance Resource` and `Terminology Resource` using one of the standalone HL7 validation tools or POSTing the resource payload to a FHIR server ⚡️ **Key Takeaway** - when we say "model" in FHIR, we are referring to `Conformance Resources` and `Terminology Resources`  Conformance Resources There are several different types of `Conformance Resources` but the ones that are used most in FHIR model development are: - `StructureDefinition` - this resource captures model development steps 1 through 4 above for healthcare entities like `Patient`, `Specimen`, `DiagnosticReport`, etc.- `SearchParameter` - this resource is used to specify an attribute on an entity (e.g. Patient.gender) which can be used to search for instances of that entity on a FHIR server and what keyword/path (e.g. Patient.gender.code.value) should be used when searching.We will take a deep dive into both of these in the tutorial.📘 Learn more about [Conformance Resources](https://www.hl7.org/fhir/conformance-module.html)  Terminology Resources Some entity attributes might need to be constrained to a particular Value Set which may come from a particular terminology system (or ontology) which defines attributes, their set of valid values, and an alphanumeric code that uniquely identifies each value.For example, we may want to constrain the `bodySite` attribute on `Specimen` to only have values from NCIT ontology's `Specimen Source Site`. We can do this by defining `Terminology Resource`s and referencing them in the `StructureDefinition` for `Specimen`.Types of `Terminology Resource`s are:- `CodeSystem` - describes an Ontology, Terminology, or Enumeration- `ValueSet` - specifies a set of codes drawn from one or more code systemsYou will see a practical example of this later in the tutorial.📘 Learn about [Terminology Resources](https://www.hl7.org/fhir/terminologies.html)  Model Documentation  Implementation GuideFHIR data models are documented in a static website called an Implementation Guide. It has a standard format and looks much like the HL7 FHIR website. Implementation Guides describe and visually illustrate:- The model's `Conformance Resource`s, `Terminology Resource`s- The differences between the model's `StructureDefinition`s and the ones they extend- Example Resources for each `StructureDefinition`- The searchable attributes on each ResourceThere is a FHIR Conformance Resource named `ImplementationGuide` which is used to store configuration information for generating the static site. Create and PublishImplementation Guides are generated using the [HL7 IG Publisher](https://confluence.hl7.org/display/FHIR/IG+Publisher+Documentation) Java CLI. The IG Publisher also fully validates the data model during its site generation process, so it is often used as a model validation tool as well. The Kids First FHIR model uses it in this way.📘 Learn more about Kids First [IG generation and model validation](https://github.com/kids-first/kf-model-fhir/blob/master/README.md) using IG Publisher   Model Validation There are 2 primary ways to validate:1. Use the [HL7 IG Publisher](https://confluence.hl7.org/display/FHIR/IG+Publisher+Documentation) Java CLI (frequently referred to as IG Publisher or just Publisher)2. Use a FHIR server    - POST StructureDefinitions to the `/StructureDefinition` endpoint    - POST example Resources to the `//$validate` endpoint HL7 IG PublisherThe most thorough and standard way to validate a FHIR data model is to use the IG Publisher. The IG Publisher is under active development and is the most up-to-date in terms of its validation logic. However, since the IG Publisher tightly couples IG site generation with validation, it can be complicated to use since successful validation depends on proper location of resource files and other necessary configuration for IG. Use a FHIR ServerThe second method is easier but not standard. All compliant FHIR servers will implement basic validation logic. However, some servers may or may not implement additional validation/checks that the IG Publisher does.To keep things simple, this tutorial will use the second method of validation. Do I POST `//$validate` or POST `/` to validate?You may be wondering if you can simply validate and create a resource in a single requestby POSTing to `// endpoint. The answer is you *can*, however, it is notguarenteed your resource will be validated.     This is because some servers have an on/off switch for validation. If validation is turned off then you will be able to create invalid resources (does not conform to model). If the server implements the `$validate` operation/endpoint (not all servers do), then it is safe to assume that the resource you POST to this endpoint will be validated. ⚡️ **Key Takeaway** - the most thorough way to validate a FHIR data model is using the HL7 IG Publisher  Server Development  Pick an Existing SolutionYou might have noticed that there are not many open source or free FHIR servers currently in development. This is likely due to a couple of factors:- The FHIR specification is rapidly evolving and the tooling around it is still in early stages of development. - Server development is hard.In order to develop a compliant FHIR server, you must: - Implement the FHIR model validation logic. This is not easy since a FHIR model is authored  in the FHIR DSL. The server must know how to parse the DSL (a.k.a. Conformance Resources) andexecute rules defined in them.- Implement a parser and query constructor for the FHIR RESTful query language, which is also custom and not based on any known standard. Additionally, the kinds of search queries that can be made with a FHIR search API are fairly rich and complex.For these reasons it is best to select one of the existing FHIR server solutions rather than develop your own. FHIR Server SolutionsFrom personal experience and a fair bit of research, the most promising ones are:                                                                                                                                                                                  Tutorial  Real World Use CaseIn this tutorial we will create a simple data model that is able to capture basic demographic information about Leukemia patients that have had a biosample drawn from them.  No protected health information [(PHI)](https://www.hipaajournal.com/considered-phi-hipaa/) data should be captured. In fact there should be no PHI attributes available anywhere in the model.At a minimum we want to capture:**Patient Attributes**- Gender (required)- Race (required)- Biological Sex**Specimen Attributes**- The patient from whom the sample was drawn- Anatomical site or location on the body from which the sample was drawn- Composition - the type of sample - blood, tissue, saliva, etc. What You'll LearnYou will learn the following practical concepts in this tutorial:- How to create a new model for a FHIR resource by extending its base model- How to add/remove attributes from the base model- How to make attributes required- How to make an attribute searchable- How to add a coded attribute - or one that is restricted to an enumeration defined by an ontology- How to validate your model- How to document your model  Setup  Requirements**FHIR Server**- For this tutorial we will use [HAPI](http://hapi.fhir.org/), the open-source FHIR server behind Smile CDR.**Base URL**- All HTTP requests will be sent to the HAPI public test server's FHIR version R4 base URL: http://hapi.fhir.org/baseR4**Model Development Editor**You will need something to author JSON formatted model files. Unfortunately there are almost no user friendly tools for this. Most model development is done in a code editor. This can be difficult as it requires the developer to unecessarily remember complex syntax of the FHIR DSL in order to create and edit model files.- **Forge** - is a [visual editor for FHIR model development](https://simplifier.net/forge). It does make some things easier, but it can be buggy and was natively developed for Windows. It may be possible to [run Forge on macOS using Wine](http://docs.simplifier.net/forge/forgeInstall.htmlrunning-on-macos).  Development Environment 🖐Here we're going to import the code we need and complete the necessary setup which will be used later in the tutorial.**You do not need to do this if you would like to use another HTTP client like `Postman` to interact with the FHIR server.**<jupyter_code># Be sure to execute this cell so that we can use the client later
from pprint import pprint
from client import FhirApiClient

BASE_URL = 'http://hapi.fhir.org/baseR4'
FHIR_VERSION = '4.0.0'
client = FhirApiClient(base_url=BASE_URL, fhir_version=FHIR_VERSION)<jupyter_output><empty_output><jupyter_text>Create a Patient Model The FHIR base model was intended to include many common healthcare entitieslike patients, biospecimens, etc. which cover 80% of healthcare data captureuses cases.It is rare to come across a healthcare entity that isn't represented inone of the existing FHIR resources. The remaining 20% of data capture use casesthat are not satisfied by the base model can easily be satisfied by extendingthe base model.So we can start by looking at the base model's `Patient` `StructureDefinition` tosee if anything needs to be modified. The HL7 FHIR website has a nice visual representation of the `Patient``StructureDefinition`:[![Patient StructureDefinition](static/images/patient-sd-visual.png)](https://www.hl7.org/fhir/patient.htmlresource)📘 Learn about the [symbol definitions in the structure visual representations](http://hl7.org/fhir/formats.htmltable)We can already see that the `Patient` `StructureDefinition` has one attribute we want:- `gender`And many attributes that we'll want to **remove** because they represent PHI fields:- `name`- `telecom`- `address`- `birthDate`- `contactPoint`- `photo`  Start with a TemplateWe've seen that `StructureDefinition`s are complex. It is difficult to remember what attributes are required, the structure, and syntax. Tools like Forge hide that complexity since you're working with a UI. However, if you don't have or want to use such a tool, you can browse existing `StructureDefinition`s and pick one similar to what you need and use it as a template.  - 📘Implementation Guides published on [HL7 FHIR IG registry](https://registry.fhir.org/guides) also have links to their documented `StructureDefinition`s- 📘 [Simplifier.net](https://simplifier.net) also has its own Implementation Guide registry at [https://simplifier.net/guides](https://simplifier.net/guides).  Create Initial Patient StructureDefinition 🖐 To create a custom data model for patients, we must create a new `StructureDefinition` which will extend the existing FHIR R4 `StructureDefinition` for `Patient`:<jupyter_code># Be sure to execute this cell so that we can use `patient_sd` in later code cells
patient_sd = {
    "resourceType": "StructureDefinition",
    "url": "http://fhir.kids-first.io/StructureDefinition/Patient",
    "version": "0.1.0",
    "name": "kids_first_research_participant",
    "title": "Kids First Research Participant",
    "status": "draft",
    "publisher": "Kids First DRC",
    "description": "The individual human or other organism.",
    "fhirVersion": "4.0.0",
    "kind": "resource",
    "abstract": False,
    "type": "Patient",
    "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Patient",
    "derivation": "constraint",
    "differential": {
        "element": [
            {
                "id": "Patient",
                "path": "Patient"
            },
            {
                "id": "Patient.identifier",
                "path": "Patient.identifier",
                "mustSupport": True
            },
            {
                "id": "Patient.name",
                "path": "Patient.name",
                "max": "0"
            },
            {
                "id": "Patient.telecom",
                "path": "Patient.telecom",
                "max": "0"
            },
            {
                "id": "Patient.address",
                "path": "Patient.address",
                "max": "0"
            },
            {
                "id": "Patient.photo",
                "path": "Patient.photo",
                "max": "0"
            },
            {
                "id": "Patient.contact",
                "path": "Patient.contact",
                "max": "0"
            },
            {
                "id": "Patient.gender",
                "path": "Patient.gender",
                "min": 1
            }
        ]
    }
}<jupyter_output><empty_output><jupyter_text>Anatomy of StructureDefinition We won't cover this in great detail, but here are the important parts of the `StructureDefinition`:- `resourceType` - every FHIR resource has to declare what type it is- `baseDefinition` - this points to the `StructureDefinition` that the current one extends. It doesn't have to be one of the base FHIR definitions. It could come from any FHIR data model. This is one of the features of FHIR that helps achieve interoperability.- `url` - this is a required unique identifier for a `Conformance Resource`. It is a stable [canonical identifier](http://hl7.org/fhir/resource.htmlcanonical) for the resource and is never intended to change regardless of which FHIR server uses it.- `fhirVersion` - the FHIR semantic version number is required. It will instruct  anything validating this resource to use R4 (4.0.0) validation logic.- `differential` or `snapshot` - Every `StructureDefinition` must have either a `differential` - a section of content that specifies differences from the base definition, or a `snapshot` section which specifies the full definition. For model development, you almost always use the `differential` section and not the `snapshot`. Important Notes1. **Canonical URL**    Canonical URLs do not need to be live URLs. 2. **Base Definition**    Let's say `StructureDefinition` A points to `StructureDefinition` B via it's `baseDefinition` attribute. In order for `StructureDefinition` A to pass validation by a FHIR server, `StructureDefinition` B MUST be already be loaded in the FHIR server.3. **Min and Max Data Types**     You may have noticed that the data types for `min` and `max` differ. This is because `max`    can be set to a number or `*` which means many/unlimited, while `min` can only be set to a     number. 📘 Learn more about [StructureDefinition anatomy](http://hl7.org/fhir/structuredefinition.html)📘 Learn more about [Resource identifiers](http://hl7.org/fhir/resource.htmlidentification)📘 Browse [FHIR data models from other projects](https://simplifier.net/search?searchtype=Projects)  Remove Attributes We're going to start with the easiest modification first: removing an attribute from the base model. In fact, in our initial `Patient` `StructureDefinition`, we've already removed a handful of attributes. To remove an attribute you simply set its maximum cardinality to 0 in the `StructureDefinition` `differential` section: ```json{    "id": "Patient.name",    "path": "Patient.name",    "max": "0"}```  Make an Attribute RequiredThis is just as simple as removing an attribute. To make an attribute required you simply set its minimum cardinality to 1 in the `StructureDefinition` `differential` section:```json{    "id": "Patient.gender",    "path": "Patient.gender",    "min": 1}```**A Note on "mustSupport"**- You might have seen the keyword `mustSupport` in some StructureDefinitions. Sometimes it can be confused with `min=1` which makes an attribute required. - The `mustSupport` keyword actually doesn't have anything to do with making an attribute required. Instead, `mustSupport` means that implementations that produce or consume resources SHALL provide "support" for the element in some meaningful way. 📘 You can learn more about [mustSupport](https://www.hl7.org/fhir/conformance-rules.htmlmustSupport) from the HL7 FHIR spec📘 Learn about [conformance language key words](https://www.hl7.org/fhir/conformance-rules.htmlconflang): SHALL, SHOULD, MAY  Validate the Patient Model 🖐 Validating the Kids First Patient model means 2 things:1. Validate the Kids First `Patient` `StructureDefinition` - structure, syntax, cardinality, etc.2. Test both valid and invalid `Patient` Resources against the Kids First Patient `StructureDefinition`📘 Learn more about [Resource Validation](https://www.hl7.org/fhir/validation.html)  Validate StructureDefinition<jupyter_code>def validate(payload, expected_success=True, print_result=False):
    rt = payload.get('resourceType')
    endpoint = f'{client.base_url}/{rt}'

    # Let's get into the habit of deleting existing instances before we create one
    # The easiest way to do this is to search for StructureDefinitions by canonical URL and
    # then delete what is returned (should only be 1 since canonical URL is a unique ID)
    success = client.delete_all(endpoint, params={'url': payload['url']})
    print(f'DELETE {payload["url"]}')
    assert success

    # POST the Patient StructureDefinition to the /StructureDefinition endpoint
    success, result = client.send_request('POST', endpoint, json=payload)
    if print_result:
        pprint(result)
    print(f'POST {endpoint}, {payload.get("name")}')
    assert success == expected_success      

validate(patient_sd, print_result=True)<jupyter_output><empty_output><jupyter_text>Create a Patient Resource<jupyter_code># Let's start by creating a valid (has all required attributes) Patient resource
patient_rs = {
    "resourceType":"Patient",
    "id": "kidsfirst-test-patient",
    "text": {
        "status": "generated",
        "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>A valid patient resource for testing purposes</p></div>"
    },
    "meta": {
        "profile": ["http://fhir.kids-first.io/StructureDefinition/Patient"]
    },
    "gender": "male"
}<jupyter_output><empty_output><jupyter_text>Validate the Patient Resource  To test the `Patient` resource against the Kids First Patient model you must declare that this resource conforms to the `Patient` `StructureDefinition` like this:```json"meta": {    "profile": ["http://fhir.kids-first.io/StructureDefinition/Patient"]}```<jupyter_code>def validate_rs(payload, expected_success=True, create_on_success=True, print_result=False):
    resource_type = payload.get('resourceType')
    
    # Validate by POSTing to the /Patient/$validate endpoint
    endpoint = f"{client.base_url}/{resource_type}/$validate"

    # Since we know this is a valid Patient resource, it should succeed
    success, result = client.send_request('POST', endpoint, json=payload)
    if print_result:
        pprint(result)
    print(f'Validate {endpoint}, {payload.get("id")}')
    assert success == expected_success
          
    # Now actually create the Patient resource
    if create_on_success and success:
        endpoint = f"{client.base_url}/{resource_type}/{payload['id']}"
        success, result = client.send_request('PUT', endpoint, json=payload)
        print(f'PUT {endpoint}')
        assert success == expected_success  

validate_rs(patient_rs, print_result=True)<jupyter_output><empty_output><jupyter_text>Validate an Invalid Patient Resource<jupyter_code># Let's create an invalid resource and make sure it fails 
# Invalid since its missing the REQUIRED gender attribute
patient_rs_invalid = {
    "resourceType":"Patient",
    "id": "kidsfirst-test-patient",
    "text": {
        "status": "generated",
        "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>An invalid patient resource for testing purposes</p></div>"
    },
    "meta": {
        "profile": ["http://fhir.kids-first.io/StructureDefinition/Patient"]
    }
}
validate_rs(patient_rs_invalid, expected_success=False, print_result=True)<jupyter_output><empty_output><jupyter_text>Add an Attribute  ExtensionsAdding a new attribute to a `StructureDefinition` is known as adding an "extension", since you are extending the definition of the base model.To add an attribute to the `Patient` `StructureDefinition`, you must do 2 things: 1. Define an extension for the attribute by creating a `StructureDefinition` resource for it2. Declare/reference the extension in the `Patient` `StructureDefinition` 📘 Learn more about defining [extensions](https://www.hl7.org/fhir/extensibility-examples.html)  Can I Add an Attribute without an Extension?You might be wondering if it's possible to simply add an attribute to `Patient` `StructureDefinition` like this: ```jsonpatient_sd = {    ...,    "differential": {        "element": [            ...,            {                "id": "Patient.race",                "path": "Patient.race",                "min": 1,                ...             }        ]    }}```and then create a `Patient` that uses the attribute like this:```jsonpatient_rs = {    ...,    "race": "White"}```This unfortunately will not work due to the FHIR [limitations of use rules](https://www.hl7.org/fhir/profiling.htmllimitations) for Resources. One of these rules states that you cannot add new elements to the base resource. Why So Complicated? ----> ReusabilityYou might be wondering why adding a new attribute isn't as simple as removing an attribute. There are a couple of reasons for this. The primary reason is because the FHIR spec pushes for interoperability through sharing of model components like extensions.Since extensions are defined in their own files, they can be reused in a plug and play fashion by other models. We will see this later in the tutorial when we reuse the `karyotypic-sex`extension defined by the [Phenopackets FHIR model](https://aehrc.github.io/fhir-phenopackets-ig/).Unfortunately, if you don't care about making your attributes shareable and/or you only care about simple key-value type attributes, FHIR does not have a simpler way to define these right now. Simple and Complex ExtensionsAnother reason why extensions may be complex is because they can represent both simple attributes or complex attributes. A simple attribute might be a key:value pair with a primitive data type, and a complex attribute might be an entirely new structure that might have several other extensions in a nested hierarchy.⚡️ **Key Takeaway - Reuse existing extensions as much as possible! This is a major benefit of FHIR**  Create Patient Race Extension 🖐Similar to StructureDefinitions, the best way to create an extension is to start with an existing extension that is similar to the one you want to create. The best place to choose from is (📘) the official [HL7 FHIR extension registry](https://registry.fhir.org/)Let's take a look at the extension we'll be adding to the Patient model to represent the patient's race.<jupyter_code># Here's what a simple key-value extension with a string data type looks like:
patient_race_ext = {
  "resourceType" : "StructureDefinition",
  "extension" : [{
    "url" : "http://hl7.org/fhir/StructureDefinition/structuredefinition-wg",
    "valueCode" : "oo"
  },
  {
    "url" : "http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm",
    "valueInteger" : 1
  }],
  "url" : "http://fhir.kids-first.io/StructureDefinition/patient-race",
  "version" : "4.0.0",
  "name" : "patient_race",
  "status" : "draft",
  "date" : "2020-01-13",
  "publisher" : "Kids First DRC",
  "description" : "Race of patient",
  "fhirVersion" : "4.0.0",
  "kind" : "complex-type",
  "abstract" : False,
  "context" : [{
    "type" : "element",
    "expression" : "Patient"
  }],
  "type" : "Extension",
  "baseDefinition" : "http://hl7.org/fhir/StructureDefinition/Extension",
  "derivation" : "constraint",
  "differential" : {
    "element" : [{
      "id" : "Extension",
      "path" : "Extension",
      "short" : "Race",
      "definition" : "Race of patient",
      "min" : 0,
      "max" : "1",
    },
    {
      "id" : "Extension.extension",
      "path" : "Extension.extension",
      "max" : "0"
    },
    {
      "id" : "Extension.url",
      "path" : "Extension.url",
      "fixedUri" : "http://fhir.kids-first.io/StructureDefinition/patient-race"
    },
    {
      "id" : "Extension.value[x]",
      "path" : "Extension.value[x]",
      "min" : 1,
      "type" : [{
        "code" : "string"
      }]
    }]
  }
}<jupyter_output><empty_output><jupyter_text>Anatomy of ExtensionSimilar to our Patient model, an extension is just another `StructureDefinition` except with `type=Extension` instead of `type=Patient`. For all `Extension` type `StructureDefinition`s:- `type` must be set to "Extension"- `kind` must be set to "complex-type" and not "resource", since this is an extension- `baseDefinition` must be set to the URL of an existing StructureDefinition of type Extension. Additionally, you must specify in the `differential`:- the `url` or identifier of the extensionAnd for simple extensions representing a key and value with a primitive data type, you must specify in the `differential`: - the `value[x]` or data type of the extension's valueLater on in the tutorial you will learn how to change this from a string type extension to a more complex extension with a `CodeableConcept` data type.  Add Race to Patient Model So far we've just defined the new attribute we want to add to the Patient model. Now we must actually bind it or declare it in the Patient model. Here's how we do this:<jupyter_code>patient_sd = {
    "resourceType": "StructureDefinition",
    "url": "http://fhir.kids-first.io/StructureDefinition/Patient",
    "version": "0.2.0",
    "name": "kids_first_research_participant",
    "title": "Kids First Research Participant",
    "status": "draft",
    "publisher": "Kids First DRC",
    "description": "The individual human or other organism.",
    "fhirVersion": "4.0.0",
    "kind": "resource",
    "abstract": False,
    "type": "Patient",
    "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Patient",
    "derivation": "constraint",
    "differential": {
        "element": [
            {
                "id": "Patient",
                "path": "Patient"
            },
            {
                "id": "Patient.identifier",
                "path": "Patient.identifier",
                "mustSupport": True
            },
            {
                "id": "Patient.name",
                "path": "Patient.name",
                "max": "0"
            },
            {
                "id": "Patient.telecom",
                "path": "Patient.telecom",
                "max": "0"
            },
            {
                "id": "Patient.address",
                "path": "Patient.address",
                "max": "0"
            },
            {
                "id": "Patient.photo",
                "path": "Patient.photo",
                "max": "0"
            },
            {
                "id": "Patient.contact",
                "path": "Patient.contact",
                "max": "0"
            },
            {
                "id": "Patient.gender",
                "path": "Patient.gender",
                "min": 1
            },
            {
                "id": "Patient.extension",
                "path": "Patient.extension",
                "slicing": {
                    "discriminator": [
                        {
                            "type": "value",
                            "path": "url"
                        }
                    ],
                    "ordered": False,
                    "rules": "open"
                }
            },
            {
                "id": "Patient.extension:patient-race",
                "path": "Patient.extension",
                "sliceName": "patient-race",
                "short": "Race",
                "definition": "Race of patient",
                "min": 0,
                "max": "1",
                "type": [
                    {
                        "code": "Extension",
                        "profile": [
                            "http://fhir.kids-first.io/StructureDefinition/patient-race"
                        ]
                    }
                ],
                "isModifier": False
            }
        ]
    }
}<jupyter_output><empty_output><jupyter_text>Explanation of PartsLet's break down each piece. First we'll start with the piece that says we want to use extensions in the `Patient` `StructureDefinition`:```json{    "id": "Patient.extension",    "path": "Patient.extension",    "slicing": {        "discriminator": [            {                "type": "value",                "path": "url"            }        ],        "ordered": False,        "rules": "open"    }}```- `id`: This must uniquely identify the object in the `differential.element` list. It does not need to be equal to `path` but often times it is, since `path` can uniquely identify the object in the `differential.element` list.- `path`: This is equal to the fully qualified location of the attribute in the resource payload. All extensions go inside an `extension` element in the Patient resource. - `slicing`: The `Patient.extension` is a list of extensions and each one must be able to be uniquely identified in that list. The extension's URL is used to "slice" or identify the extension in the list.- `ordered=False`: order of extensions does not matter in a Patient resource- `rules=open`: additional extensions can be added in a Patient resourceThe next part is the actual binding of the race extension to the `Patient` `StructureDefinition`: ```json{    "id": "Patient.extension:patient-race",    "path": "Patient.extension",    "sliceName": "patient-race",    "short": "Race",    "definition": "Race of patient",    "min": 0,    "max": "1",    "type": [        {            "code": "Extension",            "profile": [                "http://fhir.kids-first.io/StructureDefinition/patient-race"            ]        }    ],    "isModifier": False}```The important parts to note here are: - `min/max`: this says Patient instances can only have one occurrence of the `race` extension and it is not required- `type`: this binds the Patient's race attribute to it's `StructureDefinition`  Validate Patient Model with Race Now let's validate our updated Patient model and then test it against some example Patient resources which make use of the new race extension<jupyter_code># Validate/Create the Patient race extension
validate(patient_race_ext, expected_success=True, print_result=True)

# Validate/Create the updated Patient StructureDefinition which uses Race extension
validate(patient_sd, expected_success=True, print_result=True)<jupyter_output><empty_output><jupyter_text>Create and Validate a Patient With Race<jupyter_code>patient_rs['extension'] = [
    {
        'url': 'http://fhir.kids-first.io/StructureDefinition/patient-race',
        'valueString': "Asian"
    }
]
validate_rs(patient_rs, print_result=True, expected_success=True)<jupyter_output><empty_output><jupyter_text>Search for Resources At this point we're going to take a look at how search works in FHIR so that we can start searching for our resources using the attributes we're adding to our models. Also, this will come in handy for debugging - to find and verify that we've created resources we intended to.📘 Please note that the [HAPI](http://hapi.fhir.org/) server is periodically purged and contains test data, so the search results may vary. If you have a local FHIR server, you can replace the HAPI URLs in the following examples with your local server URL. FHIR Search DSLTo search for FHIR resources on a FHIR server you need to be able to construct search queries in some sort of language the server understands and then send those queries to the server. The FHIR Search specification defines its own RESTful query language to accomplish this. This means that search queries are constructed using the URL and its query parameters of the HTTP request. Why does FHIR define another DSL for this? Because there isn't really a widely accepted standard for a RESTful query language. Operators like `and`, `or`, `>`, `>=`, etc can all be represented in different ways.  FHIR Search QueriesFHIR search queries look like this:``` FormatGET [base]/[type]?name=value&... ExampleGET http://hapi.fhir.org/baseR4/Patient?gender=female```📘 Learn more about the [FHIR Search Spec](https://www.hl7.org/fhir/search.html)<jupyter_code>def fetch(endpoint):
    success, result = client.send_request('GET', endpoint)
    pprint(result)<jupyter_output><empty_output><jupyter_text>Search result optionsThere are a few different parameters that can be used to filter or condense the search results from a query. 📘 For a full overview of search result options, refer to [this section](https://www.hl7.org/fhir/search.html_sort) of the FHIR Spec Page countingThe result of querying a FHIR server is a `Bundle`. A `Bundle` is a FHIR resource that contains a list of results that fit the search query criteria. Depending on the server, search results may be paginated, and so a `Bundle` may contain links to the next page. The `_count` parameter sets the number of results per page.<jupyter_code>fetch('http://hapi.fhir.org/baseR4/Observation?_count=5')<jupyter_output><empty_output><jupyter_text>SummaryThe `_summary` parameter returns a subset of information from the search results, such as only certain fields from each result. It can also be used to count the number of results from a query.<jupyter_code>fetch('http://hapi.fhir.org/baseR4/Observation?_summary=count')<jupyter_output><empty_output><jupyter_text>Fetch all resources typesFetching all `StructureDefinitions` will give an overview of what types of resources are in a server.<jupyter_code>fetch('http://hapi.fhir.org/baseR4/StructureDefinition?_summary=count')
fetch('http://hapi.fhir.org/baseR4/StructureDefinition')<jupyter_output><empty_output><jupyter_text>Fetch a resource's schemaThe `$snapshot` parameter will return the full schema for a resource, including any `snapshot` that a resource inherits. ``` ExampleGET [base]/StructureDefinition/[id]/$snapshot```For example, say there is a resource that inherits from `Patient` and has a `StructureDefinition` that looks like this:```json{  "resourceType": "StructureDefinition",  "id": "591026",  "name": "MyPatient",  "type": "Patient",  "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Patient",  "differential": {    "element": [ {      "id": "Patient.extension.race",      ...    } ]  }}```Then `$snapshot` will return the full schema for this resource, combining the `differential` from above with the `snapshot` from `Patient`. This is useful because the `$snapshot` parameter will look at a resource's hierarchy and inheritance, and will merge it together, so there is no need for multiple API requests. Note that if a resource and its ancestors don't have have a `snapshot` defined anywhere in a `StructureDefinition`, then the `$snapshot` endpoint will produce an error.<jupyter_code>fetch('http://hapi.fhir.org/baseR4/StructureDefinition/591026/$snapshot')<jupyter_output><empty_output><jupyter_text>Examining a specific instance of a resourceThe general format for looking at a specific instance is:`GET [base]/[type]/[id]`This will return the full payload for a resource with a specific ID.<jupyter_code>fetch('http://hapi.fhir.org/baseR4/Observation/1286681')<jupyter_output><empty_output><jupyter_text>References📘 For more information on references, refer to [this section](https://www.hl7.org/fhir/search.htmlreference) in the FHIR docsFHIR resources can reference each other. For example, an `Observation` may reference a specific `Patient`. The FHIR search API allows us to search for resources that contain a specific reference. As an example, let's fetch all `Observations` that refer to a `Patient` with an id of 1286630:<jupyter_code>fetch('http://hapi.fhir.org/baseR4/Observation?subject=Patient/1286630')<jupyter_output><empty_output><jupyter_text>Filtering resourcesEarlier, we saw that the general format for a query with search parameters is:`GET [base]/[type]?name=value&...`Here are some examples of search queries utilizing research use cases:<jupyter_code># Example - fetch all Patients that are alive
fetch('http://hapi.fhir.org/baseR4/Patient?deceased=false')
# Fetch all Conditions that were observed in female Patients
# This is an example of chaining
fetch('http://hapi.fhir.org/baseR4/Condition?patient.gender=female')
# Fetch all Patients that have multiple sclerosis
# This is an example of reverse chaining
fetch('http://hapi.fhir.org/baseR4/Patient?_has:Condition:patient:code=G35')<jupyter_output><empty_output><jupyter_text>Reverse chaining, demonstrated in the example above, requires this format:`GET [base]/[resource of interest]?_has:[type of referring resource]:[name of the search parameter containing the reference to the resource of interest]:[search parameter to filter on in referring resource]`FHIR resources can have multiple references, so it is important to include the name of the field that maps from the referring resource back to the resource of interest. In the above example of `http://hapi.fhir.org/baseR4/Patient?_has:Condition:patient:code=G35`, it is not enough to simply query `http://hapi.fhir.org/baseR4/Patient?_has:Condition:code=G35`, because this does not tell us which reference field in `Condition` contains the reference back to `Patient`.📘 For more details on chaining and reverse chaining, check out [this section](https://www.hl7.org/fhir/search.htmlchaining) of the FHIR docs. 📘Simplifier.net also has a useful article on [Advanced Search Parameters](https://simplifier.net/guide/profilingacademy/Advancedsearchparameters).  SearchParameter ResourceSo you know what search queries look like, but how do you know what attributes of a Resource or keywords you can use in search queries? All attributes? Some of them? Are keywords the same as attributes?The `SearchParameter` is a type of `Conformance Resource` which answers this question. In order to search for a Resource by a particular keyword or Resource attribute, the FHIR server must have a `SearchParameter` defined for it. Each of the FHIR Resources in the FHIR base model, have a set of predefined SearchParameters that make a subset of the Resources' attributes searchable - by either the name of the attribute or some other keyword used to alias it. Patient Built-In Search ParametersYou can always check the Resource type page on the HL7 FHIR site to see which search parameters are already supported for Resources of that type. For example here is the page for `Patient`![Patient Search Params](static/images/patient-search-params.png)  Name vs ExpressionSomething very important to note about `SearchParameter` is the differentiation between it's name and expression. Take a look at the `family` `SearchParameter`. A `Patient` resource doesn't have a first-level attribute called `family`. In fact, `family` is nested inside the `name` list: ```{    "resourceType":"Patient",    "id": "test-patient",    "gender": "male",    "name": [        {            "use": "usual",            "family":"Smith",            "given": "Jack",            "period": {                "end": "2001-01-01"            }        }    ]}```However, the expression says that when you search for Patients by `family=Smith` it will actually search for all Patients with a name element in the `name` list where `family` equals `Smith`.The search query for this would look like this:```GET http://hapi.fhir.org/baseR4/Patient?family=Smith```This is very powerful because you can:- Search for Resources using a keyword which finds instances by some abitrary attribute in the Resource payload- Turn on/off search functionality by including/excluding SearchParameters in the server- Reuse a SearchParameter by making it apply to multiple Resource Types- Share search functionality across servers by sharing the SearchParameter definition file**⚡️ Key Takeaway:** SearchParameter allows you to specify a keyword that can be used to search for Resources by some arbitrary attribute on that Resource even if it is nested  SearchParameter TypesThere is a lot of information on this topic so we cannot cover all of it. However, it is important to understand that SearchParameters have different [types](https://www.hl7.org/fhir/search.htmlptypes) which govern which modifiers can be used as a prefix/suffix to either the name or value of the search parameter in a search query. For example, for `number`, `date`, and `quantity` type SearchParameters, we can use one of the available modifiers like `gt` in a query:```GET http://hapi.fhir.org/baseR4/DiagnosticReport?date=gt2013-01-14```This query will return us all `DiagnosticReport` resources that occurred after January 14, 2013.  Make Patient Searchable by Race 🖐Ok, now let's create a SearchParameter for the `race` attribute in our Patient model. This is going to consist of 2 steps:1. Create a SearchParameter for Patient.race2. Load the SearchParameter into the server  Create Search Parameter for Patient.race<jupyter_code>patient_race_sp = {
  "resourceType": "SearchParameter",
  "url": "http://fhir.kids-first.io/SearchParameter/patient-race",
  "name": "patient-race",
  "status": "active",
  "experimental": True,
  "publisher": "Kids First DRC",
  "description": "Search for Patients by their race",
  "code": "race",
  "base": [
    "Patient"
  ],
  "type": "string",
  "expression": "Patient.extension.where(url = 'http://fhir.kids-first.io/StructureDefinition/patient-race').value",
  "target": [
    "Patient"
  ]
}<jupyter_output><empty_output><jupyter_text>Anatomy of SearchParameter Again, we won't go over everything, but let's take a look at some of the important parts of a `SearchParameter`:- `code`: this is the keyword that will be used in search queries- `name`: a computer friendly name for the search parameter- `base`: list of Resource types for which this SearchParameter applies- `target`: this seems completely redundant with `base`. Not sure why it exists, but if you don't include your searches won't work- `type`: must be one of the valid search parameter types- `expression`: the path to the attribute value in the resource payload which is being used in the search query. This is specified as a `FHIRpath` expression which is based on [xpath](https://www.w3schools.com/xml/xpath_intro.asp)📘Learn more about [FHIRpath expressions](https://www.hl7.org/fhir/fhirpath.html)  Validate Patient Race Search Parameter<jupyter_code>validate(patient_race_sp, print_result=True)<jupyter_output><empty_output><jupyter_text>Search for Patient by Race<jupyter_code>def search(resource_type, params, print_result=False):
    endpoint = f'{client.base_url}/{resource_type}'
    success, result = client.send_request('GET', endpoint, params=params)
    print(f'Searching for {result["request_url"]}, '
          f'total found: {result["response"].get("total")}')
    if print_result:
          pprint(result)      
    assert success      
search('Patient', {'race': 'Asian'}, print_result=True)<jupyter_output><empty_output><jupyter_text>Terminology in FHIR Perhaps you too feel this is a confusing topic in FHIR because you've heard various words used in association with Terminology in FHIR. You've probably heard the words/phrases: code, coding, codeable concept, Value Sets, etc and are wondering what they all are.This section will help you understand exactly what these terms mean, how they differ, and how they can be used in your FHIR model.  What is Terminology or an Ontology?Let's start with the very basics. A data model at its core is really just a collection of concepts and how they relate to each other. **An example - biological sex**A concept describes some entity in the world or an attribute of some entity in the world. For example, in our model we have a concept called Patient. Our Patient concept also has concepts which describe it - one which we don't have yet but want is biological `sex`.  Now, how does one know what the concept `sex` actually means semantically? And what kinds of values the attribute `sex` on Patient can take on? This is exactly what a terminology service or ontology defines. It also defines how concepts are related to each other (i.e. tree like, graph like, etc).**Same concept in different ontologies**A concept can be defined in multiple ontologies. For example, try the following search in your browser to see which ontologies the term `sex` is included in:```https://www.ebi.ac.uk/ols/search?q=sex&groupField=iri&start=0``` Coded ValueIn FHIR a `code` is an alphanumeric string (e.g. "433152004") used to unambiguously identify a specific concept (e.g. the concept "male", defined as a human with X and Y chromosomes) within a particular ontology (e.g. SNOMED CT).Since a concept can be defined in different ontologies, and therefore take on different values, we must always specify which ontology or system it comes from.You will hear the term **"coded value"** used in FHIR documentation. This phrase refers to a pairing of the `code` and the `system` from which it is defined. Data Types for Coded ValuesIn FHIR there are different data types that can be used to represent coded values. **code**This is the simplest one, as it is just an alphanumeric string representing the code and not the system. The system is supposed to be implied based on the context the code appears in:```json{    "code": "433152004"}```**Coding**Specifies the code, the system in which the code is defined (a valid URI), version of the system, and a human friendly string describing the concept which the code identifies. ```json{   "system" : "http://snomed.info/sct",  "version" : "1.0.0",  "code" : "433152004",  "display": "Male"}```**CodeableConcept**This data type combines things. It includes 1) a list of `Coding` instances and 2) a human friendly string describing the concept. You might use this data type when you want to define the concept in multiple ontologies for greater interoperability.```json{    "coding": [                {                   "system" : "http://snomed.info/sct",                  "version" : "1.0.0",                  "code" : "433152004",                  "display": "Male"                },                {                    "system": "http://ncimeta.nci.nih.gov",                    "code": "C1710693",                    "display": "Male"                }    ],    "text": "A human who has a chromosome composition of 46 XY"}```📘Read about [Code, Coding, CodeableConcept](https://www.hl7.org/fhir/datatypes.htmlcodesystem) data types used to represent coded values⚡️**Key Take Away** - `code`, `Coding` and `CodeableConcept` are just FHIR data types that represent a concept in the world along with a code to identify the concept in a particular ontology system where the concept is defined.  Code SystemsA Code System in FHIR essentially represents an ontology - it defines concepts and gives them meaning through formal definitions, and assign codes that represent the concepts. You can define your own Code System by [creating a CodeSystem FHIR Resource](CodeSystem-Resource) or you can make use of `CodeSystem`s or ontologies that already exist.The URI that goes in the `system` attribute of a `Coding` instance, identifies which Code System the code came from. FHIR defines a whole bunch of Code Systems that you can use. For example there are: **Externally Published Code Systems**These are popular ontologies you've probably heard of outside of the FHIR context. Here's a subset that FHIR has listed on its [Code System Registry](https://www.hl7.org/fhir/terminologies-systems.html4.3.0) page. This list tells you exactly what valid URI to use to identify the ontology as FHIR Code System.![External Published Code Systems](static/images/external-code-systems.png)**Official HL7 FHIR Code Systems**![Official HL7 FHIR Code Systems](static/images/hl7-fhir-code-systems.png)**Community FHIR Code Systems**![Community FHIR Code Systems](static/images/community-fhir-code-systems.png)  Value SetsThis is a confusing topic in FHIR, perhaps because it could have been named better. A Value Set set in FHIR is a way to select the coded values from one or more Code Systems. The Value Set is then "bound" to a particular attribute on a resource so that values of that attribute are limited to whatever the Value Set allows.For example, we might add the attribute `sex` to our `Patient` `StructureDefinition` by [creating an extension](Add-an-Attribute) for it. Then we would bind a Value Set to `sex`, which limits the values of the `sex` attribute to a set of coded values that is defined in the SNOMED CT Code System (http://snomed.info/sct).**Composable**Value Sets can select coded values from one or more Code Systems. This is very powerful because it allows you reuse and combine multiple enumerations (maybe from different projects) into one. You can do this by explicitly specifying which coded values to use within a Code System or by saying that a Value Set will be composed of other existing Value Sets.**Filterable**A Value Set can also implicitly select a subset of coded values by specifying a filter to use on the coded values within the Code System. ⚡️**Key Take Away -** A `CodeSystem` basically represents an ontology and a `ValueSet` represents a selection of concepts from one or more `CodeSystem`s or ontologies.⚡️**Key Take Away -** Similar to extensions, try not to reinvent the wheel! First try to find existing `CodeSystem`s and/or `ValueSet`s that you could use to meet your use case. If you cannot find one then create one.  Add Biological Sex as a Coded Attribute to Patient 🖐Now we're ready to start modeling. Here's what we're going to do in this section:1. Create a `CodeSystem` for Biological Sex    - We're going to define our own ontology by creating a `CodeSystem` resource2. Create a `ValueSet` for Biological Sex    - The Value Set will be simple and select all of the coded values in our `CodeSystem`3. Add an attribute to the `Patient` model for biological sex    - Create an extension for biological sex    - Add the extension to the `Patient` `StructureDefinition`4. Bind the `ValuetSet` to the Biological Sex extension in 35. Test Things - Create and search for patients with populated `sex` attributes  Create a CodeSystem for Biological Sex We're going to create our own `CodeSystem` which will define a set of codes to represent different types of chromosomal sex compositions for humans.📘Read more about the [CodeSystem](https://www.hl7.org/fhir/codesystem.html) FHIR resource type<jupyter_code># Create and validate the CodeSystem resource
patient_sex_cs = {
  "resourceType": "CodeSystem",
  "url": "http://fhir.kids-first.io/CodeSystem/biological-sex",
  "version": "0.1.0",
  "name": "BiologicalSex",
  "title": "Biological Sex",
  "status": "active",
  "experimental": False,
  "publisher": "Kids First DRC",
  "description": "Represents the chromosomal sex of an individual.",
  "caseSensitive": False,
  "valueSet": "http://fhir.kids-first.io/ValueSet/biological-sex",
  "content": "complete",
  "concept": [
    {
      "code": "UNKNOWN_KARYOTYPE",
      "display": "Untyped or inconclusive karyotyping",
      "definition": "Untyped or inconclusive karyotyping"
    },
    {
      "code": "XX",
      "display": "Female",
      "definition": "Female"
    },
    {
      "code": "XY",
      "display": "Male",
      "definition": "Male"
    },
    {
      "code": "XO",
      "display": "Single X chromosome only",
      "definition": "Single X chromosome only"
    },
    {
      "code": "XXY",
      "display": "Two X and one Y chromosome",
      "definition": "Two X and one Y chromosome"
    },
    {
      "code": "XXX",
      "display": "Three X chromosomes",
      "definition": "Three X chromosomes"
    },
    {
      "code": "XXYY",
      "display": "Two X chromosomes and two Y chromosomes",
      "definition": "Two X chromosomes and two Y chromosomes"
    },
    {
      "code": "XXXY",
      "display": "Three X chromosomes and one Y chromosome",
      "definition": "Three X chromosomes and one Y chromosome"
    },
    {
      "code": "XXXX",
      "display": "Four X chromosomes",
      "definition": "Four X chromosomes"
    },
    {
      "code": "XYY",
      "display": "One X and two Y chromosomes",
      "definition": "One X and two Y chromosomes"
    },
    {
      "code": "OTHER_KARYOTYPE",
      "display": "None of the above types",
      "definition": "None of the above types"
    }
  ]
}
validate(patient_sex_cs, print_result=True)<jupyter_output><empty_output><jupyter_text>Anatomy of CodeSystemHere are the important parts of this resource type:- `caseSensitive`: Whether or not code comparison is case sensitive when codes within this system are compared to each other.- `valueSet`: the canonical URL to the ValueSet which contains all coded values from this `CodeSystem`- `concepts`: list of concept payloads . Each payload contains the concept identifier `code`, a human friendly string `display` describing the concept, and the formal definition of the concept `definition`  Create a ValueSet for Patient Biological Sex We want the Value Set for `sex` to contain all of the coded values in our Code System. This is fairly easy, we simply make a Value Set which is composed of the coded values from our Code System:<jupyter_code>patient_sex_vs = {
    "resourceType": "ValueSet",
    "url": "http://fhir.kids-first.io/ValueSet/biological-sex",
    "version": "0.1.0",
    "name": "BiologicalSex",
    "title": "Biological Sex",
    "status": "draft",
    "experimental": False,
    "publisher": "Kids First DRC",
    "description": "Represents the chromosomal sex of an individual.",
    "compose": {
        "include": [
            {
                "system": "http://fhir.kids-first.io/CodeSystem/biological-sex"
            }
        ]
    }
}
validate(patient_sex_vs)<jupyter_output><empty_output><jupyter_text>Anatomy of ValueSetThere is a lot to know about how to compose a group of coded values using a Value Set, but we will just touch on the very basics here:- `compose`: this element must have the `include` key.- `compose.include`: has a list of payloads each of which represent the concepts to include in this Value Set. The most basic payload only lists a `CodeSystem` URI which means include all of the coded values from the system.📘 Read more about [ValueSet](https://www.hl7.org/fhir/valueset.html) and the [composition rules](https://www.hl7.org/fhir/valueset.htmlcompositions)  Create an Extension for Biological Sex Here we will create an extension for our new `sex` attribute which we will later bind to our `Patient` model (`StructureDefinition`). Notice this time, we've made the value a `CodeableConcept` which we've bound to our `ValueSet` for biological sex. We could have made the value a `Coding` but then if we later wanted to attach a different ontology to this attribute we wouldn't be able to. Remember that a `CodeableConcept` allows you to have coded values from different Code Systems.<jupyter_code># Create and validate biological sex extension
patient_sex_sd = {
    "resourceType": "StructureDefinition",
    "url": "http://fhir.kids-first.io/StructureDefinition/patient-biological-sex",
    "version": "0.1.0",
    "name": "BiologicalSex",
    "title": "Biological Sex",
    "status": "draft",
    "publisher": "Kids First DRC",
    "description": "The chromosomal sex of an individual.",
    "fhirVersion": "4.0.0",
    "kind": "complex-type",
    "abstract": False,
    "context": [
        {
            "type": "element",
            "expression": "Patient"
        }
    ],
    "type": "Extension",
    "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Extension",
    "derivation": "constraint",
    "differential": {
        "element": [
            {
                "id": "Extension",
                "path": "Extension",
                "short": "The chromosomal sex of an individual.",
                "definition": "The chromosomal sex of an individual.",
                "min": 0,
                "max": "1",
                "mustSupport": True,
                "isModifier": False
            },
            {
                "id": "Extension.extension",
                "path": "Extension.extension",
                "max": "0"
            },
            {
                "id": "Extension.url",
                "path": "Extension.url",
                "type": [
                    {
                        "code": "uri"
                    }
                ],
                "fixedUri": "http://fhir.kids-first.io/StructureDefinition/patient-biological-sex"
            },
            {
                "id": "Extension.valueCodeableConcept",
                "path": "Extension.valueCodeableConcept",
                "type": [
                    {
                        "code": "CodeableConcept"
                    }
                ],
                "binding": {
                    "extension": [
                        {
                            "url": "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName",
                            "valueString": "Biological Sex"
                        }
                    ],
                    "strength": "required",
                    "valueSet": "http://fhir.kids-first.io/ValueSet/biological-sex"
                }
            }
        ]
    }
}

validate(patient_sex_sd)

# Add biological sex extension to Patient StructureDefinition and validate
patient_sd = {
    "resourceType": "StructureDefinition",
    "url": "http://fhir.kids-first.io/StructureDefinition/Patient",
    "version": "0.1.0",
    "name": "kids_first_research_participant",
    "title": "Kids First Research Participant",
    "status": "draft",
    "publisher": "Kids First DRC",
    "description": "The individual human or other organism.",
    "fhirVersion": "4.0.0",
    "kind": "resource",
    "abstract": False,
    "type": "Patient",
    "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Patient",
    "derivation": "constraint",
    "differential": {
        "element": [
            {
                "id": "Patient",
                "path": "Patient"
            },
            {
                "id": "Patient.identifier",
                "path": "Patient.identifier",
                "mustSupport": True
            },
            {
                "id": "Patient.name",
                "path": "Patient.name",
                "max": "0"
            },
            {
                "id": "Patient.telecom",
                "path": "Patient.telecom",
                "max": "0"
            },
            {
                "id": "Patient.address",
                "path": "Patient.address",
                "max": "0"
            },
            {
                "id": "Patient.photo",
                "path": "Patient.photo",
                "max": "0"
            },
            {
                "id": "Patient.contact",
                "path": "Patient.contact",
                "max": "0"
            },
            {
                "id": "Patient.gender",
                "path": "Patient.gender",
                "mustSupport": True,
                "min": 1
            },
            {
                "id": "Patient.extension",
                "path": "Patient.extension",
                "slicing": {
                    "discriminator": [
                        {
                            "type": "value",
                            "path": "url"
                        }
                    ],
                    "ordered": False,
                    "rules": "open"
                }
            },
            {
                "id": "Patient.extension:patient-race",
                "path": "Patient.extension",
                "sliceName": "patient-race",
                "short": "Race",
                "definition": "Race of patient",
                "min": 0,
                "max": "1",
                "type": [
                    {
                        "code": "Extension",
                        "profile": [
                            "http://fhir.kids-first.io/StructureDefinition/patient-race"
                        ]
                    }
                ],
                "isModifier": False
            },
            {
                "id": "Patient.extension:biological-sex",
                "path": "Patient.extension",
                "sliceName": "biological-sex",
                "short": "Chromosomal sex of an individual.",
                "definition": "This element represents the chromosomal sex of an individual.",
                "min": 0,
                "max": "1",
                "type": [
                    {
                        "code": "Extension",
                        "profile": [
                            "http://fhir.kids-first.io/StructureDefinition/patient-biological-sex"
                        ]
                    }
                ],
                "mustSupport": True
            }
        ]
    }
}

validate(patient_sd)<jupyter_output><empty_output><jupyter_text>Test Patient with Biological Sex<jupyter_code>patient_valid = {
    "resourceType":"Patient",
    "id": "kidsfirst-test-patient",
     "text": {
        "status": "generated",
        "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>A valid patient resource for testing purposes</p></div>"
    },
    "meta": {
        "profile": ["http://fhir.kids-first.io/StructureDefinition/Patient"]
    },
    "gender": "male",
    "extension": [
        {
            "url":"http://fhir.kids-first.io/StructureDefinition/patient-biological-sex",
            "valueCodeableConcept": {
                "coding": [
                    {
                        "code": "XY",
                        "system": "http://fhir.kids-first.io/CodeSystem/biological-sex"
                    }
                ],
                "text": "Male"
            }
        }
    ]
}
validate_rs(patient_valid, print_result=True, expected_success=True)<jupyter_output><empty_output><jupyter_text>Searching for Coded Attributes Before we create a `SearchParameter` resource for our new attribute, it is worth noting a few interesting features of the FHIR search spec when it comes to searching for attributes which have coded values.  Token Type SearchParameterIf you recall from the [SearchParameter Types](SearchParameter-Types) section, a `SearchParameter` can take on different types. Each type has a set of modifiers that can be used with it which change what is being searched for (e.g. `/Patients?gender:not=male` gender is a token type parameter and is allowed to use the modifier `not`)A `token` type search parameter is different from a regular `string` because it provides a close to exact match search on a string of characters, **potentially scoped by a URI**. Additionally, for `token` search parameters, matches are case sensitive by default unless the context which it appears specifies otherwise (e.g. `CodeSystem.caseSensitive=False`) Coded Attributes Use Token TypeThe `token` search parameter type is used in search parameters for coded attributes since a coded attribute will usually take on one of the FHIR data types: `Coding` or `CodeableConcept` - both of which are scoped by the `CodeSystem` URI  How Search Works for Coded AttributesLet's say we have a `SearchParameter` defined for our `sex` extension. This extension has a FHIR data type of `CodeableConcept`. If you recall our example Patient had `sex` populated like this:**Patient.sex**```"valueCodeableConcept": {    "coding": [        {            "code": "XY",            "system": "http://fhir.kids-first.io/CodeSystem/biological-sex"        }    ],    "text": "Male"}```**Search sex=XY**When you do a search like this:```/Patient?sex=XY```**Actual Search**Since this is a `CodeableConcept` data type, the server knows to execute the search like this: ```Search all Patients and check if any Patient.sex.coding.code matches "XY" exactly``` Modifiers with Token TypeYou can change this search behavior with the modifiers that are supported for `token` type search parameters.Here are some of the modifiers that can be used with `token` type search parameters:[![Token SearchParameter Type Modifiers](static/images/token-type-modifiers.png)](https://www.hl7.org/fhir/search.htmltoken) Example Search QueriesLet's take a look at some search examples for the `Condition` resource. `Condition.code` is a `CodeableConcept` type attribute which identifies the condition, problem or diagnosis for a `Patient`**Search by code**Find Conditions where any of the Condition.code.codings.code value matches `ha125`, regardless of the ontologies/CodeSystems the code appears in.```GET [base]/Condition?code=ha125```**Search by code within a particular ontology/CodeSystem**Find Conditions where any of the Condition.code.codings.code value matches `ha125`, in the `http://acme.org/conditions/codes` CodeSystem.```GET [base]/Condition?code=http://acme.org/conditions/codes|ha125```**Search using text of CodeableConcept**Search for any Condition with a code that has the text "headache" associated with it (either in `CodeableConcept.text` or `Coding.display`), regardless of the ontology/CodeSystems.```GET [base]/Condition?code:text=headache```**Search for codes within a particular portion of the ontology/CodeSystem**Search for any condition that is subsumed by (in the hierarchy/tree of codes below) the SNOMED CT Code "Neoplasm of liver".```GET [base]/Condition?code:below=126851005``` **⚡️Key Take Away** - FHIR provides a standard way to search for codes and text within a particular ontology and across ontologies. This is very powerful!  Make Patient Searchable by Biological Sex ✋We're going to create a SearchParameter for the `sex` attribute in our Patient model. Once again, this is going to consist of 2 steps:1. Create a SearchParameter for Patient.sex2. Load the SearchParameter into the server  Create and Validate Search Parameter for Patient.sex<jupyter_code>patient_sex_sp = {
  "resourceType": "SearchParameter",
  "url": "http://fhir.kids-first.io/SearchParameter/patient-sex",
  "name": "patient-sex",
  "status": "active",
  "experimental": True,
  "publisher": "Kids First DRC",
  "description": "Search for Patients by their biological sex",
  "code": "sex",
  "base": [
    "Patient"
  ],
  "type": "string",
  "expression": "Patient.extension.where(url = 'http://fhir.kids-first.io/StructureDefinition/patient-sex').value",
  "target": [
    "Patient"
  ]
}

validate(patient_sex_sp)<jupyter_output><empty_output><jupyter_text>Search for Patient by Sex **If this returns 0 results it is likely because the HAPI FHIR server has not updated its search indices with the new SearchParameter for Patient.sex**You may need to wait a day to try again.<jupyter_code>search('Patient', {'sex': 'XY'}, print_result=True)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09483014489625212, 'fraction_numerical': 0.005585386255092955, 'mean_word_length': 3.335692559663079, 'pattern_counts': {'":': 401, '<': 121, '<?xml version=': 0, '>': 124, 'https://': 42, 'lorem ipsum': 0, 'www.': 32, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 34, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '27', 'dir': 'jupyter-structured-clean-dedup', 'id': '37405', 'license': 'Apache-2.0', 'n_tokens_mistral': 20252, 'n_tokens_neox': 18836, 'n_words': 8307, 'path': 'FHIR 101 - Practical Guide.ipynb', 'repo_name': 'Delphine-L/fhir-101', 'size': '74122'}