[lib.schemas] router schema update
This commit is contained in:
parent
238bd99bd3
commit
1ccfa0d10e
@ -99,3 +99,10 @@ def args_check(fct):
|
|||||||
return await fct(req, *args, **kwargs)
|
return await fct(req, *args, **kwargs)
|
||||||
|
|
||||||
return caller
|
return caller
|
||||||
|
|
||||||
|
# ACLS list for doc and priorities
|
||||||
|
# Write your own constant in your domain or import this one
|
||||||
|
ACLS = (
|
||||||
|
('private', public.__doc__, 0),
|
||||||
|
('public', public.__doc__, 999)
|
||||||
|
)
|
||||||
|
@ -1,17 +1,28 @@
|
|||||||
import re
|
import re
|
||||||
from schema import Schema, Optional
|
from schema import Schema, Optional, Or
|
||||||
from .. import __version__
|
from .. import __version__
|
||||||
|
|
||||||
VERBS = ('GET', 'POST', 'PUT', 'PATCH', 'DELETE')
|
VERBS = ('GET', 'POST', 'PUT', 'PATCH', 'DELETE')
|
||||||
|
|
||||||
|
ITERABLE_STR = Or([ str ], { str }, ( str ))
|
||||||
|
|
||||||
ACLS_SCHEMA = Schema([{
|
ACLS_SCHEMA = Schema([{
|
||||||
'acl': str,
|
'acl': str,
|
||||||
Optional('args'): {
|
Optional('args'): {
|
||||||
Optional('required'): [ str ],
|
Optional('required'): ITERABLE_STR,
|
||||||
Optional('optional'): [ str ]
|
Optional('optional'): ITERABLE_STR
|
||||||
},
|
},
|
||||||
Optional('out'): [ str ]
|
Optional('out'): ITERABLE_STR
|
||||||
}])
|
}])
|
||||||
|
ROUTER_ACLS_SCHEMA = Schema([{
|
||||||
|
'acl': lambda n: callable(n),
|
||||||
|
Optional('args'): {
|
||||||
|
Optional('required'): ITERABLE_STR,
|
||||||
|
Optional('optional'): ITERABLE_STR
|
||||||
|
},
|
||||||
|
Optional('out'): ITERABLE_STR
|
||||||
|
}])
|
||||||
|
|
||||||
|
|
||||||
is_callable_dotted_notation = lambda x: re.match(
|
is_callable_dotted_notation = lambda x: re.match(
|
||||||
r'^(([a-zA-Z_])+\.?)*:[a-zA-Z_]+$', 'ab_c.TEST:get')
|
r'^(([a-zA-Z_])+\.?)*:[a-zA-Z_]+$', 'ab_c.TEST:get')
|
||||||
@ -48,3 +59,11 @@ API_SCHEMA = Schema({
|
|||||||
'domain': DOMAIN_SCHEMA,
|
'domain': DOMAIN_SCHEMA,
|
||||||
'paths': ROUTE_SCHEMA
|
'paths': ROUTE_SCHEMA
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ROUTER_SCHEMA = Schema({
|
||||||
|
Or('', str): {
|
||||||
|
# Optional('GET'): [],#ACLS_SCHEMA,
|
||||||
|
Optional(Or(*VERBS)): ROUTER_ACLS_SCHEMA,
|
||||||
|
Optional('SUBROUTES'): [Optional(str)]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
@ -1,14 +1,27 @@
|
|||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
from halfapi.lib.constants import VERBS
|
from schema import SchemaError
|
||||||
|
from .constants import VERBS, ROUTER_SCHEMA
|
||||||
|
from ..logging import logger
|
||||||
|
|
||||||
def read_router(m_router: ModuleType) -> Dict:
|
def read_router(m_router: ModuleType) -> Dict:
|
||||||
"""
|
"""
|
||||||
Reads a module and returns a router dict
|
Reads a module and returns a router dict
|
||||||
"""
|
|
||||||
|
|
||||||
|
If the module has a "ROUTES" constant, it just returns this constant,
|
||||||
|
Else, if the module has an "ACLS" constant, it builds the accurate dict
|
||||||
|
|
||||||
|
TODO: May be another thing, may be not a part of halfAPI
|
||||||
|
|
||||||
|
"""
|
||||||
|
m_path = None
|
||||||
|
|
||||||
|
try:
|
||||||
if not hasattr(m_router, 'ROUTES'):
|
if not hasattr(m_router, 'ROUTES'):
|
||||||
routes = {'':{}}
|
routes = {'':{}}
|
||||||
acls = getattr(m_router, 'ACLS') if hasattr(m_router, 'ACLS') else None
|
acls = getattr(m_router, 'ACLS') if hasattr(m_router, 'ACLS') else None
|
||||||
@ -16,6 +29,7 @@ def read_router(m_router: ModuleType) -> Dict:
|
|||||||
if acls is not None:
|
if acls is not None:
|
||||||
for verb in VERBS:
|
for verb in VERBS:
|
||||||
if not hasattr(m_router, verb.lower()):
|
if not hasattr(m_router, verb.lower()):
|
||||||
|
# verb in function names are lowercase
|
||||||
continue
|
continue
|
||||||
|
|
||||||
""" There is a "verb" route in the router
|
""" There is a "verb" route in the router
|
||||||
@ -41,4 +55,17 @@ def read_router(m_router: ModuleType) -> Dict:
|
|||||||
else:
|
else:
|
||||||
routes = getattr(m_router, 'ROUTES')
|
routes = getattr(m_router, 'ROUTES')
|
||||||
|
|
||||||
|
try:
|
||||||
|
ROUTER_SCHEMA.validate(routes)
|
||||||
|
except SchemaError as exc:
|
||||||
|
logger.error(routes)
|
||||||
|
raise exc
|
||||||
|
|
||||||
return routes
|
return routes
|
||||||
|
except ImportError as exc:
|
||||||
|
# TODO: Proper exception handling
|
||||||
|
raise exc
|
||||||
|
except FileNotFoundError as exc:
|
||||||
|
# TODO: Proper exception handling
|
||||||
|
logger.error(m_path)
|
||||||
|
raise exc
|
||||||
|
@ -48,8 +48,6 @@ def JSONRoute(data: Any) -> Coroutine:
|
|||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def gen_domain_routes(m_domain: ModuleType):
|
def gen_domain_routes(m_domain: ModuleType):
|
||||||
"""
|
"""
|
||||||
Yields the Route objects for a domain
|
Yields the Route objects for a domain
|
||||||
|
@ -16,7 +16,7 @@ ROUTES = {
|
|||||||
'acl': acl.public,
|
'acl': acl.public,
|
||||||
'args': {
|
'args': {
|
||||||
'required': {'foo', 'bar'},
|
'required': {'foo', 'bar'},
|
||||||
'optional': {}
|
'optional': set()
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user