Configuration
Base Configuration
The base of configuration is given below.
second = 1
minute = 60 * second
hour = 60 * minute
day = 24 * hour
year = 365 * day
class Auth:
def __init__(self, secure=True, expire=hour, refresh_expire=year):
self.secure = secure
self.expire = expire
self.refresh_expire = refresh_expire
class BaseConfig:
name = "Freenit"
version = "0.0.1"
api_root = "/api/v1"
hostname = socket.gethostname()
port = 5000
debug = False
metadata = sqlalchemy.MetaData()
dburl = "sqlite:///db.sqlite"
database = None
engine = None
secret = "SECRET" # nosec
user = "freenit.models.sql.user"
role = "freenit.models.sql.role"
theme = "freenit.models.sql.theme"
theme_name = "Freenit"
meta = None
auth = Auth()
As you see, it's mostly about setting DB and proper user/role/theme models. On top of that, there is a class for configuring mail server for sending.
class Mail:
def __init__(
self,
server="mail.example.com",
user="user@example.com",
password="Sekrit", # nosec
port=587,
tls=True,
from_addr="no-reply@mail.com",
register_subject="[Freenit] User Registration",
register_message=register_message,
master_user="dovecot@example.com",
master_pw="Sekrit",
) -> None:
self.server = server
self.user = user
self.password = password
self.port = port
self.tls = tls
self.from_addr = from_addr
self.register_subject = register_subject
self.register_message = register_message
self.master_user = master_user
self.master_pw = master_pw
Project Configuration
To actually create config for development, testing and production, declare the following classes.
class DevConfig(BaseConfig):
debug = True
dburl = "sqlite:///db.sqlite"
auth = Auth(secure=False)
class TestConfig(BaseConfig):
debug = True
dburl = "sqlite:///test.sqlite"
auth = Auth(secure=False)
class ProdConfig(BaseConfig):
secret = "MORESECURESECRET" # nosec
mail = Mail()
Freenit will try to include every one of them, and if it fails, it will use default config class
instead. That's how it looks in Freenit itself, but in your project you should organize a bit
differently. In myproject/myproject/base_config.py
define 3 classes.
from freenit.base_config import Auth, Mail, BaseConfig as FreenitBaseConfig
class BaseConfig(FreenitBaseConfig):
name = "NAME"
version = "0.0.1"
class DevConfig(BaseConfig):
debug = True
auth = Auth(False)
dburl = "sqlite:///db.sqlite"
class TestConfig(BaseConfig):
debug = True
auth = Auth(False)
dburl = "sqlite:///test.sqlite"
class ProdConfig(BaseConfig):
secret = "MORESECURESECRET" # nosec
mail = Mail()
Then in myproject/myproject/config.py
you have the following.
import os
from freenit.config import configs
try:
from .local_config import DevConfig
except ImportError:
from .base_config import DevConfig
try:
from .local_config import TestConfig
except ImportError:
from .base_config import TestConfig
try:
from .local_config import ProdConfig
except ImportError:
from .base_config import ProdConfig
configs[DevConfig.envname()] = DevConfig()
configs[TestConfig.envname()] = TestConfig()
configs[ProdConfig.envname()] = ProdConfig()
def getConfig():
config_name = os.getenv("FREENIT_ENV", "prod")
return configs.get(config_name, configs["prod"])
That way if you create myproject/myproject/local_config.py
, you can override any of the config
items. The idea behind local_config.py
is to be able to override settings in production so the
sensitive data is not distributed with the repository of the project. Also, if you need extra
settings, you can add them in your base config to share with other configs, or just to the
production config. For example, you might need Redis or some other external service to be
configured. The following code shows you how to change secret
in production.
from .base_config ProdConfig as BaseProdConfig
class ProdConfig(BaseProdConfig):
secret = "WAYMORESECURESECRET"