-
Notifications
You must be signed in to change notification settings - Fork 45
feat: add Python3.12 tenants support #822
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
khyurri
wants to merge
1
commit into
main
Choose a base branch
from
feature/python3.12
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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 @@ | ||
| /venv/ | ||
| /.pytest_cache/ | ||
| /.mypy_cache/ |
This file contains hidden or 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,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 |
This file contains hidden or 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,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://badgerdoc-keycloak" (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. | ||
This file contains hidden or 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,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"] |
This file contains hidden or 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 @@ | ||
| pytest | ||
| requests | ||
| pytest-cov | ||
| black | ||
| isort==5.9.1 | ||
| pylint | ||
| mypy==0.910 |
This file contains hidden or 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 @@ | ||
| fastapi>=0.68.0 | ||
| httpx | ||
| PyJWT[crypto]==2.3.0 |
This file contains hidden or 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,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="Roman_Kuzianov@epam.com", | ||
| packages=["tenant_dependency"], | ||
| package_dir={"tenant_dependency": "src"}, | ||
| install_requires=get_requirements("requirements.txt"), | ||
| extras_require={"dev": get_requirements("requirements-dev.txt")}, | ||
| ) |
This file contains hidden or 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 @@ | ||
| from .dependency import get_tenant_info # noqa | ||
| from .schema import TenantData # noqa |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think i missed this one