[cli-conf] halfapi domain : the file provided as argument is a toml file of the format of .halfapi/config, + better config handling
This commit is contained in:
parent
4856f80b99
commit
87856cfb42
|
@ -1,9 +1,11 @@
|
||||||
|
import os
|
||||||
from .halfapi import HalfAPI
|
from .halfapi import HalfAPI
|
||||||
from .conf import CONFIG, SCHEMA
|
|
||||||
from .logging import logger
|
from .logging import logger
|
||||||
|
from .conf import read_config
|
||||||
|
|
||||||
logger.info('CONFIG: %s', CONFIG)
|
def application():
|
||||||
logger.info('SCHEMA: %s', SCHEMA)
|
config_file = os.environ.get('HALFAPI_CONF_FILE', '.halfapi/config')
|
||||||
|
|
||||||
application = HalfAPI(
|
CONFIG = read_config([config_file])
|
||||||
CONFIG, SCHEMA or None).application
|
|
||||||
|
return HalfAPI(CONFIG).application
|
||||||
|
|
|
@ -9,6 +9,7 @@ import importlib
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import toml
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import orjson
|
import orjson
|
||||||
|
@ -16,7 +17,6 @@ import uvicorn
|
||||||
|
|
||||||
|
|
||||||
from .cli import cli
|
from .cli import cli
|
||||||
from ..conf import CONFIG
|
|
||||||
|
|
||||||
from ..half_domain import HalfDomain
|
from ..half_domain import HalfDomain
|
||||||
|
|
||||||
|
@ -145,6 +145,14 @@ def domain(domain, config_file, delete, update, create, read, run, dry_run): #,
|
||||||
# TODO: Connect to the create_domain function
|
# TODO: Connect to the create_domain function
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
raise Exception('Missing domain name')
|
raise Exception('Missing domain name')
|
||||||
|
|
||||||
|
if config_file:
|
||||||
|
CONFIG = toml.load(config_file.name)
|
||||||
|
|
||||||
|
os.environ['HALFAPI_CONF_FILE'] = config_file.name
|
||||||
|
else:
|
||||||
|
from halfapi.conf import CONFIG
|
||||||
|
|
||||||
if create:
|
if create:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
elif update:
|
elif update:
|
||||||
|
@ -152,14 +160,8 @@ def domain(domain, config_file, delete, update, create, read, run, dry_run): #,
|
||||||
elif delete:
|
elif delete:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
elif read:
|
elif read:
|
||||||
from ..conf import CONFIG
|
|
||||||
from ..halfapi import HalfAPI
|
from ..halfapi import HalfAPI
|
||||||
|
|
||||||
if config_file:
|
|
||||||
CONFIG = json.loads(''.join(
|
|
||||||
[ line.decode() for line in config_file.readlines() ]
|
|
||||||
))
|
|
||||||
|
|
||||||
halfapi = HalfAPI(CONFIG)
|
halfapi = HalfAPI(CONFIG)
|
||||||
click.echo(orjson.dumps(
|
click.echo(orjson.dumps(
|
||||||
halfapi.domains[domain].schema(),
|
halfapi.domains[domain].schema(),
|
||||||
|
@ -168,25 +170,13 @@ def domain(domain, config_file, delete, update, create, read, run, dry_run): #,
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
from ..conf import CONFIG
|
port = CONFIG.get('port',
|
||||||
if 'domain' not in CONFIG:
|
CONFIG.get('domain', {}).get('port')
|
||||||
CONFIG['domain'] = {}
|
)
|
||||||
|
|
||||||
if domain not in CONFIG['domain']:
|
|
||||||
CONFIG['domain'][domain] = {
|
|
||||||
'enabled': True,
|
|
||||||
'name': domain
|
|
||||||
}
|
|
||||||
|
|
||||||
if dry_run:
|
|
||||||
CONFIG['dryrun'] = True
|
|
||||||
|
|
||||||
CONFIG['domain'][domain]['enabled'] = True
|
|
||||||
port = CONFIG['domain'][domain].get('port', 3000)
|
|
||||||
|
|
||||||
uvicorn.run(
|
uvicorn.run(
|
||||||
'halfapi.app:application',
|
'halfapi.app:application',
|
||||||
port=port
|
port=port,
|
||||||
|
factory=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ It follows the following format :
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
from .logging import logger
|
||||||
import os
|
import os
|
||||||
from os import environ
|
from os import environ
|
||||||
import sys
|
import sys
|
||||||
|
@ -46,8 +46,6 @@ import uuid
|
||||||
|
|
||||||
import toml
|
import toml
|
||||||
|
|
||||||
from .logging import logger
|
|
||||||
|
|
||||||
PRODUCTION = True
|
PRODUCTION = True
|
||||||
LOGLEVEL = 'info'
|
LOGLEVEL = 'info'
|
||||||
CONF_FILE = os.environ.get('HALFAPI_CONF_FILE', '.halfapi/config')
|
CONF_FILE = os.environ.get('HALFAPI_CONF_FILE', '.halfapi/config')
|
||||||
|
@ -77,17 +75,18 @@ except FileNotFoundError:
|
||||||
logger.error('Cannot find a configuration file under %s', HALFAPI_DOT_FILE)
|
logger.error('Cannot find a configuration file under %s', HALFAPI_DOT_FILE)
|
||||||
|
|
||||||
|
|
||||||
def read_config():
|
def read_config(filenames=HALFAPI_CONFIG_FILES):
|
||||||
"""
|
"""
|
||||||
The highest index in "filenames" are the highest priorty
|
The highest index in "filenames" are the highest priorty
|
||||||
"""
|
"""
|
||||||
d_res = {}
|
d_res = {}
|
||||||
|
|
||||||
logger.info('Reading config files %s', HALFAPI_CONFIG_FILES)
|
logger.info('Reading config files %s', filenames)
|
||||||
for CONF_FILE in HALFAPI_CONFIG_FILES:
|
for CONF_FILE in filenames:
|
||||||
d_res.update( toml.load(HALFAPI_CONFIG_FILES) )
|
if os.path.isfile(CONF_FILE):
|
||||||
|
d_res.update( toml.load(CONF_FILE) )
|
||||||
|
|
||||||
logger.info('Reading config files (result) %s', d_res)
|
logger.info('Read config files (result) %s', d_res)
|
||||||
return { **d_res.get('project', {}), 'domain': d_res.get('domain', {}) }
|
return { **d_res.get('project', {}), 'domain': d_res.get('domain', {}) }
|
||||||
|
|
||||||
CONFIG = read_config()
|
CONFIG = read_config()
|
||||||
|
|
|
@ -9,6 +9,7 @@ It defines the following globals :
|
||||||
- application (the asgi application itself - a starlette object)
|
- application (the asgi application itself - a starlette object)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
import sys
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
import importlib
|
import importlib
|
||||||
|
@ -48,6 +49,7 @@ class HalfAPI(Starlette):
|
||||||
d_routes=None):
|
d_routes=None):
|
||||||
config_logging(logging.DEBUG)
|
config_logging(logging.DEBUG)
|
||||||
self.config = config
|
self.config = config
|
||||||
|
logger.debug('HalfAPI.config: %s', self.config)
|
||||||
|
|
||||||
SECRET = self.config.get('secret')
|
SECRET = self.config.get('secret')
|
||||||
PRODUCTION = self.config.get('production', True)
|
PRODUCTION = self.config.get('production', True)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
from json.decoder import JSONDecodeError
|
from json.decoder import JSONDecodeError
|
||||||
|
import toml
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from starlette.testclient import TestClient
|
from starlette.testclient import TestClient
|
||||||
from click.testing import CliRunner
|
from click.testing import CliRunner
|
||||||
|
@ -79,7 +80,7 @@ class TestDomain(TestCase):
|
||||||
|
|
||||||
_, self.config_file = tempfile.mkstemp()
|
_, self.config_file = tempfile.mkstemp()
|
||||||
with open(self.config_file, 'w') as fh:
|
with open(self.config_file, 'w') as fh:
|
||||||
fh.write(json.dumps(self.halfapi_conf))
|
fh.write(toml.dumps(self.halfapi_conf))
|
||||||
|
|
||||||
self.halfapi = HalfAPI(self.halfapi_conf)
|
self.halfapi = HalfAPI(self.halfapi_conf)
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import importlib
|
||||||
import tempfile
|
import tempfile
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
import json
|
import json
|
||||||
|
import toml
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from click.testing import CliRunner
|
from click.testing import CliRunner
|
||||||
|
@ -29,12 +30,16 @@ class TestCliProj():
|
||||||
_, tmp_conf = tempfile.mkstemp()
|
_, tmp_conf = tempfile.mkstemp()
|
||||||
with open(tmp_conf, 'w') as fh:
|
with open(tmp_conf, 'w') as fh:
|
||||||
fh.write(
|
fh.write(
|
||||||
json.dumps({
|
toml.dumps({
|
||||||
'domain': {
|
'domain': {
|
||||||
'dummy_domain': {
|
'dummy_domain': {
|
||||||
|
'port': 4242,
|
||||||
'name': 'dummy_domain',
|
'name': 'dummy_domain',
|
||||||
'enabled': True
|
'enabled': True
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
'project': {
|
||||||
|
'dryrun': True
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue