[wip] refactor half_domain
This commit is contained in:
parent
b4157c4a7d
commit
7001cec86e
|
@ -14,7 +14,7 @@ from .cli import cli
|
|||
|
||||
from ..logging import logger
|
||||
|
||||
from ..lib.domain import domain_schema_dict
|
||||
# from ..lib.domain import domain_schema_dict
|
||||
from ..lib.constants import DOMAIN_SCHEMA, ROUTE_SCHEMA
|
||||
from ..lib.responses import ORJSONResponse
|
||||
# from ..lib.routes import api_routes
|
||||
|
@ -31,26 +31,26 @@ def routes(module, export=False, validate=False, check=False, noheader=False, sc
|
|||
"""
|
||||
The "halfapi routes" command
|
||||
"""
|
||||
try:
|
||||
mod = importlib.import_module(module)
|
||||
except ImportError as exc:
|
||||
raise click.BadParameter('Cannot import this module', param=module) from exc
|
||||
# try:
|
||||
# mod = importlib.import_module(module)
|
||||
# except ImportError as exc:
|
||||
# raise click.BadParameter('Cannot import this module', param=module) from exc
|
||||
|
||||
if export:
|
||||
click.echo(schema_to_csv(module, header=not noheader))
|
||||
# if export:
|
||||
# click.echo(schema_to_csv(module, header=not noheader))
|
||||
|
||||
if schema:
|
||||
routes_d = domain_schema_dict(mod)
|
||||
ROUTE_SCHEMA.validate(routes_d)
|
||||
click.echo(orjson.dumps(routes_d,
|
||||
option=orjson.OPT_NON_STR_KEYS,
|
||||
default=ORJSONResponse.default_cast))
|
||||
# if schema:
|
||||
# routes_d = domain_schema_dict(mod)
|
||||
# ROUTE_SCHEMA.validate(routes_d)
|
||||
# click.echo(orjson.dumps(routes_d,
|
||||
# option=orjson.OPT_NON_STR_KEYS,
|
||||
# default=ORJSONResponse.default_cast))
|
||||
|
||||
|
||||
if validate:
|
||||
routes_d = domain_schema_dict(mod)
|
||||
try:
|
||||
ROUTE_SCHEMA.validate(routes_d)
|
||||
except Exception as exc:
|
||||
raise exc
|
||||
# if validate:
|
||||
# routes_d = domain_schema_dict(mod)
|
||||
# try:
|
||||
# ROUTE_SCHEMA.validate(routes_d)
|
||||
# except Exception as exc:
|
||||
# raise exc
|
||||
|
||||
|
|
|
@ -1,10 +1,25 @@
|
|||
import importlib
|
||||
import inspect
|
||||
import os
|
||||
import re
|
||||
|
||||
from typing import Coroutine, Dict, Iterator, List, Tuple
|
||||
from types import ModuleType, FunctionType
|
||||
|
||||
from schema import SchemaError
|
||||
|
||||
from starlette.applications import Starlette
|
||||
from starlette.routing import Router
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
from .lib.constants import API_SCHEMA_DICT, ROUTER_SCHEMA, VERBS
|
||||
from .half_route import HalfRoute
|
||||
from .lib.routes import gen_domain_routes, gen_schema_routes
|
||||
from .lib import acl
|
||||
from .lib.routes import JSONRoute
|
||||
from .lib.domain import MissingAclError, PathError, UnknownPathParameterType, \
|
||||
UndefinedRoute, UndefinedFunction, get_fct_name, route_decorator
|
||||
from .lib.domain_middleware import DomainMiddleware
|
||||
from .logging import logger
|
||||
|
||||
|
@ -13,7 +28,8 @@ class HalfDomain(Starlette):
|
|||
self.app = app
|
||||
|
||||
self.m_domain = importlib.import_module(domain)
|
||||
self.name = getattr('__name__', domain, domain)
|
||||
self.name = getattr(self.m_domain, '__name__', domain)
|
||||
self.id = getattr(self.m_domain, '__id__')
|
||||
|
||||
if not router:
|
||||
self.router = getattr('__router__', domain, '.routers')
|
||||
|
@ -44,7 +60,7 @@ class HalfDomain(Starlette):
|
|||
|
||||
logger.info('HalfDomain creation %s %s', domain, config)
|
||||
super().__init__(
|
||||
routes=gen_domain_routes(self.m_domain),
|
||||
routes=self.gen_domain_routes(),
|
||||
middleware=[
|
||||
(DomainMiddleware,
|
||||
{
|
||||
|
@ -80,29 +96,78 @@ class HalfDomain(Starlette):
|
|||
|
||||
# def schema(self):
|
||||
|
||||
def gen_routes(self):
|
||||
@staticmethod
|
||||
def gen_routes(m_router: ModuleType,
|
||||
verb: str,
|
||||
path: List[str],
|
||||
params: List[Dict]) -> Tuple[FunctionType, Dict]:
|
||||
"""
|
||||
Yields the Route objects for a domain
|
||||
Returns a tuple of the function associatied to the verb and path arguments,
|
||||
and the dictionary of it's acls
|
||||
|
||||
Parameters:
|
||||
m_domains: ModuleType
|
||||
- m_router (ModuleType): The module containing the function definition
|
||||
|
||||
- verb (str): The HTTP verb for the route (GET, POST, ...)
|
||||
|
||||
- path (List): The route path, as a list (each item being a level of
|
||||
deepness), from the lowest level (domain) to the highest
|
||||
|
||||
- params (Dict): The acl list of the following format :
|
||||
[{'acl': Function, 'args': {'required': [], 'optional': []}}]
|
||||
|
||||
|
||||
Returns:
|
||||
Generator(HalfRoute)
|
||||
"""
|
||||
"""
|
||||
yield HalfRoute('/',
|
||||
JSONRoute(self.schema(self.m_domain)),
|
||||
[{'acl': acl.public}],
|
||||
'GET'
|
||||
)
|
||||
"""
|
||||
|
||||
for path, method, m_router, fct, params in self.gen_router_routes(self.m_domain, []):
|
||||
yield HalfRoute(f'/{path}', fct, params, method)
|
||||
(Function, Dict): The destination function and the acl dictionary
|
||||
|
||||
"""
|
||||
if len(params) == 0:
|
||||
raise MissingAclError('[{}] {}'.format(verb, '/'.join(path)))
|
||||
|
||||
if len(path) == 0:
|
||||
logger.error('Empty path for [{%s}]', verb)
|
||||
raise PathError()
|
||||
|
||||
fct_name = get_fct_name(verb, path[-1])
|
||||
if hasattr(m_router, fct_name):
|
||||
fct = getattr(m_router, fct_name)
|
||||
else:
|
||||
raise UndefinedFunction('{}.{}'.format(m_router.__name__, fct_name or ''))
|
||||
|
||||
|
||||
def gen_router_routes(self, path: List[str]) -> \
|
||||
if not inspect.iscoroutinefunction(fct):
|
||||
return route_decorator(fct), params
|
||||
else:
|
||||
return acl.args_check(fct), params
|
||||
|
||||
# @staticmethod
|
||||
# def gen_routes(m_router):
|
||||
# """
|
||||
# Yields the Route objects for a domain
|
||||
|
||||
# Parameters:
|
||||
# m_domains: ModuleType
|
||||
|
||||
# Returns:
|
||||
# Generator(HalfRoute)
|
||||
# """
|
||||
# """
|
||||
# yield HalfRoute('/',
|
||||
# JSONRoute(self.schema(self.m_domain)),
|
||||
# [{'acl': acl.public}],
|
||||
# 'GET'
|
||||
# )
|
||||
# """
|
||||
|
||||
# for path, method, _, fct, params \
|
||||
# in HalfDomain.gen_router_routes(m_router, []):
|
||||
|
||||
# yield HalfRoute(f'/{path}', fct, params, method)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def gen_router_routes(m_router, path: List[str]) -> \
|
||||
Iterator[Tuple[str, str, ModuleType, Coroutine, List]]:
|
||||
"""
|
||||
Recursive generator that parses a router (or a subrouter)
|
||||
|
@ -121,7 +186,7 @@ class HalfDomain(Starlette):
|
|||
that decorates the endpoint function.
|
||||
"""
|
||||
|
||||
for subpath, params in read_router(m_router).items():
|
||||
for subpath, params in HalfDomain.read_router(m_router).items():
|
||||
path.append(subpath)
|
||||
|
||||
for verb in VERBS:
|
||||
|
@ -130,7 +195,7 @@ class HalfDomain(Starlette):
|
|||
yield ('/'.join(filter(lambda x: len(x) > 0, path)),
|
||||
verb,
|
||||
m_router,
|
||||
*gen_routes(m_router, verb, path, params[verb])
|
||||
*HalfDomain.gen_routes(m_router, verb, path, params[verb])
|
||||
)
|
||||
|
||||
for subroute in params.get('SUBROUTES', []):
|
||||
|
@ -147,7 +212,7 @@ class HalfDomain(Starlette):
|
|||
path.append(subroute)
|
||||
|
||||
try:
|
||||
yield from gen_router_routes(
|
||||
yield from HalfDomain.gen_router_routes(
|
||||
importlib.import_module(f'.{subroute}', m_router.__name__),
|
||||
path)
|
||||
|
||||
|
@ -160,6 +225,7 @@ class HalfDomain(Starlette):
|
|||
path.pop()
|
||||
|
||||
|
||||
@staticmethod
|
||||
def read_router(m_router: ModuleType) -> Dict:
|
||||
"""
|
||||
Reads a module and returns a router dict
|
||||
|
@ -214,3 +280,99 @@ class HalfDomain(Starlette):
|
|||
# TODO: Proper exception handling
|
||||
logger.error(m_path)
|
||||
raise exc
|
||||
|
||||
def gen_domain_routes(self):
|
||||
"""
|
||||
Yields the Route objects for a domain
|
||||
|
||||
Parameters:
|
||||
m_domains: ModuleType
|
||||
|
||||
Returns:
|
||||
Generator(HalfRoute)
|
||||
"""
|
||||
yield HalfRoute('/',
|
||||
JSONRoute(self.domain_schema()),
|
||||
[{'acl': acl.public}],
|
||||
'GET'
|
||||
)
|
||||
|
||||
for path, method, m_router, fct, params in HalfDomain.gen_router_routes(self.m_domain, []):
|
||||
yield HalfRoute(f'/{path}', fct, params, method)
|
||||
|
||||
def domain_schema_dict(self) -> Dict:
|
||||
""" gen_router_routes return values as a dict
|
||||
Parameters:
|
||||
|
||||
m_router (ModuleType): The domain routers' module
|
||||
|
||||
Returns:
|
||||
|
||||
Dict: Schema of dict is halfapi.lib.constants.DOMAIN_SCHEMA
|
||||
|
||||
@TODO: Should be a "router_schema_dict" function
|
||||
"""
|
||||
d_res = {}
|
||||
|
||||
for path, verb, m_router, fct, parameters in HalfDomain.gen_router_routes(self.m_router, []):
|
||||
if path not in d_res:
|
||||
d_res[path] = {}
|
||||
|
||||
if verb not in d_res[path]:
|
||||
d_res[path][verb] = {}
|
||||
|
||||
d_res[path][verb]['callable'] = f'{m_router.__name__}:{fct.__name__}'
|
||||
try:
|
||||
d_res[path][verb]['docs'] = yaml.safe_load(fct.__doc__)
|
||||
except AttributeError:
|
||||
logger.error(
|
||||
'Cannot read docstring from fct (fct=%s path=%s verb=%s', fct.__name__, path, verb)
|
||||
|
||||
d_res[path][verb]['acls'] = list(map(lambda elt: { **elt, 'acl': elt['acl'].__name__ },
|
||||
parameters))
|
||||
|
||||
return d_res
|
||||
|
||||
|
||||
def domain_schema(self) -> Dict:
|
||||
schema = { **API_SCHEMA_DICT }
|
||||
schema['domain'] = {
|
||||
'name': self.name,
|
||||
'id': self.id,
|
||||
'version': getattr(self.m_domain, '__version__', ''),
|
||||
'patch_release': getattr(self.m_domain, '__patch_release__', ''),
|
||||
'routers': self.m_router.__name__,
|
||||
'acls': tuple(getattr(self.m_acl, 'ACLS', ()))
|
||||
}
|
||||
schema['paths'] = self.domain_schema_dict()
|
||||
return schema
|
||||
|
||||
|
||||
# def domain_schema_list(m_router: ModuleType) -> List:
|
||||
# """ Schema as list, one row by route/acl
|
||||
# Parameters:
|
||||
#
|
||||
# m_router (ModuleType): The domain routers' module
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# List[Tuple]: (path, verb, callable, doc, acls)
|
||||
# """
|
||||
# res = []
|
||||
#
|
||||
# for path, verb, m_router, fct, parameters in gen_router_routes(m_router, []):
|
||||
# for params in parameters:
|
||||
# res.append((
|
||||
# path,
|
||||
# verb,
|
||||
# f'{m_router.__name__}:{fct.__name__}',
|
||||
# params.get('acl').__name__,
|
||||
# params.get('args', {}).get('required', []),
|
||||
# params.get('args', {}).get('optional', []),
|
||||
# params.get('out', [])
|
||||
# ))
|
||||
#
|
||||
# return res
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ from .lib.jwt_middleware import JWTAuthenticationBackend
|
|||
from .lib.responses import (ORJSONResponse, UnauthorizedResponse,
|
||||
NotFoundResponse, InternalServerErrorResponse, NotImplementedResponse,
|
||||
ServiceUnavailableResponse)
|
||||
from .lib.domain import domain_schema_dict, NoDomainsException, domain_schema
|
||||
from .lib.domain import NoDomainsException
|
||||
from .lib.routes import gen_schema_routes, JSONRoute
|
||||
from .lib.schemas import schema_json, get_acls
|
||||
from .logging import logger, config_logging
|
||||
|
@ -105,6 +105,9 @@ class HalfAPI:
|
|||
)
|
||||
|
||||
for key, domain in self.config.get('domain', {}).items():
|
||||
if not isinstance(domain, dict):
|
||||
continue
|
||||
|
||||
dom_name = domain.get('name', key)
|
||||
if not domain.get('enabled', False):
|
||||
continue
|
||||
|
@ -215,7 +218,7 @@ class HalfAPI:
|
|||
res = {
|
||||
domain: HalfDomain.acls_route(domain)
|
||||
for domain, domain_conf in self.config.get('domain', {}).items()
|
||||
if domain_conf.get('enabled', False)
|
||||
if isinstance(domain_conf, dict) and domain_conf.get('enabled', False)
|
||||
}
|
||||
|
||||
async def wrapped(req, *args, **kwargs):
|
||||
|
|
|
@ -18,7 +18,7 @@ from starlette.exceptions import HTTPException
|
|||
|
||||
from halfapi.lib import acl
|
||||
from halfapi.lib.responses import ORJSONResponse, ODSResponse
|
||||
from halfapi.lib.router import read_router
|
||||
# from halfapi.lib.router import read_router
|
||||
from halfapi.lib.constants import VERBS
|
||||
|
||||
from ..logging import logger
|
||||
|
@ -180,97 +180,97 @@ def gen_routes(m_router: ModuleType,
|
|||
return acl.args_check(fct), params
|
||||
|
||||
|
||||
def gen_router_routes(m_router: ModuleType, path: List[str]) -> \
|
||||
Iterator[Tuple[str, str, ModuleType, Coroutine, List]]:
|
||||
"""
|
||||
Recursive generator that parses a router (or a subrouter)
|
||||
and yields from gen_routes
|
||||
|
||||
Parameters:
|
||||
|
||||
- m_router (ModuleType): The currently treated router module
|
||||
- path (List[str]): The current path stack
|
||||
|
||||
Yields:
|
||||
|
||||
(str, str, ModuleType, Coroutine, List): A tuple containing the path, verb,
|
||||
router module, function reference and parameters of the route.
|
||||
Function and parameters are yielded from then gen_routes function,
|
||||
that decorates the endpoint function.
|
||||
"""
|
||||
|
||||
for subpath, params in read_router(m_router).items():
|
||||
path.append(subpath)
|
||||
|
||||
for verb in VERBS:
|
||||
if verb not in params:
|
||||
continue
|
||||
yield ('/'.join(filter(lambda x: len(x) > 0, path)),
|
||||
verb,
|
||||
m_router,
|
||||
*gen_routes(m_router, verb, path, params[verb])
|
||||
)
|
||||
|
||||
for subroute in params.get('SUBROUTES', []):
|
||||
#logger.debug('Processing subroute **%s** - %s', subroute, m_router.__name__)
|
||||
param_match = re.fullmatch('^([A-Z_]+)_([a-z]+)$', subroute)
|
||||
if param_match is not None:
|
||||
try:
|
||||
path.append('{{{}:{}}}'.format(
|
||||
param_match.groups()[0].lower(),
|
||||
param_match.groups()[1]))
|
||||
except AssertionError as exc:
|
||||
raise UnknownPathParameterType(subroute) from exc
|
||||
else:
|
||||
path.append(subroute)
|
||||
|
||||
try:
|
||||
yield from gen_router_routes(
|
||||
importlib.import_module(f'.{subroute}', m_router.__name__),
|
||||
path)
|
||||
|
||||
except ImportError as exc:
|
||||
logger.error('Failed to import subroute **{%s}**', subroute)
|
||||
raise exc
|
||||
|
||||
path.pop()
|
||||
|
||||
path.pop()
|
||||
# def gen_router_routes(m_router: ModuleType, path: List[str]) -> \
|
||||
# Iterator[Tuple[str, str, ModuleType, Coroutine, List]]:
|
||||
# """
|
||||
# Recursive generator that parses a router (or a subrouter)
|
||||
# and yields from gen_routes
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# - m_router (ModuleType): The currently treated router module
|
||||
# - path (List[str]): The current path stack
|
||||
#
|
||||
# Yields:
|
||||
#
|
||||
# (str, str, ModuleType, Coroutine, List): A tuple containing the path, verb,
|
||||
# router module, function reference and parameters of the route.
|
||||
# Function and parameters are yielded from then gen_routes function,
|
||||
# that decorates the endpoint function.
|
||||
# """
|
||||
#
|
||||
# for subpath, params in read_router(m_router).items():
|
||||
# path.append(subpath)
|
||||
#
|
||||
# for verb in VERBS:
|
||||
# if verb not in params:
|
||||
# continue
|
||||
# yield ('/'.join(filter(lambda x: len(x) > 0, path)),
|
||||
# verb,
|
||||
# m_router,
|
||||
# *gen_routes(m_router, verb, path, params[verb])
|
||||
# )
|
||||
#
|
||||
# for subroute in params.get('SUBROUTES', []):
|
||||
# #logger.debug('Processing subroute **%s** - %s', subroute, m_router.__name__)
|
||||
# param_match = re.fullmatch('^([A-Z_]+)_([a-z]+)$', subroute)
|
||||
# if param_match is not None:
|
||||
# try:
|
||||
# path.append('{{{}:{}}}'.format(
|
||||
# param_match.groups()[0].lower(),
|
||||
# param_match.groups()[1]))
|
||||
# except AssertionError as exc:
|
||||
# raise UnknownPathParameterType(subroute) from exc
|
||||
# else:
|
||||
# path.append(subroute)
|
||||
#
|
||||
# try:
|
||||
# yield from gen_router_routes(
|
||||
# importlib.import_module(f'.{subroute}', m_router.__name__),
|
||||
# path)
|
||||
#
|
||||
# except ImportError as exc:
|
||||
# logger.error('Failed to import subroute **{%s}**', subroute)
|
||||
# raise exc
|
||||
#
|
||||
# path.pop()
|
||||
#
|
||||
# path.pop()
|
||||
#
|
||||
|
||||
|
||||
|
||||
def domain_schema_dict(m_router: ModuleType) -> Dict:
|
||||
""" gen_router_routes return values as a dict
|
||||
Parameters:
|
||||
|
||||
m_router (ModuleType): The domain routers' module
|
||||
|
||||
Returns:
|
||||
|
||||
Dict: Schema of dict is halfapi.lib.constants.DOMAIN_SCHEMA
|
||||
|
||||
@TODO: Should be a "router_schema_dict" function
|
||||
"""
|
||||
d_res = {}
|
||||
|
||||
for path, verb, m_router, fct, parameters in gen_router_routes(m_router, []):
|
||||
if path not in d_res:
|
||||
d_res[path] = {}
|
||||
|
||||
if verb not in d_res[path]:
|
||||
d_res[path][verb] = {}
|
||||
|
||||
d_res[path][verb]['callable'] = f'{m_router.__name__}:{fct.__name__}'
|
||||
try:
|
||||
d_res[path][verb]['docs'] = yaml.safe_load(fct.__doc__)
|
||||
except AttributeError:
|
||||
logger.error(
|
||||
'Cannot read docstring from fct (fct=%s path=%s verb=%s', fct.__name__, path, verb)
|
||||
|
||||
d_res[path][verb]['acls'] = list(map(lambda elt: { **elt, 'acl': elt['acl'].__name__ },
|
||||
parameters))
|
||||
|
||||
return d_res
|
||||
# def domain_schema_dict(m_router: ModuleType) -> Dict:
|
||||
# """ gen_router_routes return values as a dict
|
||||
# Parameters:
|
||||
#
|
||||
# m_router (ModuleType): The domain routers' module
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Dict: Schema of dict is halfapi.lib.constants.DOMAIN_SCHEMA
|
||||
#
|
||||
# @TODO: Should be a "router_schema_dict" function
|
||||
# """
|
||||
# d_res = {}
|
||||
#
|
||||
# for path, verb, m_router, fct, parameters in gen_router_routes(m_router, []):
|
||||
# if path not in d_res:
|
||||
# d_res[path] = {}
|
||||
#
|
||||
# if verb not in d_res[path]:
|
||||
# d_res[path][verb] = {}
|
||||
#
|
||||
# d_res[path][verb]['callable'] = f'{m_router.__name__}:{fct.__name__}'
|
||||
# try:
|
||||
# d_res[path][verb]['docs'] = yaml.safe_load(fct.__doc__)
|
||||
# except AttributeError:
|
||||
# logger.error(
|
||||
# 'Cannot read docstring from fct (fct=%s path=%s verb=%s', fct.__name__, path, verb)
|
||||
#
|
||||
# d_res[path][verb]['acls'] = list(map(lambda elt: { **elt, 'acl': elt['acl'].__name__ },
|
||||
# parameters))
|
||||
#
|
||||
# return d_res
|
||||
|
||||
from .constants import API_SCHEMA_DICT
|
||||
def domain_schema(m_domain: ModuleType) -> Dict:
|
||||
|
|
|
@ -19,7 +19,7 @@ from types import ModuleType, FunctionType
|
|||
|
||||
import yaml
|
||||
|
||||
from .domain import gen_router_routes, domain_acls, route_decorator, domain_schema
|
||||
# from .domain import gen_router_routes, domain_acls, route_decorator, domain_schema
|
||||
from .responses import ORJSONResponse
|
||||
from .acl import args_check
|
||||
from ..half_route import HalfRoute
|
||||
|
|
|
@ -17,7 +17,7 @@ from types import ModuleType
|
|||
from starlette.schemas import SchemaGenerator
|
||||
|
||||
from .. import __version__
|
||||
from .domain import gen_router_routes, domain_schema_list
|
||||
# from .domain import gen_router_routes, domain_schema_list
|
||||
from ..logging import logger
|
||||
from .routes import gen_starlette_routes, api_routes, api_acls
|
||||
from .responses import ORJSONResponse
|
||||
|
|
|
@ -10,7 +10,7 @@ def test_run_noproject(cli_runner):
|
|||
print(result.stdout)
|
||||
assert result.exit_code == 0
|
||||
|
||||
result = cli_runner.invoke(cli, ['run'])
|
||||
result = cli_runner.invoke(cli, ['run', '--dryrun'])
|
||||
try:
|
||||
assert result.exit_code == 0
|
||||
except AssertionError as exc:
|
||||
|
|
|
@ -278,7 +278,7 @@ def application_debug(project_runner):
|
|||
'secret':'turlututu',
|
||||
'production':False,
|
||||
'domain': {
|
||||
'domain': {
|
||||
'dummy_domain': {
|
||||
'name': 'test_domain',
|
||||
'router': 'test_domain.routers',
|
||||
'enabled': True,
|
||||
|
|
|
@ -11,4 +11,5 @@ def test_halfapi_dummy_domain(dummy_domain):
|
|||
config = {}
|
||||
config['domain'] = {}
|
||||
config['domain'][dummy_domain['name']] = dummy_domain
|
||||
print(config)
|
||||
halfapi = HalfAPI(config)
|
||||
|
|
|
@ -8,8 +8,6 @@ from pprint import pprint
|
|||
from starlette.routing import Route
|
||||
from starlette.testclient import TestClient
|
||||
|
||||
from halfapi.lib.domain import gen_router_routes
|
||||
|
||||
def test_get_config_route(dummy_project, application_domain):
|
||||
c = TestClient(application_domain)
|
||||
r = c.get('/')
|
||||
|
|
|
@ -1,51 +1,51 @@
|
|||
#!/usr/bin/env python3
|
||||
import importlib
|
||||
from halfapi.lib.domain import VERBS, gen_routes, gen_router_routes, \
|
||||
MissingAclError, domain_schema_dict, domain_schema_list
|
||||
|
||||
from types import FunctionType
|
||||
|
||||
|
||||
def test_gen_router_routes():
|
||||
from .dummy_domain import routers
|
||||
for path, verb, m_router, fct, params in gen_router_routes(routers, ['dummy_domain']):
|
||||
assert isinstance(path, str)
|
||||
assert verb in VERBS
|
||||
assert len(params) > 0
|
||||
assert hasattr(fct, '__call__')
|
||||
assert len(m_router.__file__) > 0
|
||||
|
||||
|
||||
def test_gen_routes():
|
||||
from .dummy_domain.routers.abc.alphabet import TEST_uuid
|
||||
try:
|
||||
gen_routes(
|
||||
TEST_uuid,
|
||||
'get',
|
||||
['abc', 'alphabet', 'TEST_uuid', ''],
|
||||
[])
|
||||
except MissingAclError:
|
||||
assert True
|
||||
|
||||
fct, params = gen_routes(
|
||||
TEST_uuid,
|
||||
'get',
|
||||
['abc', 'alphabet', 'TEST_uuid', ''],
|
||||
TEST_uuid.ACLS['GET'])
|
||||
|
||||
assert isinstance(fct, FunctionType)
|
||||
assert isinstance(params, list)
|
||||
assert len(TEST_uuid.ACLS['GET']) == len(params)
|
||||
|
||||
def test_domain_schema_dict():
|
||||
from .dummy_domain import routers
|
||||
d_res = domain_schema_dict(routers)
|
||||
|
||||
assert isinstance(d_res, dict)
|
||||
|
||||
def test_domain_schema_list():
|
||||
from .dummy_domain import routers
|
||||
res = domain_schema_list(routers)
|
||||
|
||||
assert isinstance(res, list)
|
||||
assert len(res) > 0
|
||||
# #!/usr/bin/env python3
|
||||
# import importlib
|
||||
# from halfapi.lib.domain import VERBS, gen_routes, gen_router_routes, \
|
||||
# MissingAclError, domain_schema_dict, domain_schema_list
|
||||
#
|
||||
# from types import FunctionType
|
||||
#
|
||||
#
|
||||
# def test_gen_router_routes():
|
||||
# from .dummy_domain import routers
|
||||
# for path, verb, m_router, fct, params in gen_router_routes(routers, ['dummy_domain']):
|
||||
# assert isinstance(path, str)
|
||||
# assert verb in VERBS
|
||||
# assert len(params) > 0
|
||||
# assert hasattr(fct, '__call__')
|
||||
# assert len(m_router.__file__) > 0
|
||||
#
|
||||
#
|
||||
# def test_gen_routes():
|
||||
# from .dummy_domain.routers.abc.alphabet import TEST_uuid
|
||||
# try:
|
||||
# gen_routes(
|
||||
# TEST_uuid,
|
||||
# 'get',
|
||||
# ['abc', 'alphabet', 'TEST_uuid', ''],
|
||||
# [])
|
||||
# except MissingAclError:
|
||||
# assert True
|
||||
#
|
||||
# fct, params = gen_routes(
|
||||
# TEST_uuid,
|
||||
# 'get',
|
||||
# ['abc', 'alphabet', 'TEST_uuid', ''],
|
||||
# TEST_uuid.ACLS['GET'])
|
||||
#
|
||||
# assert isinstance(fct, FunctionType)
|
||||
# assert isinstance(params, list)
|
||||
# assert len(TEST_uuid.ACLS['GET']) == len(params)
|
||||
#
|
||||
# def test_domain_schema_dict():
|
||||
# from .dummy_domain import routers
|
||||
# d_res = domain_schema_dict(routers)
|
||||
#
|
||||
# assert isinstance(d_res, dict)
|
||||
#
|
||||
# def test_domain_schema_list():
|
||||
# from .dummy_domain import routers
|
||||
# res = domain_schema_list(routers)
|
||||
#
|
||||
# assert isinstance(res, list)
|
||||
# assert len(res) > 0
|
||||
|
|
|
@ -1,57 +1,57 @@
|
|||
import os
|
||||
import pytest
|
||||
from schema import SchemaError
|
||||
from halfapi.lib.router import read_router
|
||||
from halfapi.lib.constants import ROUTER_SCHEMA, ROUTER_ACLS_SCHEMA
|
||||
|
||||
def test_read_router_routers():
|
||||
from .dummy_domain import routers
|
||||
|
||||
router_d = read_router(routers)
|
||||
assert '' in router_d
|
||||
assert 'SUBROUTES' in router_d['']
|
||||
assert isinstance(router_d['']['SUBROUTES'], list)
|
||||
|
||||
for elt in os.scandir(routers.__path__[0]):
|
||||
if elt.is_dir():
|
||||
assert elt.name in router_d['']['SUBROUTES']
|
||||
|
||||
def test_read_router_abc():
|
||||
from .dummy_domain.routers import abc
|
||||
router_d = read_router(abc)
|
||||
|
||||
assert '' in router_d
|
||||
assert 'SUBROUTES' in router_d['']
|
||||
assert isinstance(router_d['']['SUBROUTES'], list)
|
||||
|
||||
def test_read_router_alphabet():
|
||||
from .dummy_domain.routers.abc import alphabet
|
||||
router_d = read_router(alphabet)
|
||||
|
||||
assert '' in router_d
|
||||
assert 'SUBROUTES' in router_d['']
|
||||
assert isinstance(router_d['']['SUBROUTES'], list)
|
||||
|
||||
ROUTER_SCHEMA.validate(router_d)
|
||||
|
||||
with pytest.raises(SchemaError):
|
||||
""" Test that we cannot specify wrong method in ROUTES or ACLS
|
||||
|
||||
TODO: Write more errors
|
||||
"""
|
||||
router_d['']['TEG'] = {}
|
||||
ROUTER_SCHEMA.validate(router_d)
|
||||
|
||||
def test_read_router_TEST():
|
||||
from .dummy_domain.routers.abc.alphabet import TEST_uuid
|
||||
router_d = read_router(TEST_uuid)
|
||||
|
||||
print(router_d)
|
||||
assert '' in router_d
|
||||
assert 'SUBROUTES' in router_d['']
|
||||
assert isinstance(router_d['']['GET'], list)
|
||||
assert isinstance(router_d['']['POST'], list)
|
||||
assert isinstance(router_d['']['PATCH'], list)
|
||||
assert isinstance(router_d['']['PUT'], list)
|
||||
|
||||
|
||||
# import os
|
||||
# import pytest
|
||||
# from schema import SchemaError
|
||||
# from halfapi.lib.router import read_router
|
||||
# from halfapi.lib.constants import ROUTER_SCHEMA, ROUTER_ACLS_SCHEMA
|
||||
#
|
||||
# def test_read_router_routers():
|
||||
# from .dummy_domain import routers
|
||||
#
|
||||
# router_d = read_router(routers)
|
||||
# assert '' in router_d
|
||||
# assert 'SUBROUTES' in router_d['']
|
||||
# assert isinstance(router_d['']['SUBROUTES'], list)
|
||||
#
|
||||
# for elt in os.scandir(routers.__path__[0]):
|
||||
# if elt.is_dir():
|
||||
# assert elt.name in router_d['']['SUBROUTES']
|
||||
#
|
||||
# def test_read_router_abc():
|
||||
# from .dummy_domain.routers import abc
|
||||
# router_d = read_router(abc)
|
||||
#
|
||||
# assert '' in router_d
|
||||
# assert 'SUBROUTES' in router_d['']
|
||||
# assert isinstance(router_d['']['SUBROUTES'], list)
|
||||
#
|
||||
# def test_read_router_alphabet():
|
||||
# from .dummy_domain.routers.abc import alphabet
|
||||
# router_d = read_router(alphabet)
|
||||
#
|
||||
# assert '' in router_d
|
||||
# assert 'SUBROUTES' in router_d['']
|
||||
# assert isinstance(router_d['']['SUBROUTES'], list)
|
||||
#
|
||||
# ROUTER_SCHEMA.validate(router_d)
|
||||
#
|
||||
# with pytest.raises(SchemaError):
|
||||
# """ Test that we cannot specify wrong method in ROUTES or ACLS
|
||||
#
|
||||
# TODO: Write more errors
|
||||
# """
|
||||
# router_d['']['TEG'] = {}
|
||||
# ROUTER_SCHEMA.validate(router_d)
|
||||
#
|
||||
# def test_read_router_TEST():
|
||||
# from .dummy_domain.routers.abc.alphabet import TEST_uuid
|
||||
# router_d = read_router(TEST_uuid)
|
||||
#
|
||||
# print(router_d)
|
||||
# assert '' in router_d
|
||||
# assert 'SUBROUTES' in router_d['']
|
||||
# assert isinstance(router_d['']['GET'], list)
|
||||
# assert isinstance(router_d['']['POST'], list)
|
||||
# assert isinstance(router_d['']['PATCH'], list)
|
||||
# assert isinstance(router_d['']['PUT'], list)
|
||||
#
|
||||
#
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
from starlette.routing import Route
|
||||
from halfapi.lib.routes import gen_starlette_routes, gen_router_routes
|
||||
|
||||
def test_gen_starlette_routes():
|
||||
from .dummy_domain import routers
|
||||
for route in gen_starlette_routes({
|
||||
'dummy_domain': routers }):
|
||||
|
||||
assert isinstance(route, Route)
|
||||
|
||||
import pytest
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_api_routes():
|
||||
from . import dummy_domain
|
||||
d_res, d_acls = api_routes(dummy_domain)
|
||||
assert isinstance(d_res, dict)
|
||||
assert isinstance(d_acls, dict)
|
||||
|
||||
yielded = False
|
||||
|
||||
for path, verb, m_router, fct, params in gen_router_routes(dummy_domain, []):
|
||||
if not yielded:
|
||||
yielded = True
|
||||
|
||||
assert path in d_res
|
||||
assert verb in d_res[path]
|
||||
assert 'docs' in d_res[path][verb]
|
||||
assert 'acls' in d_res[path][verb]
|
||||
assert isinstance(d_res[path][verb]['docs'], dict)
|
||||
assert isinstance(d_res[path][verb]['acls'], list)
|
||||
assert len(d_res[path][verb]['acls']) == len(params)
|
||||
|
||||
assert yielded is True
|
||||
# from starlette.routing import Route
|
||||
# from halfapi.lib.routes import gen_starlette_routes, gen_router_routes
|
||||
#
|
||||
# def test_gen_starlette_routes():
|
||||
# from .dummy_domain import routers
|
||||
# for route in gen_starlette_routes({
|
||||
# 'dummy_domain': routers }):
|
||||
#
|
||||
# assert isinstance(route, Route)
|
||||
#
|
||||
# import pytest
|
||||
#
|
||||
# @pytest.mark.skip
|
||||
# def test_api_routes():
|
||||
# from . import dummy_domain
|
||||
# d_res, d_acls = api_routes(dummy_domain)
|
||||
# assert isinstance(d_res, dict)
|
||||
# assert isinstance(d_acls, dict)
|
||||
#
|
||||
# yielded = False
|
||||
#
|
||||
# for path, verb, m_router, fct, params in gen_router_routes(dummy_domain, []):
|
||||
# if not yielded:
|
||||
# yielded = True
|
||||
#
|
||||
# assert path in d_res
|
||||
# assert verb in d_res[path]
|
||||
# assert 'docs' in d_res[path][verb]
|
||||
# assert 'acls' in d_res[path][verb]
|
||||
# assert isinstance(d_res[path][verb]['docs'], dict)
|
||||
# assert isinstance(d_res[path][verb]['acls'], list)
|
||||
# assert len(d_res[path][verb]['acls']) == len(params)
|
||||
#
|
||||
# assert yielded is True
|
||||
|
|
Loading…
Reference in New Issue