Skip to content

Commit

Permalink
Merge pull request #7 from minrk/lint
Browse files Browse the repository at this point in the history
add and run linter config via pre-commit
  • Loading branch information
minrk authored Sep 20, 2024
2 parents bfc44a4 + c88c6b5 commit 0a698d0
Show file tree
Hide file tree
Showing 14 changed files with 195 additions and 90 deletions.
60 changes: 29 additions & 31 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: JupyterHealth SMART on FHIR test suite

on:
push:
branches: [ main ]
branches: [main]
pull_request:

jobs:
Expand All @@ -13,33 +13,31 @@ jobs:
python-version: [3.12] # extend if needed

steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '18.x'
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .[testing]
- name: Install SMART sandbox
run: |
git clone https://github.com/smart-on-fhir/smart-launcher-v2.git
cd smart-launcher-v2
git switch -c aa0f3b1 # Fix the version we use for the sandbox
npm ci
npm run build
env:
PORT: 5555
- name: Run tests
run: |
pytest tests/
env:
SANDBOX_DIR: ${{ github.workspace }}/smart-launcher-v2


- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: "18.x"
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .[testing]
- name: Install SMART sandbox
run: |
git clone https://github.com/smart-on-fhir/smart-launcher-v2.git
cd smart-launcher-v2
git switch -c aa0f3b1 # Fix the version we use for the sandbox
npm ci
npm run build
env:
PORT: 5555
- name: Run tests
run: |
pytest tests/
env:
SANDBOX_DIR: ${{ github.workspace }}/smart-launcher-v2
34 changes: 32 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
jupyterhub-proxy.pid
jupyterhub_cookie_secret
*.key
*.key.pub
*.egg-info

node_modules
*.py[co]
*~
.cache
.DS_Store
/build
dist
docs/_build
docs/build

.ipynb_checkpoints
.virtual_documents


jupyterhub_cookie_secret
jupyterhub.sqlite
jupyterhub.sqlite*

*.egg-info
MANIFEST
.coverage
.coverage.*
htmlcov
.idea/
.vscode/
.pytest_cache
pip-wheel-metadata
oldest-requirements.txt
jupyterhub-proxy.pid

*.hot-update*
49 changes: 49 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# pre-commit is a tool to perform a predefined set of tasks manually and/or
# automatically before git commits are made.
#
# Config reference: https://pre-commit.com/#pre-commit-configyaml---top-level
#
# Common tasks
#
# - Run on all files: pre-commit run --all-files
# - Register git hooks: pre-commit install --install-hooks
#

ci:
# pre-commit.ci will open PRs updating our hooks once a month
autoupdate_schedule: monthly

repos:
# autoformat and lint Python code
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.3
hooks:
- id: ruff
types_or:
- python
- jupyter
args: ["--fix", "--show-fixes"]
- id: ruff-format
types_or:
- python
- jupyter

# Autoformat: markdown, yaml, javascript (see the file .prettierignore)
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v4.0.0-alpha.8
hooks:
- id: prettier

# Format toml
- repo: https://github.com/ComPWA/taplo-pre-commit
rev: v0.9.3
hooks:
- id: taplo-format
- id: taplo-lint

# Autoformat and linting, misc. details
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: end-of-file-fixer
- id: requirements-txt-fixer
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# SMART on FHIR flow in Jupyter

This repo contains two demos:
- `server_extension`: a Jupyter server extension that acts as public client for a SMART server.
- `hub_service`: a JupyterHub service that acts as confidential client for a SMART server and performs asymmetric authentication.

- `server_extension`: a Jupyter server extension that acts as public client for a SMART server.
- `hub_service`: a JupyterHub service that acts as confidential client for a SMART server and performs asymmetric authentication.

Check the READMEs in the respective folders for more information. Work in progress.
9 changes: 7 additions & 2 deletions examples/hub_service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@ This project contains a demo of a JupyterHub service that acts as a confidential
## Installation

1. Clone this repository:

```
git clone https://github.com/jupyterhealth/smart-fhir-jupyter-demo.git
cd smart-fhir-jupyter-demo/hub_service
```

2. Create and activate a virtual environment:

```
python -m venv .venv
source .venv/bin/activate
source .venv/bin/activate
```

3. Install the required dependencies:

```
pip install -e .
```
Expand All @@ -30,6 +33,7 @@ This project contains a demo of a JupyterHub service that acts as a confidential
## Configuration

1. Update the `jupyterhub_config.py` file with your SMART on FHIR server details:

- Set the `fhir_base_url` to the sandbox server's URL

2. As a confidential client, this needs a public/private key pair. For demo purposes, the script takes care of generating this keypair.
Expand All @@ -39,4 +43,5 @@ This project contains a demo of a JupyterHub service that acts as a confidential
Once authenticated, users can make requests to the FHIR server through the service. The service handles token management and SMART on FHIR authentication flow.

Example:
- Accessing `http://localhost:8000/hub/fhir` will fetch Condition resources from the FHIR server.

- Accessing `http://localhost:8000/hub/fhir` will fetch Condition resources from the FHIR server.
1 change: 0 additions & 1 deletion examples/hub_service/jupyterhub_config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import requests

from oauthenticator.generic import GenericOAuthenticator

c = get_config() # noqa
Expand Down
18 changes: 10 additions & 8 deletions examples/server_extension/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SMART App demo with Jupyter

This is a Jupyter server extension that fetches data from a SMART on FHIR endpoint.
This is a Jupyter server extension that fetches data from a SMART on FHIR endpoint.

_work in progress_

Expand All @@ -9,15 +9,17 @@ _work in progress_
## Local Installation with pip

1. Clone the repository:

```
git clone https://github.com/jupyterhealth/smart-fhir-jupyter-demo.git
cd smart-fhir-jupyter-demo/server_extension
```

2. Create and activate a virtual environment:

```
python -m venv .venv
source .venv/bin/activate
source .venv/bin/activate
```

3. Install the Jupyter server extension:
Expand All @@ -28,6 +30,7 @@ _work in progress_
## Installation with Docker

1. Clone the repository:

```
git clone https://github.com/jupyterhealth/smart-fhir-jupyter-demo.git
cd smart-fhir-jupyter-demo/server_extension
Expand All @@ -45,20 +48,23 @@ _work in progress_
1. Ensure you're in the project directory and your virtual environment is activated.

2. Enable the server extension:

```
jupyter server extension enable jupyter_smart_on_fhir.server_extension
```

2. Start the Jupyter server:
3. Start the Jupyter server:

```
jupyter server
```

3. Open a web browser and navigate to `http://localhost:8888` to access the Jupyter interface.
4. Open a web browser and navigate to `http://localhost:8888` to access the Jupyter interface.

## Running with Docker

1. Run the Docker container:

```
docker run -p 8888:8888 smart-server-extension
```
Expand All @@ -71,7 +77,3 @@ _work in progress_
```
http://localhost:8888/extension/fhir
```




11 changes: 6 additions & 5 deletions jupyter_smart_on_fhir/auth.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from dataclasses import dataclass, asdict
import requests
import secrets
import jwt
import json
import os
import secrets
from dataclasses import asdict, dataclass
from pathlib import Path

import jwt
import requests


@dataclass
class SMARTConfig:
Expand Down Expand Up @@ -47,7 +48,7 @@ def generate_state(next_url=None) -> dict:
def get_jwks_from_key(key_file: Path, key_id: str = "1") -> str:
"""Generate a JWKS from a public key file. Not required for end users, but useful for development"""
try:
with open(key_file + ".pub", "r") as f:
with open(key_file + ".pub") as f:
public_key = f.read()
except FileNotFoundError as e:
raise FileNotFoundError(
Expand Down
16 changes: 9 additions & 7 deletions jupyter_smart_on_fhir/hub_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,27 @@
- Asymmetric authentication
"""

import base64
import os
import time
import secrets
import time
from functools import wraps
from urllib.parse import urlencode

import jwt
import requests
from cryptography.fernet import Fernet, InvalidToken
from flask import (
Flask,
Response,
current_app,
make_response,
redirect,
request,
session,
current_app,
)
import requests
from urllib.parse import urlencode
import jwt
import base64

from jupyter_smart_on_fhir.auth import SMARTConfig, generate_state, validate_keys
from cryptography.fernet import Fernet, InvalidToken

prefix = os.environ.get("JUPYTERHUB_SERVICE_PREFIX", "/")

Expand Down
16 changes: 9 additions & 7 deletions jupyter_smart_on_fhir/server_extension.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
from jupyter_server.extension.application import ExtensionApp
from jupyter_server.base.handlers import JupyterHandler
import tornado
import requests
import base64
import hashlib
import secrets
from urllib.parse import urlencode, urljoin
import hashlib
import base64
from jupyter_smart_on_fhir.auth import SMARTConfig, generate_state

import requests
import tornado
from jupyter_server.base.handlers import JupyterHandler
from jupyter_server.extension.application import ExtensionApp
from traitlets import List, Unicode

from jupyter_smart_on_fhir.auth import SMARTConfig, generate_state

smart_path = "/smart"
login_path = "/smart/login"
callback_path = "/smart/oauth_callback"
Expand Down
Loading

0 comments on commit 0a698d0

Please sign in to comment.