Skip to content

Commit

Permalink
feat: add Python3.12 tenants
Browse files Browse the repository at this point in the history
  • Loading branch information
khyurri committed Jan 6, 2024
1 parent 76c1373 commit 66ad790
Show file tree
Hide file tree
Showing 22 changed files with 910 additions and 23 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/filter-lib.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ on:
push:
paths:
- lib/filter_lib/**
- lib/python3.12/filter_lib/**
- .github/worlflows/filter-lib.yml
pull_request:
paths:
- lib/filter_lib/**
- lib/python3.12/filter_lib/**
- .github/worlflows/filter-lib.yml
jobs:
filter-lib-pre-commit-actions:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
filter-lib-pre-commit-actions:
strategy:
matrix:
python-version: [ "3.12.1" ]
python-version: [ "3.12.0", "3.12.1" ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -41,7 +41,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ "3.12.1" ]
python-version: [ "3.12.0", "3.12.1" ]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -53,10 +53,8 @@ jobs:
run: |
python -m pip install --upgrade pip
cd lib/python3.12/filter_lib
pip install -r requirements.txt
pip install -r requirements-dev.txt
pip install ".[dev]"
- name: Test with pytest
run: |
cd lib/python3.12/filter_lib
pytest

Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
name: filter_lib precommit and test
run-name: filter_lib precommit and test
name: tenants precommit and test
run-name: tenants precommit and test
on:
push:
paths:
- lib/python3.12/filter_lib/**
- .github/worlflows/python3.12/filter-lib.yml
- lib/python3.12/tenants/**
- .github/worlflows/python3.12/tenants.yml
pull_request:
paths:
- lib/python3.12/filter_lib/**
- .github/worlflows/python3.12/filter-lib.yml
- lib/python3.12/tenants/**
- .github/worlflows/python3.12/tenants.yml
jobs:
filter-lib-pre-commit-actions:
tenants-pre-commit-actions:
strategy:
matrix:
python-version: [ "3.12.1" ]
python-version: [ "3.12.0", "3.12.1" ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand All @@ -24,7 +24,7 @@ jobs:
- name: Run isort
uses: isort/[email protected]
with:
sort-paths: lib/python3.12/filter_lib/*
sort-paths: lib/python3.12/tenants/*
configuration:
--check-only
--profile=black
Expand All @@ -33,15 +33,15 @@ jobs:
- name: Black
uses: psf/black@stable
with:
src: "lib/python3.12/filter_lib"
src: "lib/python3.12/tenants"
options: '--check --line-length=79 --exclude="tests" --verbose'
- run: pip install flake8
- run: flake8 --exclude=tests --extend-ignore=E203 lib/python3.12/filter_lib
filter-lib-build:
- run: flake8 --exclude=tests --extend-ignore=E203 lib/python3.12/tenants
tenants-build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ "3.12.1" ]
python-version: [ "3.12.0", "3.12.1" ]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -52,11 +52,9 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
cd lib/python3.12/filter_lib
pip install -r requirements.txt
pip install -r requirements-dev.txt
cd lib/python3.12/tenants
pip install ".[dev]"
- name: Test with pytest
run: |
cd lib/python3.12/filter_lib
cd lib/python3.12/tenants
pytest
3 changes: 3 additions & 0 deletions lib/python3.12/tenants/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/venv/
/.pytest_cache/
/.mypy_cache/
49 changes: 49 additions & 0 deletions lib/python3.12/tenants/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- repo: https://github.com/pycqa/isort
rev: 5.9.1
hooks:
- id: isort
args:
- --profile=black
- --line-length=79
exclude: tests/
- repo: https://github.com/psf/black
rev: 21.6b0
hooks:
- id: black
language_version: python3
args:
- --line-length=79
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.910
hooks:
- id: mypy
name: mypy
entry: mypy
language: python
types: [python]
args:
- --ignore-missing-imports
- --scripts-are-modules
- --allow-untyped-decorators
- --strict
- --no-strict-optional
require_serial: true
exclude: tests/
additional_dependencies:
- 'pydantic'
- repo: https://github.com/pycqa/pylint
rev: pylint-2.8.1
hooks:
- id: pylint
types: [ python ]
args:
- --max-line-length=79
- --errors-only
- --disable=E0401,E0611
58 changes: 58 additions & 0 deletions lib/python3.12/tenants/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
## How to use with BadgerDoc

Import and create an instance of tenant dependency.
To make this dependency work with BadgerDoc you need to provide an url to keycloak and set 'algorithm' arg to `RS256`.

```Python
from tenant_dependency import TenantData, get_tenant_info

# inner url would look like this "http://bagerdoc-keycloack" (http://{keycloak_pod_name})
# outer url would look like this "http://dev1.gcov.ru"

tenant = get_tenant_info(url="http://dev1.gcov.ru", algorithm="RS256", debug=True)
```
## Note:
#### If you're using algorithm RS256 (Current BadgerDoc algorithm) you don't need arg "key", use only "url".
#### Otherwise, if you're using algorithm HS256, you need "key" arg and don't need "url". Check `usage_example/main.py`.
Param `debug` is needed to render `Authorize` button in `/openapi` docs.

Now you can add this dependency to your FastAPI endpoint:

```Python
from fastapi import Depends, FastAPI
from tenant_dependency import TenantData, get_tenant_info

app = FastAPI()
tenant = get_tenant_info(url="http://dev1.gcov.ru", algorithm="RS256", debug=True)


@app.post("/test")
async def get_nums(token: TenantData = Depends(tenant)):
return token.dict()
```
Default values for `algorithm` and `debug` is `RS256` and `True`,
so you can create an instance like that:
```Python
tenant = get_tenant_info(url="http://dev1.gcov.ru")
```


Go to docs and check how it works.

1) Click `Authorize` and submit token.
2) Try to use endpoint.

Without valid jwt this endpoint `/test` will raise 401 Error.


```Python
@app.post("/test")
async def get_nums(token: TenantData = Depends(tenant)):
return token.dict()
```
This dependency will:
1) Check if incoming request came with header `Authorization`, if that header wasn't provided Error 401 will be raised.
2) If header `Authorization` exists, dependency will try to validate it with signature key or url those you put as args to dependency `tenant = get_tenant_info(key="SECRET") / tenant = get_tenant_info(url="http://bagerdoc-keycloack")`. If is key invalid or token is expired 401 Error will be raised.
3) It also checks header for arg "X-Current-Tenant", so if that arg isn't provided 401 will be raised. In case "X-Current-Tenant" provided dependency will check "X-Current-Tenant" containing in `tenants` array. Raises 401 if check wasn't successful.
4) If token is valid dependency will parse token's body and get data from it. Token must contain data about `tenants`, `user_id` and `roles`, otherwise 403 error will be raised.
5) If previous steps were successful, your endpoint can do anything further, and you can work with `token` arg that is actually is a pydantic model, so you can work with it like you work with other pydantic models.
20 changes: 20 additions & 0 deletions lib/python3.12/tenants/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[tool.black]
line-length = 79

[tool.isort]
profile = "black"
line_length = 79

[tool.mypy]
plugins = "pydantic.mypy"
ignore_missing_imports = "True"
scripts_are_modules = "True"
allow_untyped_decorators = "True"
strict = "True"
no_strict_optional = "True"
disallow_untyped_calls = "False"

[tool.pylint.basic]
max-line-length=79
errors-only = "True"
disable = ["E0401", "E0611"]
7 changes: 7 additions & 0 deletions lib/python3.12/tenants/requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pytest
requests
pytest-cov
black
isort==5.9.1
pylint
mypy==0.910
3 changes: 3 additions & 0 deletions lib/python3.12/tenants/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fastapi>=0.68.0
httpx
PyJWT[crypto]==2.3.0
27 changes: 27 additions & 0 deletions lib/python3.12/tenants/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from typing import List

from setuptools import setup


def get_requirements(path: str) -> List[str]:
with open(path, "r", encoding="utf-8") as file:
return [row.strip() for row in file.readlines()]


def get_long_description(path: str) -> str:
with open(path, "r", encoding="utf-8") as file:
return file.read()


setup(
name="tenant_dependency",
version="0.1.3",
description="Package for validating and parsing jwt via FastAPI dependency", # noqa
long_description=get_long_description("README.md"),
author="Roman Kuzianov",
author_email="[email protected]",
packages=["tenant_dependency"],
package_dir={"tenant_dependency": "src"},
install_requires=get_requirements("requirements.txt"),
extras_require={"dev": get_requirements("requirements-dev.txt")},
)
2 changes: 2 additions & 0 deletions lib/python3.12/tenants/src/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .dependency import get_tenant_info # noqa
from .schema import TenantData # noqa
Loading

0 comments on commit 66ad790

Please sign in to comment.