forked from sectra-medical/dpat_imageanalysisapi_sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
62e4c35
commit a41af36
Showing
23 changed files
with
1,151 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
skips: | ||
- B311 | ||
- B113 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# These are some examples of commonly ignored file patterns. | ||
# You should customize this list as applicable to your project. | ||
# Learn more about .gitignore: | ||
# https://www.atlassian.com/git/tutorials/saving-changes/gitignore | ||
|
||
# Node artifact files | ||
node_modules/ | ||
dist/ | ||
|
||
# Compiled Java class files | ||
*.class | ||
|
||
# Compiled Python bytecode | ||
*.py[cod] | ||
|
||
# Log files | ||
*.log | ||
|
||
# Package files | ||
*.jar | ||
|
||
# Maven | ||
target/ | ||
dist/ | ||
|
||
# JetBrains IDE | ||
.idea/ | ||
|
||
# Unit test reports | ||
TEST*.xml | ||
|
||
# Generated by MacOS | ||
.DS_Store | ||
|
||
# Generated by Windows | ||
Thumbs.db | ||
|
||
# Applications | ||
*.app | ||
*.exe | ||
*.war | ||
|
||
# Large media files | ||
*.mp4 | ||
*.tiff | ||
*.avi | ||
*.flv | ||
*.mov | ||
*.wmv | ||
|
||
**/*.egg-info | ||
**/*build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
SHELL=bash | ||
|
||
.PHONY: format | ||
format: | ||
isort .; | ||
black . | ||
|
||
.PHONY: lint | ||
lint: | ||
flake8 ids7client/ | ||
bandit -c .bandit.yml -r ids7client/ | ||
isort --check ids7client/ | ||
black ids7client/ --check --diff | ||
mypy ids7client/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
# Python Client for Sectra IDS7 PACS | ||
|
||
## Introduction | ||
|
||
This python package aims to facilite the development of AI applications integrated in Sectra IDS7 PACS. | ||
|
||
Please note that for now, not every feature is implemented but the package can easily be enriched: | ||
|
||
* some endpoints are missing (e.g., slide downloading) | ||
* QIDO client is pretty basic | ||
|
||
### What it implements | ||
|
||
* A client for the IDS7 AI API (`IDS7AIClient`) | ||
* A client for the IDS7 QIDO API (`IDS7QidoClient`) | ||
* A set of pydantic models to encapsulate and validate data sent and received from IDS7 | ||
|
||
|
||
### What it does not implement, but might, at some point | ||
|
||
* A server to receive analysis requests from IDS7 | ||
|
||
## Installation | ||
|
||
To install ids7client (until it is published in pypi): | ||
|
||
```pip install .``` | ||
|
||
To install ids7client with development dependencies (linting and formating, see below): | ||
|
||
```pip install ./[dev]``` | ||
|
||
## Usage | ||
|
||
Before using the client, make sure you have access to a valid authentication token, sent in the analysis requests. | ||
|
||
### Example 1: Retrieve image information | ||
|
||
```python | ||
from ids7client.ai import IDS7AIClient | ||
|
||
# Callback info, sent by IDS7 in the request | ||
callback_url = "https://sectrapacs.com" | ||
callback_token = "abc" | ||
|
||
# Slide id, sent by IDS7 in the request | ||
slide_id = "blabla" | ||
|
||
client = IDS7AIClient( | ||
url=callback_url, | ||
token=callback_token | ||
) | ||
|
||
# Returns the image info with extended and personal health information data | ||
image_info = client.get_image_info(slide_id, extended=True, phi=True) | ||
``` | ||
|
||
### Example 2: Returning basic results | ||
|
||
The following code creates a result payload that can be sent as response to display a frame on the whole slide and a label telling the user that the analysis is pending. | ||
|
||
```python | ||
from ids7client.ai import ( | ||
ResultContent, | ||
ResultType, | ||
PrimitiveItem, | ||
Style, | ||
Polygon, | ||
Point, | ||
Label, | ||
Result | ||
) | ||
|
||
# Slide id, sent by IDS7 in the request | ||
slide_id = "blabla" | ||
|
||
data = ResultContent( | ||
type=ResultType.PRIMITIVES, | ||
content=[ | ||
PrimitiveItem( | ||
style=Style( | ||
strokeStyle="#000000", | ||
), | ||
polygons=[ | ||
Polygon( | ||
points=[ | ||
Point(x=0.0, y=0.0), | ||
Point(x=1.0, y=0.0), | ||
Point(x=1.0, y=1.0), | ||
Point(x=0.0, y=1.0), | ||
] | ||
) | ||
], | ||
labels=[ | ||
Label( | ||
location=Point(x=0.00, y=0.0), | ||
label="Analysis running", | ||
) | ||
], | ||
) | ||
], | ||
) | ||
|
||
result = Result( | ||
slideId=slide_id, | ||
displayResult="Analysis running", | ||
applicationVersion="1.0.0", | ||
data=data | ||
) | ||
``` | ||
|
||
### Example 3: Retrieving patient, request and exam id | ||
|
||
```python | ||
from IDS7Client.ai import IDS7AIClient | ||
from IDS7Client.qido import IDS7QidoClient, DicomCodes | ||
|
||
# Callback info, sent by IDS7 in the request | ||
callback_url = "https://sectrapacs.com" | ||
callback_token = "abc" | ||
|
||
# Slide id, sent by IDS7 in the request | ||
slide_id = "blabla" | ||
|
||
ai_client = IDS7AIClient( | ||
url=callback_url, | ||
token=callback_token | ||
) | ||
|
||
# Returns the image info with extended and personal health information data | ||
image_info = client.get_image_info(slide_id, extended=True, phi=True) | ||
|
||
# Instanciates QIDO client with provided url, username and password | ||
qido_client = IDS7QidoClient(qido_url, qido_username, qido_password) | ||
|
||
# Retrieve study from QIDO API | ||
study = qido_client.find_one_study(studyInstanceUid=data.study_id) | ||
|
||
# Retrieve patient, request and exam id from the response | ||
patient_id = study.get_value_as_string(DicomCodes.PATIENT_ID) | ||
request_id = study.get_value_as_string(DicomCodes.REQUEST_ID) | ||
exam_id = study.get_value_as_string(DicomCodes.EXAM_ID) | ||
``` | ||
|
||
### Error handling and retries | ||
|
||
Any request to the IDS7 server is retried 5 times with exponential delays if there is a connection error. Any other error is not handled by the clients. | ||
|
||
Clients raise `IDS7RequestError` if the IDS7 server returns an error status code (e.g., 400, 404, 500, etc.). The error includes the returned status code, text and the requested path. | ||
|
||
## Code quality | ||
|
||
Code quality is ensured with the following tools: | ||
|
||
* flake8 for formating | ||
* mypy for static typing analysis | ||
* bandit for security | ||
* black for formating | ||
* isort for imports order | ||
|
||
One can format the code using the following command: | ||
|
||
```make format``` | ||
|
||
One can lint the code using the following command: | ||
|
||
```make lint``` | ||
|
||
|
||
## What's next? | ||
|
||
* HL7 API client | ||
* More detailed data validation (e.g., min and max lengths of arrays) | ||
* Missing IDS7 endpoints |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
bandit | ||
black | ||
flake8 | ||
isort | ||
mypy | ||
types-requests | ||
types-setuptools |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from .errors import IDS7RequestError |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from .client import IDS7AIClient | ||
from .schemas import ( | ||
Action, | ||
ApplicationInfo, | ||
Attachment, | ||
AttachmentState, | ||
CallbackInfo, | ||
Context, | ||
CreateInput, | ||
DisplayedName, | ||
DisplayProperties, | ||
FocalPlane, | ||
ImageInfo, | ||
ImageNotification, | ||
InputTemplate, | ||
InputType, | ||
Invocation, | ||
Label, | ||
MultiAreaContent, | ||
OpticalPath, | ||
Patch, | ||
PatchContent, | ||
Point, | ||
Polygon, | ||
Polyline, | ||
PrimitiveItem, | ||
Registration, | ||
Result, | ||
ResultContent, | ||
ResultData, | ||
ResultResponse, | ||
ResultType, | ||
Size, | ||
SlideFormat, | ||
Specimen, | ||
Status, | ||
Style, | ||
TaggedPolygonContent, | ||
TaggedPolygonInputContent, | ||
TileFormat, | ||
) |
Oops, something went wrong.