feat: use yaml and envs to load config

This commit is contained in:
swve 2023-03-24 22:50:08 +01:00
parent 0782e2c419
commit dee9ae6cf3
8 changed files with 181 additions and 6 deletions

22
app.py
View file

@ -1,6 +1,8 @@
import asyncio
import logging
from fastapi import FastAPI, Request
import re
from config.config import LearnHouseConfig, get_learnhouse_config
from src.core.config.config import Settings, get_settings
from src.core.events.events import shutdown_app, startup_app
from src.main import global_router
@ -16,10 +18,13 @@ from fastapi_jwt_auth.exceptions import AuthJWTException
# (c) LearnHouse 2022
########################
# Get LearnHouse Config
learnhouse_config: LearnHouseConfig = get_learnhouse_config()
# Global Config
app = FastAPI(
title="LearnHouse",
description="LearnHouse is a new open-source platform tailored for learning experiences.",
title=learnhouse_config.site_name,
description=learnhouse_config.site_description,
version="0.1.0",
root_path="/"
)
@ -45,7 +50,7 @@ app.add_event_handler("shutdown", shutdown_app(app))
# JWT Exception Handler
@app.exception_handler(AuthJWTException)
@ app.exception_handler(AuthJWTException)
def authjwt_exception_handler(request: Request, exc: AuthJWTException):
return JSONResponse(
status_code=exc.status_code, # type: ignore
@ -59,10 +64,19 @@ app.include_router(global_router)
# General Routes
@app.get("/")
@ app.get("/")
async def root():
return {"Message": "Welcome to LearnHouse ✨"}
# Get config
@ app.get("/config")
async def config():
logging.info("Getting config")
config = get_learnhouse_config()
return config.dict()
# @app.get("/initial_data")
# async def initial_data(request: Request):

View file

@ -0,0 +1,111 @@
from pydantic import BaseModel
import os
import yaml
class HostingConfig(BaseModel):
domain: str
port: int
ssl: bool
use_default_org: bool
allowed_origins: list
allowed_regexp: str
self_hosted: bool
class DatabaseConfig(BaseModel):
host: str
port: int
user: str
password: str
database_name: str
class LearnHouseConfig(BaseModel):
site_name: str
site_description: str
contact_email: str
hosting_config: HostingConfig
database_config: DatabaseConfig
def get_learnhouse_config() -> LearnHouseConfig:
# Get the YAML file
yaml_path = os.path.join(os.path.dirname(__file__), 'config.yaml')
# Load the YAML file
with open(yaml_path, 'r') as f:
yaml_config = yaml.safe_load(f)
# Check if environment variables are defined
env_site_name = os.environ.get('LEARNHOUSE_SITE_NAME')
env_site_description = os.environ.get('LEARNHOUSE_SITE_DESCRIPTION')
env_contact_email = os.environ.get('LEARNHOUSE_CONTACT_EMAIL')
env_domain = os.environ.get('LEARNHOUSE_DOMAIN')
env_port = os.environ.get('LEARNHOUSE_PORT')
env_ssl = os.environ.get('LEARNHOUSE_SSL')
env_use_default_org = os.environ.get('LEARNHOUSE_USE_DEFAULT_ORG')
env_allowed_origins = os.environ.get('LEARNHOUSE_ALLOWED_ORIGINS')
env_allowed_regexp = os.environ.get('LEARNHOUSE_ALLOWED_REGEXP')
env_self_hosted = os.environ.get('LEARNHOUSE_SELF_HOSTED')
env_host = os.environ.get('LEARNHOUSE_DB_HOST')
env_db_port = os.environ.get('LEARNHOUSE_DB_PORT')
env_user = os.environ.get('LEARNHOUSE_DB_USER')
env_password = os.environ.get('LEARNHOUSE_DB_PASSWORD')
env_database_name = os.environ.get('LEARNHOUSE_DB_NAME')
# Fill in values with YAML file if they are not provided
site_name = env_site_name or yaml_config.get('site_name')
site_description = env_site_description or yaml_config.get(
'site_description')
contact_email = env_contact_email or yaml_config.get('contact_email')
domain = env_domain or yaml_config.get('hosting_config', {}).get('domain')
port = env_port or yaml_config.get('hosting_config', {}).get('port')
ssl = env_ssl or yaml_config.get('hosting_config', {}).get('ssl')
use_default_org = env_use_default_org or yaml_config.get(
'hosting_config', {}).get('use_default_org')
allowed_origins = env_allowed_origins or yaml_config.get(
'hosting_config', {}).get('allowed_origins')
allowed_regexp = env_allowed_regexp or yaml_config.get(
'hosting_config', {}).get('allowed_regexp')
self_hosted = env_self_hosted or yaml_config.get(
'hosting_config', {}).get('self_hosted')
host = env_host or yaml_config.get('database_config', {}).get('host')
db_port = env_db_port or yaml_config.get('database_config', {}).get('port')
user = env_user or yaml_config.get('database_config', {}).get('user')
password = env_password or yaml_config.get(
'database_config', {}).get('password')
database_name = env_database_name or yaml_config.get(
'database_config', {}).get('database_name')
# Create HostingConfig and DatabaseConfig objects
hosting_config = HostingConfig(
domain=domain,
port=int(port),
ssl=bool(ssl),
use_default_org=bool(use_default_org),
allowed_origins=list(allowed_origins),
allowed_regexp=allowed_regexp,
self_hosted=bool(self_hosted)
)
database_config = DatabaseConfig(
host=host,
port=int(db_port),
user=user,
password=password,
database_name=database_name
)
# Create LearnHouseConfig object
config = LearnHouseConfig(
site_name=site_name,
site_description=site_description,
contact_email=contact_email,
hosting_config=hosting_config,
database_config=database_config
)
return config

21
config/config.yaml Normal file
View file

@ -0,0 +1,21 @@
site_name: LearnHouse
site_description: LearnHouse is an open-source platform tailored for learning experiences.
contact_email: hi@learnhouse.app
hosting_config:
domain: learnhouse.app
port: 443
ssl: true
use_default_org: false
allowed_origins:
- https://learnhouse.app
- https://learnhouse.io
allowed_regexp: "^https://(.*\\.)?learnhouse\\.app$"
self_hosted: false
database_config:
host: db.mongo
port: 5432
user: myuser
password: mypassword
database_name: mydatabase

View file

View file

@ -29,7 +29,7 @@
"@editor/*": ["components/Editor/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx","**/**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}

View file

@ -8,4 +8,5 @@ python-jose
passlib
fastapi-jwt-auth
faker
requests
requests
pyyaml

View file

@ -1,6 +1,7 @@
from typing import Callable
from fastapi import FastAPI
from src.core.events.database import close_database, connect_to_db
from src.core.events.logs import create_logs_dir
def startup_app(app: FastAPI) -> Callable:
@ -8,6 +9,9 @@ def startup_app(app: FastAPI) -> Callable:
# Connect to database
await connect_to_db(app)
# Create logs directory
await create_logs_dir()
return start_app

24
src/core/events/logs.py Normal file
View file

@ -0,0 +1,24 @@
import logging
import os
async def create_logs_dir():
if not os.path.exists("logs"):
os.mkdir("logs")
# Initiate logging
async def init_logging():
await create_logs_dir()
# Logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
datefmt="%d-%b-%y %H:%M:%S",
handlers=[
logging.FileHandler("logs/learnhouse.log"),
logging.StreamHandler()
]
)
logging.info("Logging initiated")