[core] Don't read configs at the module top-level

This commit is contained in:
Thomas Lindner 2023-03-18 18:16:57 +01:00
parent 003a10b273
commit 35eff0c416
5 changed files with 64 additions and 73 deletions

View file

@ -14,12 +14,13 @@
0. `cd backend`
1. Activate your dev environment with `source .venv/bin/activate`
2. Install with `pip install .`
3. Turn off production mode: `sudo su -c 'echo "production = 0" >> /etc/kibicara.conf'`
3. Create a config file: `echo "production = 0" > kibicara.conf`
#### Cheatsheet
- Install Kibicara with `pip install .`
- Execute Kibicara with `kibicara` (verbose: `kibicara -vvv`)
- Execute Kibicara with `kibicara -f kibicara.conf`
(verbose: `kibicara -vvv -f kibicara.conf`)
- Interact with Swagger REST-API Documentation: `http://localhost:8000/api/docs`
- Test and stylecheck with `tox`
- Fix style issues with `black -S src tests`

View file

@ -1,4 +1,4 @@
Copyright (C) 2020 by Thomas Lindner <tom@dl6tom.de>
Copyright (C) 2020, 2023 by Thomas Lindner <tom@dl6tom.de>
Copyright (C) 2020 by Cathy Hu <cathy.hu@fau.de>
Copyright (C) 2020 by Christian Hagenest <c.hagenest@pm.me>
Copyright (C) 2020 by Martin Rey <martin.rey@mailbox.org>

View file

@ -1,29 +1,16 @@
# Copyright (C) 2020 by Thomas Lindner <tom@dl6tom.de>
# Copyright (C) 2020, 2023 by Thomas Lindner <tom@dl6tom.de>
# Copyright (C) 2020 by Cathy Hu <cathy.hu@fau.de>
# Copyright (C) 2020 by Martin Rey <martin.rey@mailbox.org>
#
# SPDX-License-Identifier: 0BSD
"""Configuration file and command line argument parser.
Gives a dictionary named `config` with configuration parsed either from
`/etc/kibicara.conf` or from a file given by command line argument `-f`.
If no configuration was found at all, the defaults are used.
Example:
```
from kibicara.config import config
print(config)
```
"""
from argparse import ArgumentParser
from sys import argv
from nacl.secret import SecretBox
from nacl.utils import random
from pytoml import load
"""Default configuration.
The default configuration gets overwritten by a configuration file if one exists.
"""
config = {
'database_connection': 'sqlite:////tmp/kibicara.sqlite',
'frontend_url': 'http://localhost:4200', # url of frontend, change in prod
@ -38,47 +25,3 @@ config = {
'root_url': 'http://localhost:8000', # url of backend
'cors_allow_origin': 'http://localhost:4200',
}
"""Default configuration.
The default configuration gets overwritten by a configuration file if one exists.
"""
args = None
if argv[0].endswith('kibicara'):
parser = ArgumentParser()
parser.add_argument(
'-f',
'--config',
dest='configfile',
default='/etc/kibicara.conf',
help='path to config file',
)
parser.add_argument(
'-v',
'--verbose',
action='count',
help='Raise verbosity level',
)
args = parser.parse_args()
if argv[0].endswith('kibicara_mda'):
parser = ArgumentParser()
parser.add_argument(
'-f',
'--config',
dest='configfile',
default='/etc/kibicara.conf',
help='path to config file',
)
# the MDA passes the recipient address as command line argument
parser.add_argument('recipient')
args = parser.parse_args()
if args is not None:
try:
with open(args.configfile) as configfile:
config.update(load(configfile))
except FileNotFoundError:
# run with default config
pass

View file

@ -1,4 +1,4 @@
# Copyright (C) 2020 by Thomas Lindner <tom@dl6tom.de>
# Copyright (C) 2020, 2023 by Thomas Lindner <tom@dl6tom.de>
# Copyright (C) 2020 by Cathy Hu <cathy.hu@fau.de>
# Copyright (C) 2020 by Martin Rey <martin.rey@mailbox.org>
#
@ -6,6 +6,7 @@
"""Entrypoint of Kibicara."""
from argparse import ArgumentParser
from asyncio import run as asyncio_run
from logging import DEBUG, INFO, WARNING, basicConfig, getLogger
@ -14,8 +15,9 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from hypercorn.asyncio import serve
from hypercorn.config import Config
from pytoml import load
from kibicara.config import args, config
from kibicara.config import config
from kibicara.model import Mapping
from kibicara.platformapi import Spawner
from kibicara.webapi import router
@ -31,9 +33,29 @@ class Main:
"""
def __init__(self):
asyncio_run(self.__run())
parser = ArgumentParser()
parser.add_argument(
'-f',
'--config',
dest='configfile',
default='/etc/kibicara.conf',
help='path to config file',
)
parser.add_argument(
'-v',
'--verbose',
action='count',
help='Raise verbosity level',
)
args = parser.parse_args()
try:
with open(args.configfile) as configfile:
config.update(load(configfile))
except FileNotFoundError:
# run with default config
pass
async def __run(self):
LOGLEVELS = {
None: WARNING,
1: INFO,
@ -45,6 +67,9 @@ class Main:
)
getLogger('aiosqlite').setLevel(WARNING)
Mapping.create_all()
asyncio_run(self.__run())
async def __run(self):
await Spawner.init_all()
await self.__start_webserver()

View file

@ -1,10 +1,11 @@
# Copyright (C) 2020 by Maike <maike@systemli.org>
# Copyright (C) 2020 by Cathy Hu <cathy.hu@fau.de>
# Copyright (C) 2020 by Thomas Lindner <tom@dl6tom.de>
# Copyright (C) 2020, 2023 by Thomas Lindner <tom@dl6tom.de>
# Copyright (C) 2020 by Martin Rey <martin.rey@mailbox.org>
#
# SPDX-License-Identifier: 0BSD
from argparse import ArgumentParser
from asyncio import run as asyncio_run
from email.parser import BytesParser
from email.policy import default
@ -15,9 +16,10 @@ from sys import stdin
from fastapi import status
from ormantic import NoMatch
from pytoml import load
from requests import post
from kibicara.config import args, config
from kibicara.config import config
from kibicara.platforms.email.model import Email, EmailSubscribers
logger = getLogger(__name__)
@ -25,11 +27,31 @@ logger = getLogger(__name__)
class Main:
def __init__(self):
asyncio_run(self.__run())
parser = ArgumentParser()
parser.add_argument(
'-f',
'--config',
dest='configfile',
default='/etc/kibicara.conf',
help='path to config file',
)
# the MDA passes the recipient address as command line argument
parser.add_argument('recipient')
args = parser.parse_args()
try:
with open(args.configfile) as configfile:
config.update(load(configfile))
except FileNotFoundError:
# run with default config
pass
async def __run(self):
# extract email from the recipient
email_name = args.recipient.lower()
asyncio_run(self.__run(email_name))
async def __run(self, email_name):
try:
email = await Email.objects.get(name=email_name)
except NoMatch: