forked from sRassmann/deeplasia-service
-
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.
* Implement basic flask app * Update docker and adopt waitress for serving * Add docs for API usage * Add devcontainer configuration * Add OpenAPI specification * Add error responses to api specification * Serve api spec file * Reduce image size by 1GB and improve build time * Update name of x-ray image property * Add dependabot * Add docker build workflow * Update README.md * Add html file to display OpenAPI spec --------- Co-authored-by: Sebastian Rassmann <[email protected]>
- Loading branch information
1 parent
3e74b19
commit cce5886
Showing
32 changed files
with
779 additions
and
1,610 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,21 @@ | ||
{ | ||
"name": "Python 3.9", | ||
"image": "mcr.microsoft.com/devcontainers/python:3.9", | ||
"runArgs": [ | ||
// "--gpus", | ||
// "all", | ||
"--env-file", | ||
".devcontainer/.env" | ||
], | ||
"postCreateCommand": "pip install -r requirements.txt", | ||
"customizations": { | ||
"vscode": { | ||
"extensions": [ | ||
"ms-python.python", | ||
"ms-azuretools.vscode-docker", | ||
"mhutchie.git-graph", | ||
"42Crunch.vscode-openapi" | ||
] | ||
} | ||
} | ||
} |
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,2 @@ | ||
.devcontainer | ||
models |
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 @@ | ||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates | ||
version: 2 | ||
updates: | ||
- package-ecosystem: "github-actions" | ||
directory: "/" | ||
schedule: | ||
interval: "weekly" |
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,38 @@ | ||
name: Build Docker Image | ||
|
||
on: | ||
workflow_dispatch: | ||
release: | ||
types: [created] | ||
|
||
jobs: | ||
build-and-publish-docker-image: | ||
name: Build Docker image and publish to GitHub Container Registry | ||
runs-on: ubuntu-latest | ||
env: | ||
REGISTRY: ghcr.io | ||
IMAGE_NAME: ${{ github.repository }} | ||
permissions: | ||
contents: read | ||
packages: write | ||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
- name: Log into registry ${{ env.REGISTRY }} | ||
uses: docker/login-action@v3 | ||
with: | ||
registry: ${{ env.REGISTRY }} | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
- name: Extract Docker metadata | ||
id: meta | ||
uses: docker/metadata-action@v5 | ||
with: | ||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | ||
- name: Build and push Docker image | ||
uses: docker/build-push-action@v5 | ||
with: | ||
context: . | ||
push: true | ||
tags: ${{ steps.meta.outputs.tags }} | ||
labels: ${{ steps.meta.outputs.labels }} |
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 |
---|---|---|
|
@@ -81,3 +81,5 @@ modesl/* | |
|
||
/imgs/* | ||
/models/* | ||
|
||
*.env |
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 |
---|---|---|
@@ -1,18 +1,17 @@ | ||
FROM python:3.9 | ||
FROM python:3.9-slim | ||
|
||
COPY . /app | ||
ENV DEEPLASIA_THREADS=4 | ||
|
||
WORKDIR /app | ||
# If your company uses a self-signed CA: | ||
# ENV PIP_TRUSTED_HOST=download.pytorch.org | ||
|
||
RUN ["apt-get", "update"] | ||
RUN ["apt-get", "-y", "install", "vim"] | ||
WORKDIR /app | ||
|
||
#Install necessary packages from requirements.txt with no cache dir allowing for installation on machine with very little memory on board | ||
COPY requirements.txt /app/. | ||
RUN pip install -r requirements.txt | ||
|
||
#Exposing the default streamlit port | ||
COPY . /app | ||
|
||
EXPOSE 8080 | ||
|
||
#Running the streamlit app | ||
ENTRYPOINT ["streamlit", "run", "--server.maxUploadSize=20", "--server.port=8080"] | ||
CMD ["main.py"] | ||
CMD [ "waitress-serve", "app:app"] |
File renamed without changes.
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,121 @@ | ||
# Deeplasia Service | ||
|
||
Deeplasia is a prior-free deep learning approach to asses bone age in children and adolescents. | ||
This repository contains a RESTfull service with a simple API to process X-ray images and predict bone age in months. | ||
|
||
Please refer for more information: | ||
|
||
* http://www.deeplasia.de/ | ||
* https://github.com/aimi-bonn/Deeplasia | ||
|
||
[![Build Docker Image](https://github.com/CrescNet/deeplasia-service/actions/workflows/build.yml/badge.svg)](https://github.com/CrescNet/deeplasia-service/actions/workflows/build.yml) | ||
|
||
## How to Use | ||
|
||
In order to run this application, you must provide the deep learning models. Please contact use to get them. | ||
|
||
Use the environment variable `DEEPLASIA_THREADS` to limit the number of threads used by [PyTorch](https://pytorch.org/) (defaults to 4 threads). | ||
|
||
### Run in Conda Environment | ||
|
||
**Requirements:** | ||
|
||
* [Conda](https://docs.conda.io) must be installed | ||
* Deep learning models are located in the directory `./models` | ||
|
||
Run the following CLI commands and navigate to <http://localhost:5000/>. | ||
|
||
```sh | ||
conda create -n flask_ba python=3.9 | ||
conda activate flask_ba | ||
pip install -r requirements.txt | ||
python flask run | ||
``` | ||
|
||
### Run with Docker | ||
|
||
**Requirements:** | ||
|
||
* [Docker](https://docs.docker.com/engine/install/) must be installed | ||
* Deep learning models are not included in the image and must be mounted on container start | ||
|
||
You can use our pre built Docker image to run the application: | ||
|
||
```sh | ||
docker run -p 8080:8080 -v ./models:/app/models ghcr.io/CrescNet/deeplasia-service | ||
``` | ||
|
||
Or you can build the image yourself (clone this repository first): | ||
|
||
```bash | ||
docker build -t deeplasia-service . | ||
docker run -p 8080:8080 -v ./models:/app/models deeplasia-service | ||
``` | ||
|
||
Navigate to <http://localhost:8080/> | ||
|
||
#### Limiting CPU usage | ||
|
||
To [limit the CPU usage of the docker container](https://docs.docker.com/config/containers/resource_constraints/), add the following flags to the docker run cmd: | ||
|
||
```sh | ||
--cpus=<number_of_cpus> | ||
``` | ||
|
||
Note, that this should match the number of threads specified with environment variable `DEEPLASIA_THREADS`. | ||
|
||
e.g.: | ||
|
||
```sh | ||
docker run -p 8080:8080 --cpus=2 -e "DEEPLASIA_THREADS=2" -v ./models:/app/models ghcr.io/CrescNet/deeplasia-service | ||
``` | ||
|
||
## API | ||
|
||
Please refer to `deeplasia-api.yml` for an [OpenAPI](https://www.openapis.org/) specification of the API. | ||
|
||
### Request | ||
|
||
In python the request can be conducted as follows: | ||
|
||
```python | ||
import requests | ||
|
||
url = "http://localhost:8080/predict" | ||
|
||
test_img = "/path/to/xray.png" | ||
files = { "file": open(test_img, "rb") } | ||
|
||
data = { | ||
"sex": "female", # specify if known, else is predicted | ||
"use_mask": True # default is true | ||
} | ||
|
||
resp = requests.post(url, files=files, json=data) | ||
resp.json() | ||
``` | ||
|
||
Gives something like: | ||
|
||
```json | ||
{ | ||
"bone_age": 164.9562530517578, | ||
"sex_predicted": false, | ||
"used_sex": "female" | ||
} | ||
``` | ||
|
||
## Predicting Sex | ||
|
||
The canonical way would be as described in previous sections, with using the predicted mask and specifying the sex. | ||
If, however, the sex happens to be unknown (or unsure for e.g. errors of inserting the data) the sex can also be predicted. | ||
|
||
## Usage of Masks | ||
|
||
Skipping the masking by the predicted mask is meant to be a debugging feature, if the results with the mask are not convincing | ||
(e.g. predicting 127 months as age), one could re-conduct bone age prediction without the mask and see if makes a difference. | ||
We might think about storing the masks as a visual control as well as logging features in general in the future. | ||
|
||
## License | ||
|
||
The code in this repository and the image `deeplasia-service` are licensed under CC BY-NC-SA 4.0 DEED. |
Oops, something went wrong.