diff --git a/halfapi/__init__.py b/halfapi/__init__.py index c7e11fc..aa84553 100644 --- a/halfapi/__init__.py +++ b/halfapi/__init__.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -__version__ = '0.5.9' +__version__ = '0.5.10' def version(): return f'HalfAPI version:{__version__}' diff --git a/halfapi/cli/cli.py b/halfapi/cli/cli.py index 777d5b2..28c4189 100644 --- a/halfapi/cli/cli.py +++ b/halfapi/cli/cli.py @@ -7,7 +7,12 @@ not loaded otherwise. """ # builtins 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.option('--version', is_flag=True) diff --git a/halfapi/cli/domain.py b/halfapi/cli/domain.py index e7abc06..7a7e9d6 100644 --- a/halfapi/cli/domain.py +++ b/halfapi/cli/domain.py @@ -21,12 +21,12 @@ logger = logging.getLogger('halfapi') # domain create # ################# 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) - if domain_name in DOMAINSDICT(): - logger.warning('Domain **%s** is already in project') - sys.exit(1) + #if domain_name in DOMAINSDICT(): + # logger.warning('Domain **%s** is already in project', domain_name) + # sys.exit(1) if not config.has_section('domains'): config.add_section('domains') @@ -54,7 +54,7 @@ def list_api_routes(): """ Echoes the list of all active domains. """ - + click.echo('# API Routes') for domain, m_dom in DOMAINSDICT().items(): list_routes(domain, m_dom) diff --git a/halfapi/cli/init.py b/halfapi/cli/init.py index c117ff2..6ed16f9 100644 --- a/halfapi/cli/init.py +++ b/halfapi/cli/init.py @@ -21,7 +21,7 @@ logger = logging.getLogger('halfapi') TMPL_HALFAPI_ETC = """[project] name = {project} -host = 127.0.0.1 +host = 127.0.0.1 port = 8000 secret = /path/to/secret_file production = False diff --git a/halfapi/conf.py b/halfapi/conf.py index 69d3527..8ae6706 100644 --- a/halfapi/conf.py +++ b/halfapi/conf.py @@ -9,14 +9,14 @@ It uses the following environment variables : It defines the following globals : - - PROJECT_NAME (str) - - DOMAINSDICT ({domain_name: domain_module}) - - PRODUCTION (bool) - - LOGLEVEL (string) - - BASE_DIR (str) - - HOST (str) - - PORT (int) - - CONF_DIR (str) + - PROJECT_NAME (str) - HALFAPI_PROJECT_NAME + - DOMAINSDICT ({domain_name: domain_module}) - HALFAPI_DOMAIN_NAME / HALFAPI_DOMAIN_MODULE + - PRODUCTION (bool) - HALFAPI_PRODUCTION + - LOGLEVEL (string) - HALFAPI_LOGLEVEL + - BASE_DIR (str) - HALFAPI_BASE_DIR + - HOST (str) - HALFAPI_HOST + - PORT (int) - HALFAPI_PORT + - CONF_DIR (str) - HALFAPI_CONF_DIR - IS_PROJECT (bool) - config (ConfigParser) @@ -43,9 +43,9 @@ import importlib 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: {} DOMAINS = {} PRODUCTION = False @@ -115,49 +115,60 @@ def read_config(): CONFIG = {} -IS_PROJECT = False -if is_project(): - read_config() +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: - raise Exception('Need a project name as argument') +if len(PROJECT_NAME) == 0: + raise Exception('Need a project name as argument') - DOMAINSDICT = lambda: d_domains(config) - DOMAINS = DOMAINSDICT() - HOST = config.get('project', 'host') - PORT = config.getint('project', 'port') +DOMAINSDICT = lambda: d_domains(config) +DOMAINS = DOMAINSDICT() +if len(DOMAINS) == 0: + logger.info('Domain-less instance') - try: - 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 - os.environ['HALFAPI_SECRET'] = SECRET - except FileNotFoundError as exc: - logger.error('There is no file like %s : %s', - config.get('project', 'secret'), exc) +HOST = config.get('project', 'host', fallback=environ.get('HALFAPI_HOST', '127.0.0.1')) +PORT = config.getint('project', 'port', fallback=environ.get('HALFAPI_PORT', '3000')) - PRODUCTION = config.getboolean('project', 'production') or False - os.environ['HALFAPI_PROD'] = str(PRODUCTION) +try: + 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 = { - 'project_name': PROJECT_NAME, - 'production': PRODUCTION, - 'secret': SECRET, - 'domains': DOMAINS, - 'domain_config': {} - } +os.environ['HALFAPI_PROD'] = str(PRODUCTION) - for domain in DOMAINS: - if domain not in config.sections(): - continue +LOGLEVEL = config.get('project', 'loglevel', + fallback=environ.get('HALFAPI_LOGLEVEL', 'info')).lower() - 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)) diff --git a/halfapi/lib/domain.py b/halfapi/lib/domain.py index e19c2ba..2a11c31 100644 --- a/halfapi/lib/domain.py +++ b/halfapi/lib/domain.py @@ -3,6 +3,7 @@ lib/domain.py The domain-scoped utility functions """ +import os import re import sys import importlib @@ -229,6 +230,11 @@ def d_domains(config) -> 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: return {}