[conf] halfapi becomes configurable only by environment variables (for one domain)

This commit is contained in:
Maxime Alves LIRMM 2021-09-03 13:17:06 +02:00
parent 0470f9fa89
commit cdd2214043
6 changed files with 75 additions and 53 deletions

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
__version__ = '0.5.9' __version__ = '0.5.10'
def version(): def version():
return f'HalfAPI version:{__version__}' return f'HalfAPI version:{__version__}'

View File

@ -7,7 +7,12 @@ not loaded otherwise.
""" """
# builtins # builtins
import click import click
from ..conf import IS_PROJECT
IS_PROJECT = True
try:
from ..conf import DOMAINS
except Exception:
IS_PROJECT = False
@click.group(invoke_without_command=True) @click.group(invoke_without_command=True)
@click.option('--version', is_flag=True) @click.option('--version', is_flag=True)

View File

@ -21,12 +21,12 @@ logger = logging.getLogger('halfapi')
# domain create # # domain create #
################# #################
def create_domain(domain_name: str, module_path: str): def create_domain(domain_name: str, module_path: str):
logger.info('Will add **%s** (%s) to current halfAPI project', logger.info('Will add **%s** (%s) to current halfAPI project',
domain_name, module_path) domain_name, module_path)
if domain_name in DOMAINSDICT(): #if domain_name in DOMAINSDICT():
logger.warning('Domain **%s** is already in project') # logger.warning('Domain **%s** is already in project', domain_name)
sys.exit(1) # sys.exit(1)
if not config.has_section('domains'): if not config.has_section('domains'):
config.add_section('domains') config.add_section('domains')
@ -54,7 +54,7 @@ def list_api_routes():
""" """
Echoes the list of all active domains. Echoes the list of all active domains.
""" """
click.echo('# API Routes') click.echo('# API Routes')
for domain, m_dom in DOMAINSDICT().items(): for domain, m_dom in DOMAINSDICT().items():
list_routes(domain, m_dom) list_routes(domain, m_dom)

View File

@ -21,7 +21,7 @@ logger = logging.getLogger('halfapi')
TMPL_HALFAPI_ETC = """[project] TMPL_HALFAPI_ETC = """[project]
name = {project} name = {project}
host = 127.0.0.1 host = 127.0.0.1
port = 8000 port = 8000
secret = /path/to/secret_file secret = /path/to/secret_file
production = False production = False

View File

@ -9,14 +9,14 @@ It uses the following environment variables :
It defines the following globals : It defines the following globals :
- PROJECT_NAME (str) - PROJECT_NAME (str) - HALFAPI_PROJECT_NAME
- DOMAINSDICT ({domain_name: domain_module}) - DOMAINSDICT ({domain_name: domain_module}) - HALFAPI_DOMAIN_NAME / HALFAPI_DOMAIN_MODULE
- PRODUCTION (bool) - PRODUCTION (bool) - HALFAPI_PRODUCTION
- LOGLEVEL (string) - LOGLEVEL (string) - HALFAPI_LOGLEVEL
- BASE_DIR (str) - BASE_DIR (str) - HALFAPI_BASE_DIR
- HOST (str) - HOST (str) - HALFAPI_HOST
- PORT (int) - PORT (int) - HALFAPI_PORT
- CONF_DIR (str) - CONF_DIR (str) - HALFAPI_CONF_DIR
- IS_PROJECT (bool) - IS_PROJECT (bool)
- config (ConfigParser) - config (ConfigParser)
@ -43,9 +43,9 @@ import importlib
from .lib.domain import d_domains from .lib.domain import d_domains
logger = logging.getLogger('halfapi') logger = logging.getLogger('uvicorn.asgi')
PROJECT_NAME = os.path.basename(os.getcwd()) PROJECT_NAME = environ.get('HALFAPI_PROJECT_NAME') or os.path.basename(os.getcwd())
DOMAINSDICT = lambda: {} DOMAINSDICT = lambda: {}
DOMAINS = {} DOMAINS = {}
PRODUCTION = False PRODUCTION = False
@ -115,49 +115,60 @@ def read_config():
CONFIG = {} CONFIG = {}
IS_PROJECT = False read_config()
if is_project():
read_config()
IS_PROJECT = True IS_PROJECT = True
PROJECT_NAME = config.get('project', 'name', fallback=PROJECT_NAME) PROJECT_NAME = config.get('project', 'name', fallback=PROJECT_NAME)
if len(PROJECT_NAME) == 0: if len(PROJECT_NAME) == 0:
raise Exception('Need a project name as argument') raise Exception('Need a project name as argument')
DOMAINSDICT = lambda: d_domains(config) DOMAINSDICT = lambda: d_domains(config)
DOMAINS = DOMAINSDICT() DOMAINS = DOMAINSDICT()
HOST = config.get('project', 'host') if len(DOMAINS) == 0:
PORT = config.getint('project', 'port') logger.info('Domain-less instance')
try: HOST = config.get('project', 'host', fallback=environ.get('HALFAPI_HOST', '127.0.0.1'))
with open(config.get('project', 'secret')) as secret_file: PORT = config.getint('project', 'port', fallback=environ.get('HALFAPI_PORT', '3000'))
SECRET = secret_file.read().strip()
CONFIG['secret'] = SECRET.strip()
# Set the secret so we can use it in domains
os.environ['HALFAPI_SECRET'] = SECRET
except FileNotFoundError as exc:
logger.error('There is no file like %s : %s',
config.get('project', 'secret'), exc)
PRODUCTION = config.getboolean('project', 'production') or False try:
os.environ['HALFAPI_PROD'] = str(PRODUCTION) with open(config.get('project', 'secret')) as secret_file:
SECRET = secret_file.read().strip()
CONFIG['secret'] = SECRET.strip()
# Set the secret so we can use it in domains
environ['HALFAPI_SECRET'] = SECRET
except FileNotFoundError as exc:
if 'HALFAPI_SECRET' in environ:
SECRET = environ.get('HALFAPI_SECRET')
CONFIG['secret'] = SECRET.strip()
# Set the secret so we can use it in domains
environ['HALFAPI_SECRET'] = SECRET
LOGLEVEL = config.get('project', 'loglevel').lower() or 'info' logger.error('There is no file like %s : %s',
config.get('project', 'secret'), exc)
BASE_DIR = config.get('project', 'base_dir', fallback='.') #os.getcwd()) PRODUCTION = config.getboolean('project', 'production',
fallback=environ.get('HALFAPI_PROD', False))
CONFIG = { os.environ['HALFAPI_PROD'] = str(PRODUCTION)
'project_name': PROJECT_NAME,
'production': PRODUCTION,
'secret': SECRET,
'domains': DOMAINS,
'domain_config': {}
}
for domain in DOMAINS: LOGLEVEL = config.get('project', 'loglevel',
if domain not in config.sections(): fallback=environ.get('HALFAPI_LOGLEVEL', 'info')).lower()
continue
CONFIG['domain_config'][domain] = dict(config.items(domain)) BASE_DIR = config.get('project', 'base_dir',
fallback=environ.get('HALFAPI_BASE_DIR', '.'))
CONFIG = {
'project_name': PROJECT_NAME,
'production': PRODUCTION,
'secret': SECRET,
'domains': DOMAINS,
'domain_config': {}
}
for domain in DOMAINS:
if domain not in config.sections():
continue
CONFIG['domain_config'][domain] = dict(config.items(domain))

View File

@ -3,6 +3,7 @@
lib/domain.py The domain-scoped utility functions lib/domain.py The domain-scoped utility functions
""" """
import os
import re import re
import sys import sys
import importlib import importlib
@ -229,6 +230,11 @@ def d_domains(config) -> Dict[str, ModuleType]:
dict[str, ModuleType] dict[str, ModuleType]
""" """
if os.environ.get('HALFAPI_DOMAIN_NAME') and os.environ.get('HALFAPI_DOMAIN_MODULE', '.routers'):
config['domains'] = {
os.environ.get('HALFAPI_DOMAIN_NAME'): os.environ.get('HALFAPI_DOMAIN_MODULE')
}
if not 'domains' in config: if not 'domains' in config:
return {} return {}