[conf] add envfile supprt / fix the bugs related to acl_caller_middleware / fix the bugs related to responses classes
This commit is contained in:
parent
f0d5eb7d92
commit
644e5c5d3d
|
@ -1,2 +1,3 @@
|
||||||
export HALFORM_SECRET="halform_secret"
|
HALFORM_SECRET="halform_secret"
|
||||||
export HALFORM_DSN="dbname=api user=api password= host=127.0.0.1 port=5432"
|
HALFORM_DSN="dbname=api user=api password= host=127.0.0.1 port=5432"
|
||||||
|
DEBUG=1
|
||||||
|
|
|
@ -100,16 +100,18 @@ def check_conf():
|
||||||
if not environ.get('HALFORM_DSN', False):
|
if not environ.get('HALFORM_DSN', False):
|
||||||
print('Missing HALFORM_DSN variable from configuration')
|
print('Missing HALFORM_DSN variable from configuration')
|
||||||
|
|
||||||
DEBUG = True
|
CONFIG={
|
||||||
|
'DEBUG' : 'DEBUG' in environ.keys()
|
||||||
|
}
|
||||||
|
|
||||||
debug_routes = [
|
debug_routes = [
|
||||||
Route('/', lambda request: PlainTextResponse('It Works!')),
|
Route('/', lambda request, *args, **kwargs: PlainTextResponse('It Works!')),
|
||||||
Route('/user', lambda request: JSONResponse({'user':request.user})),
|
Route('/user', lambda request, *args, **kwargs: JSONResponse({'user':str(request.user)})),
|
||||||
Route('/payload', lambda request: JSONResponse({'payload':request.payload}))
|
Route('/payload', lambda request, *args, **kwargs: JSONResponse({'payload':str(request.payload)}))
|
||||||
] if DEBUG is True else []
|
] if CONFIG['DEBUG'] is True else []
|
||||||
|
|
||||||
app = Starlette(
|
app = Starlette(
|
||||||
debug=DEBUG,
|
debug=CONFIG['DEBUG'],
|
||||||
routes=debug_routes,
|
routes=debug_routes,
|
||||||
middleware=[
|
middleware=[
|
||||||
Middleware(AuthenticationMiddleware, backend=JWTAuthenticationBackend(secret_key=environ.get('HALFORM_SECRET'))),
|
Middleware(AuthenticationMiddleware, backend=JWTAuthenticationBackend(secret_key=environ.get('HALFORM_SECRET'))),
|
||||||
|
|
|
@ -32,6 +32,7 @@ def cli(ctx):
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
return run()
|
return run()
|
||||||
|
|
||||||
|
@click.option('--envfile', default=None)
|
||||||
@click.option('--host', default='127.0.0.1')
|
@click.option('--host', default='127.0.0.1')
|
||||||
@click.option('--port', default='8000')
|
@click.option('--port', default='8000')
|
||||||
@click.option('--debug', default=False)
|
@click.option('--debug', default=False)
|
||||||
|
@ -42,7 +43,17 @@ def cli(ctx):
|
||||||
@click.option('--dbuser', default='api')
|
@click.option('--dbuser', default='api')
|
||||||
@click.option('--dbpassword', default='')
|
@click.option('--dbpassword', default='')
|
||||||
@cli.command()
|
@cli.command()
|
||||||
def run(host, port, debug, dev, dbname, dbhost, dbport, dbuser, dbpassword):
|
def run(envfile, host, port, debug, dev, dbname, dbhost, dbport, dbuser, dbpassword):
|
||||||
|
if envfile:
|
||||||
|
try:
|
||||||
|
with open(envfile) as f:
|
||||||
|
print('Will use the following env parameters')
|
||||||
|
print(f.readlines())
|
||||||
|
pass
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f'No file named {envfile}')
|
||||||
|
envfile = None
|
||||||
|
|
||||||
if dev:
|
if dev:
|
||||||
debug = True
|
debug = True
|
||||||
reload = True
|
reload = True
|
||||||
|
@ -87,6 +98,7 @@ def run(host, port, debug, dev, dbname, dbhost, dbport, dbuser, dbpassword):
|
||||||
sys.path.insert(0, os.getcwd())
|
sys.path.insert(0, os.getcwd())
|
||||||
click.echo(sys.path)
|
click.echo(sys.path)
|
||||||
uvicorn.run('halfapi.app:app',
|
uvicorn.run('halfapi.app:app',
|
||||||
|
env_file=envfile,
|
||||||
host=host,
|
host=host,
|
||||||
port=int(port),
|
port=int(port),
|
||||||
log_level=log_level,
|
log_level=log_level,
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
from os import environ
|
||||||
|
|
||||||
from starlette.exceptions import HTTPException
|
from starlette.exceptions import HTTPException
|
||||||
from starlette.middleware.base import BaseHTTPMiddleware
|
from starlette.middleware.base import BaseHTTPMiddleware
|
||||||
from starlette.routing import Match, Mount
|
from starlette.routing import Match, Mount
|
||||||
|
@ -6,7 +8,11 @@ from starlette.types import ASGIApp, Receive, Scope, Send
|
||||||
|
|
||||||
from halfapi.models.api.view.acl import Acl as AclView
|
from halfapi.models.api.view.acl import Acl as AclView
|
||||||
|
|
||||||
def match_route(scope: Scope):
|
class DebugRouteException(Exception):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(self)
|
||||||
|
|
||||||
|
def match_route(app: ASGIApp, scope: Scope):
|
||||||
""" Checks all routes from "app" and checks if it matches with the one from
|
""" Checks all routes from "app" and checks if it matches with the one from
|
||||||
scope
|
scope
|
||||||
|
|
||||||
|
@ -30,7 +36,10 @@ def match_route(scope: Scope):
|
||||||
Refer to the database documentation for more details on the api.route
|
Refer to the database documentation for more details on the api.route
|
||||||
table.
|
table.
|
||||||
"""
|
"""
|
||||||
from halfapi.app import app
|
|
||||||
|
print('3')
|
||||||
|
from ..app import CONFIG
|
||||||
|
print(CONFIG)
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
'domain': None,
|
'domain': None,
|
||||||
|
@ -39,6 +48,9 @@ def match_route(scope: Scope):
|
||||||
'version': None
|
'version': None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if 'DEBUG' in CONFIG.keys() and len(scope['path'].split('/')) <= 3:
|
||||||
|
raise DebugRouteException()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
""" Identification of the parts of the path
|
""" Identification of the parts of the path
|
||||||
|
|
||||||
|
@ -51,7 +63,6 @@ def match_route(scope: Scope):
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
#404 Not found
|
#404 Not found
|
||||||
raise HTTPException(404)
|
raise HTTPException(404)
|
||||||
|
|
||||||
# Prefix the path with "/"
|
# Prefix the path with "/"
|
||||||
path = f'/{path}'
|
path = f'/{path}'
|
||||||
|
|
||||||
|
@ -111,13 +122,18 @@ class AclCallerMiddleware(BaseHTTPMiddleware):
|
||||||
await self.app(scope, receive, send)
|
await self.app(scope, receive, send)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
app = self.app
|
||||||
|
while True:
|
||||||
|
if not hasattr(app, 'app'):
|
||||||
|
break
|
||||||
|
app = app.app
|
||||||
|
|
||||||
if scope['path'].split('/')[-1] not in ['docs','openapi.json','redoc']:
|
if scope['path'].split('/')[-1] not in ['docs','openapi.json','redoc']:
|
||||||
# routes in the the database, the others being
|
# routes in the the database, the others being
|
||||||
# docs/openapi.json/redoc
|
# docs/openapi.json/redoc
|
||||||
d_match, path_params = match_route(scope)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
d_match, path_params = match_route(app, scope)
|
||||||
scope['acls'] = []
|
scope['acls'] = []
|
||||||
for acl in AclView(**d_match).select():
|
for acl in AclView(**d_match).select():
|
||||||
# retrieve related ACLs
|
# retrieve related ACLs
|
||||||
|
@ -132,5 +148,11 @@ class AclCallerMiddleware(BaseHTTPMiddleware):
|
||||||
# TODO : No ACL sur une route existante, prevenir l'admin?
|
# TODO : No ACL sur une route existante, prevenir l'admin?
|
||||||
print("No ACL")
|
print("No ACL")
|
||||||
pass
|
pass
|
||||||
|
except DebugRouteException:
|
||||||
|
print("Debug route")
|
||||||
|
if 'DEBUG_ACL' in environ.keys():
|
||||||
|
scope['acls'] = environ['DEBUG_ACL'].split(':')
|
||||||
|
else:
|
||||||
|
scope['acls'] = []
|
||||||
|
|
||||||
return await self.app(scope, receive, send)
|
return await self.app(scope, receive, send)
|
||||||
|
|
|
@ -5,12 +5,13 @@ from datetime import date
|
||||||
from io import TextIOBase, StringIO
|
from io import TextIOBase, StringIO
|
||||||
|
|
||||||
# asgi framework
|
# asgi framework
|
||||||
from starlette.responses import Response
|
from starlette.responses import PlainTextResponse, Response
|
||||||
|
|
||||||
__all__ = ['CSVResponse',
|
__all__ = ['CSVResponse',
|
||||||
'InternalServerErrorResponse',
|
'InternalServerErrorResponse',
|
||||||
'NotFoundResponse',
|
'NotFoundResponse',
|
||||||
'NotImplementedResponse',
|
'NotImplementedResponse',
|
||||||
|
'PlainTextResponse',
|
||||||
'UnauthorizedResponse']
|
'UnauthorizedResponse']
|
||||||
|
|
||||||
class CSVResponse(Response):
|
class CSVResponse(Response):
|
||||||
|
@ -32,27 +33,27 @@ class CSVResponse(Response):
|
||||||
class InternalServerErrorResponse(Response):
|
class InternalServerErrorResponse(Response):
|
||||||
""" The 500 Internal Server Error default Response
|
""" The 500 Internal Server Error default Response
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(status_code=500)
|
super().__init__(status_code=500)
|
||||||
|
|
||||||
|
|
||||||
class NotFoundResponse(Response):
|
class NotFoundResponse(Response):
|
||||||
""" The 404 Not Found default Response
|
""" The 404 Not Found default Response
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(status_code=404)
|
super().__init__(status_code=404)
|
||||||
|
|
||||||
|
|
||||||
class NotImplementedResponse(Response):
|
class NotImplementedResponse(Response):
|
||||||
""" The 501 Not Implemented default Response
|
""" The 501 Not Implemented default Response
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(status_code=501)
|
super().__init__(status_code=501)
|
||||||
|
|
||||||
|
|
||||||
class UnauthorizedResponse(Response):
|
class UnauthorizedResponse(Response):
|
||||||
""" The 401 Not Found default Response
|
""" The 401 Not Found default Response
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(status_code = 401)
|
super().__init__(status_code = 401)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Atomic file writes."
|
description = "Atomic file writes."
|
||||||
|
marker = "sys_platform == \"win32\""
|
||||||
name = "atomicwrites"
|
name = "atomicwrites"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
@ -53,6 +54,14 @@ optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
category = "main"
|
||||||
|
description = "Handle .env files"
|
||||||
|
name = "dotenv"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
version = "0.0.5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
|
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
|
||||||
|
@ -95,6 +104,7 @@ psycopg2-binary = "*"
|
||||||
reference = "fe53195abb637d2192857e8b4878f4865b0fcce4"
|
reference = "fe53195abb637d2192857e8b4878f4865b0fcce4"
|
||||||
type = "git"
|
type = "git"
|
||||||
url = "git@gite.lirmm.fr:newsi/halfORM.git"
|
url = "git@gite.lirmm.fr:newsi/halfORM.git"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "A collection of framework independent HTTP protocol utils."
|
description = "A collection of framework independent HTTP protocol utils."
|
||||||
|
@ -159,6 +169,19 @@ uvicorn = "*"
|
||||||
reference = "4f9cf92253b2ee526a528724877840c8ec158d3a"
|
reference = "4f9cf92253b2ee526a528724877840c8ec158d3a"
|
||||||
type = "git"
|
type = "git"
|
||||||
url = "git@gite.lirmm.fr:newsi/api/organigramme.git"
|
url = "git@gite.lirmm.fr:newsi/api/organigramme.git"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
category = "dev"
|
||||||
|
description = "Core utilities for Python packages"
|
||||||
|
name = "packaging"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
version = "20.4"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
pyparsing = ">=2.0.2"
|
||||||
|
six = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "plugin and hook calling mechanisms for python"
|
description = "plugin and hook calling mechanisms for python"
|
||||||
|
@ -217,23 +240,39 @@ crypto = ["cryptography (>=1.4)"]
|
||||||
flake8 = ["flake8", "flake8-import-order", "pep8-naming"]
|
flake8 = ["flake8", "flake8-import-order", "pep8-naming"]
|
||||||
test = ["pytest (>=4.0.1,<5.0.0)", "pytest-cov (>=2.6.0,<3.0.0)", "pytest-runner (>=4.2,<5.0.0)"]
|
test = ["pytest (>=4.0.1,<5.0.0)", "pytest-cov (>=2.6.0,<3.0.0)", "pytest-runner (>=4.2,<5.0.0)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
category = "dev"
|
||||||
|
description = "Python parsing module"
|
||||||
|
name = "pyparsing"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
|
version = "2.4.7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "pytest: simple powerful testing with Python"
|
description = "pytest: simple powerful testing with Python"
|
||||||
name = "pytest"
|
name = "pytest"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=3.5"
|
||||||
version = "3.10.1"
|
version = "5.4.3"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
atomicwrites = ">=1.0"
|
atomicwrites = ">=1.0"
|
||||||
attrs = ">=17.4.0"
|
attrs = ">=17.4.0"
|
||||||
colorama = "*"
|
colorama = "*"
|
||||||
more-itertools = ">=4.0.0"
|
more-itertools = ">=4.0.0"
|
||||||
pluggy = ">=0.7"
|
packaging = "*"
|
||||||
|
pluggy = ">=0.12,<1.0"
|
||||||
py = ">=1.5.0"
|
py = ">=1.5.0"
|
||||||
setuptools = "*"
|
wcwidth = "*"
|
||||||
six = ">=1.10.0"
|
|
||||||
|
[package.dependencies.importlib-metadata]
|
||||||
|
python = "<3.8"
|
||||||
|
version = ">=0.12"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
checkqa-mypy = ["mypy (v0.761)"]
|
||||||
|
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
|
@ -276,6 +315,7 @@ half_orm = "*"
|
||||||
reference = "d0f14a9631eecd29098d13a3f34e9cd533145f24"
|
reference = "d0f14a9631eecd29098d13a3f34e9cd533145f24"
|
||||||
type = "git"
|
type = "git"
|
||||||
url = "git@gite.lirmm.fr:newsi/sidb_halfORM.git"
|
url = "git@gite.lirmm.fr:newsi/sidb_halfORM.git"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Python 2 and 3 compatibility utilities"
|
description = "Python 2 and 3 compatibility utilities"
|
||||||
|
@ -335,6 +375,14 @@ optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
category = "dev"
|
||||||
|
description = "Measures the displayed width of unicode strings in a terminal"
|
||||||
|
name = "wcwidth"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
version = "0.2.5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
|
description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
|
||||||
|
@ -360,7 +408,7 @@ testing = ["jaraco.itertools", "func-timeout"]
|
||||||
organigramme = ["fastapi", "organigramme"]
|
organigramme = ["fastapi", "organigramme"]
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
content-hash = "54154bcf65bf5540092d6493dd5810fb541bc4a75e9fc328ca66d25ef5ed0584"
|
content-hash = "56e1f269ca07039fa6898fa427261f61cab9ef871c5a82edb592cbfb197c2d03"
|
||||||
python-versions = "^3.7"
|
python-versions = "^3.7"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
|
@ -388,6 +436,9 @@ colorama = [
|
||||||
{file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"},
|
{file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"},
|
||||||
{file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"},
|
{file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"},
|
||||||
]
|
]
|
||||||
|
dotenv = [
|
||||||
|
{file = "dotenv-0.0.5.tar.gz", hash = "sha256:b58d2ab3f83dbd4f8a362b21158a606bee87317a9444485566b3c8f0af847091"},
|
||||||
|
]
|
||||||
fastapi = [
|
fastapi = [
|
||||||
{file = "fastapi-0.58.1-py3-none-any.whl", hash = "sha256:d7499761d5ca901cdf5b6b73018d14729593f8ab1ea22d241f82fa574fc406ad"},
|
{file = "fastapi-0.58.1-py3-none-any.whl", hash = "sha256:d7499761d5ca901cdf5b6b73018d14729593f8ab1ea22d241f82fa574fc406ad"},
|
||||||
{file = "fastapi-0.58.1.tar.gz", hash = "sha256:92e59b77eef7d6eaa80b16d275adda06b5f33b12d777e3fc5521b2f7f4718e13"},
|
{file = "fastapi-0.58.1.tar.gz", hash = "sha256:92e59b77eef7d6eaa80b16d275adda06b5f33b12d777e3fc5521b2f7f4718e13"},
|
||||||
|
@ -424,6 +475,10 @@ more-itertools = [
|
||||||
{file = "more_itertools-8.4.0-py3-none-any.whl", hash = "sha256:b78134b2063dd214000685165d81c154522c3ee0a1c0d4d113c80361c234c5a2"},
|
{file = "more_itertools-8.4.0-py3-none-any.whl", hash = "sha256:b78134b2063dd214000685165d81c154522c3ee0a1c0d4d113c80361c234c5a2"},
|
||||||
]
|
]
|
||||||
organigramme = []
|
organigramme = []
|
||||||
|
packaging = [
|
||||||
|
{file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"},
|
||||||
|
{file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"},
|
||||||
|
]
|
||||||
pluggy = [
|
pluggy = [
|
||||||
{file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
|
{file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
|
||||||
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
|
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
|
||||||
|
@ -487,9 +542,13 @@ pyjwt = [
|
||||||
{file = "PyJWT-1.7.1-py2.py3-none-any.whl", hash = "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e"},
|
{file = "PyJWT-1.7.1-py2.py3-none-any.whl", hash = "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e"},
|
||||||
{file = "PyJWT-1.7.1.tar.gz", hash = "sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96"},
|
{file = "PyJWT-1.7.1.tar.gz", hash = "sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96"},
|
||||||
]
|
]
|
||||||
|
pyparsing = [
|
||||||
|
{file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
|
||||||
|
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
|
||||||
|
]
|
||||||
pytest = [
|
pytest = [
|
||||||
{file = "pytest-3.10.1-py2.py3-none-any.whl", hash = "sha256:3f193df1cfe1d1609d4c583838bea3d532b18d6160fd3f55c9447fdca30848ec"},
|
{file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"},
|
||||||
{file = "pytest-3.10.1.tar.gz", hash = "sha256:e246cf173c01169b9617fc07264b7b1316e78d7a650055235d6d897bc80d9660"},
|
{file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"},
|
||||||
]
|
]
|
||||||
pyyaml = [
|
pyyaml = [
|
||||||
{file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"},
|
{file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"},
|
||||||
|
@ -536,6 +595,10 @@ uvloop = [
|
||||||
{file = "uvloop-0.14.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09"},
|
{file = "uvloop-0.14.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09"},
|
||||||
{file = "uvloop-0.14.0.tar.gz", hash = "sha256:123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e"},
|
{file = "uvloop-0.14.0.tar.gz", hash = "sha256:123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e"},
|
||||||
]
|
]
|
||||||
|
wcwidth = [
|
||||||
|
{file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
|
||||||
|
{file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
|
||||||
|
]
|
||||||
websockets = [
|
websockets = [
|
||||||
{file = "websockets-8.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c"},
|
{file = "websockets-8.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c"},
|
||||||
{file = "websockets-8.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170"},
|
{file = "websockets-8.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170"},
|
||||||
|
|
|
@ -22,9 +22,9 @@ requests = "^2"
|
||||||
[tool.poetry.extras]
|
[tool.poetry.extras]
|
||||||
organigramme = [ "fastapi", "organigramme" ]
|
organigramme = [ "fastapi", "organigramme" ]
|
||||||
|
|
||||||
|
[tool.poetry.scripts]
|
||||||
|
halfapi = 'halfapi.cli:cli'
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry>=0.12"]
|
requires = ["poetry>=0.12"]
|
||||||
build-backend = "poetry.masonry.api"
|
build-backend = "poetry.masonry.api"
|
||||||
|
|
||||||
[tool.poetry.scripts]
|
|
||||||
halfapi = 'halfapi.cli:cli'
|
|
||||||
|
|
Loading…
Reference in New Issue