handle HALFAPI_DOMAIN_MODULE environment variable

This commit is contained in:
maxime 2022-06-23 07:21:49 +02:00
parent b17ce623f4
commit f68b7e59b8
3 changed files with 68 additions and 23 deletions

View File

@ -98,12 +98,17 @@ PROJECT_NAME = CONFIG.get('project_name',
if environ.get('HALFAPI_DOMAIN_NAME'): if environ.get('HALFAPI_DOMAIN_NAME'):
DOMAIN_NAME = environ.get('HALFAPI_DOMAIN_NAME') DOMAIN_NAME = environ.get('HALFAPI_DOMAIN_NAME')
CONFIG['domain'] = {} CONFIG['domain'] = {}
CONFIG['domain'][DOMAIN_NAME] = { CONFIG['domain'][DOMAIN_NAME] = {
'enabled': True, 'enabled': True,
'name': DOMAIN_NAME, 'name': DOMAIN_NAME,
'prefix': False 'prefix': False
} }
if environ.get('HALFAPI_DOMAIN_MODULE'):
dom_module = environ.get('HALFAPI_DOMAIN_MODULE')
CONFIG['domain'][DOMAIN_NAME]['module'] = dom_module
if len(CONFIG.get('domain', {}).keys()) == 0: if len(CONFIG.get('domain', {}).keys()) == 0:
logger.info('No domains') logger.info('No domains')

View File

@ -27,7 +27,7 @@ from .lib.domain_middleware import DomainMiddleware
from .logging import logger from .logging import logger
class HalfDomain(Starlette): class HalfDomain(Starlette):
def __init__(self, domain, router=None, acl=None, app=None): def __init__(self, domain, module=None, router=None, acl=None, app=None):
""" """
Parameters: Parameters:
domain (str): Module name (should be importable) domain (str): Module name (should be importable)
@ -37,7 +37,7 @@ class HalfDomain(Starlette):
""" """
self.app = app self.app = app
self.m_domain = importlib.import_module(domain) self.m_domain = importlib.import_module(domain) if module is None else module
self.name = getattr(self.m_domain, '__name__', domain) self.name = getattr(self.m_domain, '__name__', domain)
self.id = getattr(self.m_domain, '__id__') self.id = getattr(self.m_domain, '__id__')
self.version = getattr(self.m_domain, '__version__', '0.0.0') self.version = getattr(self.m_domain, '__version__', '0.0.0')
@ -47,13 +47,17 @@ class HalfDomain(Starlette):
self.deps = getattr(self.m_domain, '__deps__', tuple()) self.deps = getattr(self.m_domain, '__deps__', tuple())
if not router: if not router:
self.router = getattr('__router__', domain, '.routers') self.router = getattr(domain, '__router__', '.routers')
else: else:
self.router = router self.router = router
self.m_router = importlib.import_module(self.router, domain) self.m_router = None
try:
self.m_router = importlib.import_module(self.router, self.m_domain.__package__)
except AttributeError:
raise Exception('no router module')
self.m_acl = HalfDomain.m_acl(domain, acl) self.m_acl = HalfDomain.m_acl(self.m_domain, acl)
self.config = { **app.config } self.config = { **app.config }
@ -86,31 +90,37 @@ class HalfDomain(Starlette):
) )
@staticmethod @staticmethod
def m_acl(domain, acl=None): def m_acl(module, acl=None):
""" Returns the imported acl module for the domain """ Returns the imported acl module for the domain module
""" """
if (not acl): if (not acl):
acl = getattr('__acl__', domain, '.acl') acl = getattr(module, '__acl__', '.acl')
return importlib.import_module(acl, domain) return importlib.import_module(acl, module.__package__)
@staticmethod @staticmethod
def acls(domain, acl=None): def acls(domain, module=None, acl=None):
""" Returns the ACLS constant for the given domain """ Returns the ACLS constant for the given domain
""" """
m_acl = HalfDomain.m_acl(domain, acl) if not module:
module = importlib.import_module(domain)
m_acl = HalfDomain.m_acl(module, acl)
try: try:
return getattr(m_acl, 'ACLS') return getattr(m_acl, 'ACLS')
except AttributeError: except AttributeError:
raise Exception(f'Missing acl.ACLS constant in {domain} module') raise Exception(f'Missing acl.ACLS constant in {domain} module')
@staticmethod @staticmethod
def acls_route(domain, acl=None): def acls_route(domain, module=None, acl=None):
d_res = {} d_res = {}
m_acl = HalfDomain.m_acl(domain, acl) if module is None:
module = importlib.import_module(domain)
for acl_name, doc, order in HalfDomain.acls(domain, acl): m_acl = HalfDomain.m_acl(module, acl)
for acl_name, doc, order in HalfDomain.acls(domain, acl=acl):
fct = getattr(m_acl, acl_name) fct = getattr(m_acl, acl_name)
d_res[acl_name] = { d_res[acl_name] = {
'callable': fct, 'callable': fct,

View File

@ -122,7 +122,12 @@ class HalfAPI(Starlette):
domain_key = domain.get('name', key) domain_key = domain.get('name', key)
self.add_domain(domain_key, domain.get('router'), domain.get('acl'), path) self.add_domain(
domain_key,
domain.get('module'),
domain.get('router'),
domain.get('acl'),
path)
schemas.append(self.__domains[domain_key].schema()) schemas.append(self.__domains[domain_key].schema())
@ -209,7 +214,10 @@ class HalfAPI(Starlette):
def acls_route(self): def acls_route(self):
res = { res = {
domain: HalfDomain.acls_route(domain, domain_conf.get('acl')) domain: HalfDomain.acls_route(
domain,
module=domain_conf.get('module'),
acl=domain_conf.get('acl'))
for domain, domain_conf in self.config.get('domain', {}).items() for domain, domain_conf in self.config.get('domain', {}).items()
if isinstance(domain_conf, dict) and domain_conf.get('enabled', False) if isinstance(domain_conf, dict) and domain_conf.get('enabled', False)
} }
@ -237,17 +245,39 @@ class HalfAPI(Starlette):
def domains(self): def domains(self):
return self.__domains return self.__domains
def add_domain(self, name, router=None, acl=None, path='/', config=None): def add_domain(self, name, module=None, router=None, acl=None, path='/', config=None):
# logger.debug('HalfApi.add_domain %s %s %s %s %s',
# name,
# module,
# router,
# acl,
# path,
# config)
if config: if config:
self.config['domain'][name] = config self.config['domain'][name] = config
if not module:
module = name
try:
self.__domains[name] = HalfDomain( self.__domains[name] = HalfDomain(
name, name,
router, module=importlib.import_module(module),
acl, router=router,
self acl=acl,
app=self
) )
except ImportError as exc:
print(
'Cannot instantiate HalfDomain {} with module {}'.format(
name,
module
))
raise exc
self.mount(path, self.__domains[name]) self.mount(path, self.__domains[name])
return self.__domains[name] return self.__domains[name]