MOPCON 2022

FHIR, Vaccine QRCode Passport and Python

Peter

2022/10/15

Slide

Outlines

  • 我是誰?

  • FHIR是什麼?它可以拿來做什麼?

  • 我所知道的FHIR資料格式在台灣發展的現況介紹

  • FHIR相關閱讀與參考資源介紹

  • FHIR Client for Python

  • 數位疫苗護照應用的設計

  • 聯測松是什麼?

  • 參與聯測之預測的心得

  • 分享當天聯測松情況、參與的心得、訣竅與所見所聞

  • 結論 & Q&A

我是誰?

  • Peter, GitHub

  • 在GitHub活躍的開源專案貢獻者

  • Speaker

    • COSCUP、MOPCON......

  • Associate Engineer

    • DevOps

    • Back-end

    • System Architecture Researching

    • Web Application Security

    • PHP, Python and JavaScript

  • Industrial Technology Research Institute

    • Smart Grid Technology (2017~2021)

  • Institute for Information Industry

    • Database, Data platform architecture (2021~)

FHIR是什麼?它可以拿來做什麼?

  • 快捷式醫療服務互操作資源

    • 採用了現代的HTTP API技術

    • 使用者介面使用集成的HTML和CSS

    • 資料格式可選擇用於JSON或XML

Without FHIR

Without FHIR

  • 缺乏統一規範

  • 永遠做不完的重工

  • 難以支援行動裝置

  • 未來發展性不足

With FHIR

With FHIR

  • 支援資料標準格式一致

  • 與現代網頁技術標準一致

在解決資料交換標準後...

  • 你的FHIR不是我的FHIR

    • 大家都參考FHIR資料格式標準但是實做上仍有差異

FHIR標準在台灣的發展

台灣醫療影像標準協會

解決你的FHIR不是我的FHIR問題

FHIR標準在台灣的發展

台灣醫療影像標準協會

  • HL7 FHIR®

  • DICOMweb™

  • ISO/IEEE 11073等

  • 採用規範標準化資訊互通介面

  • 進行跨系統資訊互通聯測松 ( Connectathon )

  • 發展及推行支援標準化之系統

    • 以利於系統之整合應用、系統複製、擴散與商品化應用

MI-TW ( Medical Informatics ) 聯測基於國際醫學資訊標準

FHIR標準閱讀參考文獻

  • https://www.hl7.org/fhir

    • https://www.hl7.org/fhir/bundle-response.json.html

  • https://mitw.dicom.org.tw/preconnectathon.html

  • https://mitw.dicom.org.tw/training.html

Python FHIR Client

https://github.com/peter279k/fhir-client

Python FHIR Client

https://github.com/peter279k/fhir-client

Python FHIR Client

https://github.com/peter279k/fhir-client

Python FHIR Client

Python 3.7+建置(Ubuntu 18.04)

root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.6 LTS
Release:        18.04
Codename:       bionic
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~# add-apt-repository ppa:deadsnakes/ppa -y
Get:1 http://mirrors.digitalocean.com/ubuntu bionic InRelease [242 kB]
......
Fetched 7171 kB in 2s (3669 kB/s)
Reading package lists... Done
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~# apt-get install python3.7
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  libpython3.7-minimal libpython3.7-stdlib python3.7-minimal
Suggested packages:
  python3.7-venv binfmt-support
......
Do you want to continue? [Y/n] Y
......
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~#

Python FHIR Client

Python 3.7+建置(Ubuntu 18.04)

root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~# python3.7 --version
Python 3.7.14
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~# python3.7 -m pip install --user --upgrade pip
Cache entry deserialization failed, entry ignored
Collecting pip
......
Installing collected packages: pip
Successfully installed pip-22.2.2
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~# python3.7 -m pip install --user pipenv
Collecting pipenv
  Downloading pipenv-2022.10.10-py2.py3-none-any.whl (3.3 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.3/3.3 MB 59.3 MB/s eta 0:00:00
.......
Collecting virtualenv
......
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~# echo 'alias pipenv="python3.7 -m pipenv"' \
>  >> ~/.bashrc
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~# source ~/.bashrc
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~# pipenv --version
pipenv, version 2022.10.10
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~#

Python FHIR Client

Python 3.7+建置(Ubuntu 18.04)

root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~/fhir-client# rm /usr/bin/python3
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~/fhir-client# ln -s /usr/bin/python3.7 /usr/bin/python3
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~/fhir-client# python3 --version
Python 3.7.14
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~# git clone https://github.com/peter279k/fhir-client
Cloning into 'fhir-client'...
remote: Enumerating objects: 114, done.
remote: Counting objects: 100% (114/114), done.
remote: Compressing objects: 100% (60/60), done.
remote: Total 114 (delta 52), reused 110 (delta 50), pack-reused 0
Receiving objects: 100% (114/114), 20.97 KiB | 6.99 MiB/s, done.
Resolving deltas: 100% (52/52), done.
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~# cd fhir-client
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~/fhir-client# pipenv install
Pipfile.lock not found, creating...
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✔ Success!
Locking [dev-packages] dependencies...
Building requirements...
Resolving dependencies...
✔ Success!
......
root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~/fhir-client#

Python FHIR Client

Python 3.7+建置(Ubuntu 20.04)

root@mopcon2022-demo:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.5 LTS
Release:        20.04
Codename:       focal
root@mopcon2022-demo:~# python3 --version
Python 3.8.10
root@mopcon2022-demo:~# apt-get install python3-pip
root@mopcon2022-demo:~# pip3 --version
pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)
root@mopcon2022-demo:~#
root@mopcon2022-demo:~# useradd -m --shell /bin/bash peter
root@mopcon2022-demo:~# passwd peter
New password:
Retype new password:
passwd: password updated successfully
root@mopcon2022-demo:~#
root@mopcon2022-demo:~# gpasswd -a peter sudo
Adding user peter to group sudo
root@mopcon2022-demo:~# su - peter
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

peter@mopcon2022-demo:~$
peter@mopcon2022-demo:~$ pip3 install -U pipenv

Python FHIR Client

Python 3.7+建置(Ubuntu 20.04)

peter@mopcon2022-demo:~$ git clone https://github.com/peter279k/fhir-client
Cloning into 'fhir-client'...
remote: Enumerating objects: 114, done.
remote: Counting objects: 100% (114/114), done.
remote: Compressing objects: 100% (60/60), done.
remote: Total 114 (delta 52), reused 110 (delta 50), pack-reused 0
Receiving objects: 100% (114/114), 20.97 KiB | 6.99 MiB/s, done.
Resolving deltas: 100% (52/52), done.
peter@mopcon2022-demo:~/fhir-client$ echo 'alias pipenv="python3 -m pipenv"' \
>  >> ~/.bashrc
peter@mopcon2022-demo:~/fhir-client$ source ~/.bashrc
peter@mopcon2022-demo:~/fhir-client$ pipenv --version
pipenv, version 2022.10.11
peter@mopcon2022-demo:~/fhir-client$ pipenv install
......
nstalling dependencies from Pipfile.lock (b6f97a)...
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

Python FHIR Client

跟Patient病人有關操作的Python檔案

peter@mopcon2022-demo:~/fhir-client$ cd API-Examples/
peter@mopcon2022-demo:~/fhir-client/API-Examples$
peter@mopcon2022-demo:~/fhir-client/API-Examples$ ls
Bundle  Composition  Immunization  Observation  Organization  Patient  Practitioner
peter@mopcon2022-demo:~/fhir-client/API-Examples$
peter@mopcon2022-demo:~/fhir-client/API-Examples$ ls Patient/
create_patient.py  get_patient_info_by_id.py      get_patient_lists.py
delete_patient.py  get_patient_info_by_search.py  update_patient.py
peter@mopcon2022-demo:~/fhir-client/API-Examples$

Python FHIR Client

create_patient.py(新增病人)

import json
import requests


headers = {
    'Accept': 'application/fhir+json',
    'Content-Type': 'application/fhir+json',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36',
}
fhir_server_url = 'https://fhir.dicom.tw/fhir/Patient'
#fhir_server_url = 'https://hapi.fhir.tw//fhir/Patient'

# define example payload

response = requests.post(fhir_server_url, headers=headers, data=json.dumps(example_payload))

print(json.loads(response.text))

Python FHIR Client

create_patient.py(新增病人)example_payload

example_payload = {
    'resourceType': 'Patient',
    'identifier': [
        {
            'system': 'https://www.dicom.org.tw/cs/identityCardNumber_tw',
            'value': 'M123456789',
        },
    ],
    'name': [
        {
            'text': '李小明',
            'family': '李',
            'given': ['小明'],
        },
        {
            'text': 'Sha-Ming Li',
            'family': 'Li',
            'given': ['Sha-Ming'],
        },
    ],
    'gender': 'male',
    'birthDate': '1993-06-30',

Python FHIR Client

create_patient.py(新增病人)example_payload

    'address': [
        {
            'use': 'home',
            'text': '105台北市松山區民生東路四段133號',
        },
        {
            'country': 'TW',
        },
    ],
    'telecom': [
        {
            'use': 'home',
            'system': 'phone',
            'value': '0910123456',
        }
    ],
}

Python FHIR Client

Running create_patient.py(新增病人)response

pipenv run python3 create_patient.py

Python FHIR Client

Running get_patient_info_by_id.py(利用id查詢病人)

pipenv run python3 get_patient_info_by_id.py

import json
import requests


headers = {
    'Accept': 'application/fhir+json',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36',
}
fhir_server_url = 'https://fhir.dicom.tw/fhir/Patient/71008'
#fhir_server_url = 'https://hapi.fhir.tw/fhir/Patient/49953'

response = requests.get(fhir_server_url, headers=headers)

print(json.loads(response.text))

Python FHIR Client

Running get_patient_info_by_id.py(利用id查詢病人)

pipenv run python3 get_patient_info_by_search.py

import json
import requests


headers = {
    'Accept': 'application/fhir+json',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36',
}
search_parameters = '?family=李&identifier=M123456789'
fhir_server_url = 'https://fhir.dicom.tw/fhir/Patient' + search_parameters
#fhir_server_url = 'https://hapi.fhir.tw/fhir/Patient' + search_parameters

response = requests.get(fhir_server_url, headers=headers)

print(json.loads(response.text))

數位疫苗護照應用的設計

故事是這樣的

PM

組長

數位疫苗護照應用的設計

故事是這樣的

  • PM:我們承接了聯測松計畫執行,也要有人參加響應?

  • 組長:我們來做一個數位疫苗護照應用參加聯測吧!

  • 組長:你去參加吧!
     

  • 所以我就開始開發數位疫苗護照了

數位疫苗護照應用的設計

情境上的設計(使用者端)

數位疫苗護照應用的設計

情境上的設計(店家端)

數位疫苗護照應用的設計

選用的技術

  • 前端

    • Bootstrap + React.js

  • 後端

    • ​Python

    • FastAPI

數位疫苗護照應用的設計

解決疫苗Immunization Bundle問題

數位疫苗護照應用Demo環境建置

git clone https://github.com/peter279k/hospital-system-server

peter@mopcon2022-demo:~$ cd hospital-system-server/
peter@mopcon2022-demo:~/hospital-system-server$ pipenv install
......
Installing dependencies from Pipfile.lock (98f5ea)...
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

pipenv run uvicorn main:app --host 0.0.0.0

INFO:     Will watch for changes in these directories: ['/root/hospital-system-server']
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [10880] using StatReload
INFO:     Started server process [10884]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

後端系統建置

數位疫苗護照應用Demo環境建置

數位疫苗護照應用Demo環境建置

讓後端系統跑在背景

peter@mopcon2022-demo:~/hospital-system-server$ cp hospital-system-server.service.example \
>  hospital-system-server.service
peter@mopcon2022-demo:~/hospital-system-server$ cat hospital-system-server.service

數位疫苗護照應用Demo環境建置

讓後端系統跑在背景

peter@mopcon2022-demo:~/hospital-system-server$ sudo cp hospital-system-server.service \
> /etc/systemd/system/
[sudo] password for peter:
peter@mopcon2022-demo:~/hospital-system-server$ sudo systemctl daemon-reload
peter@mopcon2022-demo:~/hospital-system-server$

數位疫苗護照應用Demo環境建置

前端系統建置

Install the nvm

peter@mopcon2022-demo:~$ source ~/.bashrc
peter@mopcon2022-demo:~$ nvm list
            N/A
iojs -> N/A (default)
node -> stable (-> N/A) (default)
unstable -> N/A (default)
peter@mopcon2022-demo:~$ nvm install --lts
Installing latest LTS version.
Downloading and installing node v16.17.1...
Downloading https://nodejs.org/dist/v16.17.1/node-v16.17.1-linux-x64.tar.xz...
......
Now using node v16.17.1 (npm v8.15.0)
Creating default alias: default -> lts/* (-> v16.17.1)
peter@mopcon2022-demo:~$ node --version
v16.17.1
peter@mopcon2022-demo:~$ npm --version
8.15.0
peter@mopcon2022-demo:~$

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash

數位疫苗護照應用Demo環境建置

前端系統建置

peter@mopcon2022-demo:~$ cd vaccine-qrcode-passport/
peter@mopcon2022-demo:~/vaccine-qrcode-passport$ npm install
.......
Run `npm audit` for details.
peter@mopcon2022-demo:~/vaccine-qrcode-passport$ cp .env.example .env
peter@mopcon2022-demo:~/vaccine-qrcode-passport$ cat .env
REACT_APP_IP_ADDRESS=
REACT_APP_API_ADDRESS=http://127.0.0.1:8000
REACT_APP_ENV=development
REACT_APP_FHIR_SERVER=no
REACT_APP_FHIR_SERVER_TOKEN=no

git clone https://github.com/peter279k/vaccine-qrcode-passport

數位疫苗護照應用Demo環境建置

前端系統建置(運行開發/聯測模式)

root@ubuntu-s-1vcpu-1gb-amd-sgp1-01:~/vaccine-qrcode-passport# npm run start
Compiled successfully!

You can now view vaccine-qrcode-passport in the browser.

  http://localhost:3000

Note that the development build is not optimized.
To create a production build, use npm run build.

數位疫苗護照應用Demo環境建置

前端系統建置(設定FHIR Server Endpoint)

數位疫苗護照應用Demo環境建置

前端系統建置(設定FHIR Server Endpoint)

數位疫苗護照應用Demo環境建置

前端系統查詢病患

參加聯測松?聯測松是什麼?

數位疫苗護照應用設計跟開發好後就可以參加聯測了

是要讓醫院、醫資廠商的系統,用符合HL7組織制定的國際醫療資料標準來互通資料,打破資料溝通障礙,改善未來國內外醫療資料的互通性。

聯測松有多個賽道,該選擇哪幾個?

選擇與產品有關符合的賽道

搞懂要聯測的產品是Consumer還是Producer

聯測松時程

  • 各種資料格式標準研討

  • 募集廠商

  • 舉辦聯測工作坊(沒參加)

  • 廠商報名聯測活動(組長統一報名)

  • 聯測與賽道線上說明(沒參加看影片記錄)

  • 用藥疫苗線上討論(跟我聯測有關有參加)

  • 預測活動(有參加)

  • 聯測活動當天(共三天)(有參加)

2022聯測松時程

聯測松–預測活動

  • 教你如何操作與設定Gazelle系統

  • 熟悉賽道的測項流程進行方式

聯測松–聯測設定

  • 在產品上開發設定聯測可以用的功能

聯測松–聯測設定

  • 在產品上開發設定聯測可以用的功能

聯測松–聯測與產品情境設計

聯測松–當天聯測活動

聯測松–當天聯測活動&心得

  • 總共3天

  • 類黑客松

  • 隔壁不太會程式技術的會問你問題

  • 改程式→送測項驗證→改程式...

  • 前端UI記得要有Debug模式

    • React Syntax Highlighter顯示回應與請求的JSON payload

    • 聯測有些測項會需要這個截圖

  • 會用cURL或是Postman會很有幫助

  • 與督察員「討論」測項不通過的原因

  • 一天比一天還要少人

  • 接完大會的FHIR server可以去接別人的

當天聯測活動(Gazelle聊天室)

當天聯測活動(Gazelle聊天室)​

聯測松結果

聯測松結果

參考資料

  • 相關報導

    • https://www.ithome.com.tw/news/147594

  • Gazelle

    • https://gazelle.dicom.tw

  • FHIR Server

    • https://fhir.dicom.tw

    • https://hapi.fhir.tw

    • https://github.com/hapifhir/hapi-fhir

  • VaccineQRCode Passport專案

    • https://github.com/peter279k/fhir-client

    • https://github.com/peter279k/vaccine-qrcode-passport

    • https://github.com/peter279k/hospital-system-server

  • Immunization Bundle資料格式定義回答

    • https://hackmd.io/UaQ4o8hMSdqE0D9_FsAk1A

Demo

Any Questions?

MOPCON 2022

By peter279k

MOPCON 2022

MOPCON 2022

  • 719