Skip to content

Commit edc0f2d

Browse files
committed
Conver Config class to use dataclass annotation
1 parent d303f41 commit edc0f2d

3 files changed

Lines changed: 35 additions & 43 deletions

File tree

‎hypercorn.sh‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
22
rm -f /tmp/server.*
33
openssl req -new -newkey rsa:4096 -x509 -nodes -days 365 -keyout /tmp/server.key -out /tmp/server.crt -subj "/C=SG/ST=Singapore/L=Singapore /O=Kok How Pte. Ltd./OU=PythonFlaskRestAPI/CN=localhost/emailAddress=funcoolgeek@gmail.com" -passin pass:PythonFlaskRestAPI
4-
uv run hypercorn --config=/etc/hypercorn.toml --reload src.main:app
5-
#uv run hypercorn --config=/etc/hypercorn.toml --reload 'src.main:create_app()'
4+
#uv run hypercorn --config=/etc/hypercorn.toml --reload src.main:app
5+
uv run hypercorn --config=/etc/hypercorn.toml --reload 'src.main:create_app()'

‎src/config.py‎

Lines changed: 30 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os, json, logging, sys, secrets
2+
from dataclasses import dataclass
23
from dotenv import load_dotenv
34
from logging.handlers import TimedRotatingFileHandler
45
from urllib import parse
@@ -20,45 +21,35 @@ def __call__(cls, *args, **kwargs):
2021
elif registry[cls][1] != args or registry(cls)[2] != kwargs:
2122
raise TypeError(f"Class already initialized with different arguments!")
2223
return registry[cls][0]
23-
class Config(metaclass=ConfigSingleton):
24-
LOGLEVEL:str = None
24+
@dataclass(frozen=True)
25+
class Config:
26+
with open('/etc/pythonrestapi_config.json', 'r') as f:
27+
config = json.load(f)
2528
TESTING = False
26-
SECRET_KEY:str = None
27-
SQLALCHEMY_DATABASE_URI:str = None
28-
POSTGRESQL_DATABASE_URI:str = None
29-
JWT_SECRET_KEY:str = None
30-
GEMINI_API_KEY:str = None
31-
def __new__(cls, *args, **kwargs):
32-
return super().__new__(cls)
33-
def __init__(self, environment="Development"):
34-
with open('/etc/pythonrestapi_config.json', 'r') as f:
35-
config = json.load(f)
36-
self.LOGLEVEL = config['LOGLEVEL']
37-
self.SECRET_KEY = config["SECRET_KEY"] or "you-will-never-guess"
38-
self.SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg://{os.environ.get('DB_USERNAME')}:{parse.quote_plus(os.environ.get('DB_PASSWORD'))}@{config['DB_HOST']}/library"
39-
self.POSTGRESQL_DATABASE_URI = f"postgresql://{os.environ.get('DB_USERNAME')}:{parse.quote_plus(os.environ.get('DB_PASSWORD'))}@{config['DB_HOST']}/library"
40-
if "JWT_SECRET_KEY" in config and len(config["JWT_SECRET_KEY"]) >= 64:
41-
self.JWT_SECRET_KEY = config["JWT_SECRET_KEY"]
42-
else:
43-
self.JWT_SECRET_KEY = secrets.token_hex(64) # SHA512 requirement
44-
self.GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
45-
"""
46-
https://docs.python.org/3/library/logging.html
47-
The level parameter now accepts a string representation of the level such as ‘INFO’ as an alternative to the integer constants such as INFO.
48-
"""
49-
logging.getLogger("httpx").setLevel(logging.WARNING)
50-
"""
51-
https://realpython.com/python-modulo-string-formatting/#fine-tune-your-output-with-conversion-flags
52-
- Justification of values that are shorter than the specified field width
53-
The Hyphen-Minus Flag (-)
54-
When a formatted value is shorter than the specified field width, it’s usually right-justified in the field. The hyphen-minus (-) flag causes the value to be left-justified in the specified field instead.
55-
"""
56-
if config["ENVIRONMENT"] == "development":
57-
logging.basicConfig(filename='/var/log/pythonrestapi/log', filemode='w', format='%(asctime)s %(levelname)-8s %(message)s', level=self.LOGLEVEL, datefmt='%Y-%m-%d %H:%M:%S')
58-
else:
59-
logging.basicConfig(handlers=[
60-
TimedRotatingFileHandler(filename='/var/log/pythonrestapi/log', when='d', interval=1, backupCount=3),
61-
logging.StreamHandler(sys.stdout)
62-
], format='%(asctime)s %(levelname)-8s %(message)s', level=self.LOGLEVEL, datefmt='%Y-%m-%d %H:%M:%S')
29+
environment = config["ENVIRONMENT"],
30+
LOGLEVEL = config['LOGLEVEL'],
31+
SECRET_KEY = config["SECRET_KEY"] or "you-will-never-guess",
32+
JWT_SECRET_KEY = config["JWT_SECRET_KEY"] if "JWT_SECRET_KEY" in config and len(config["JWT_SECRET_KEY"]) >= 64 else secrets.token_hex(64),
33+
SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg://{os.environ.get('DB_USERNAME')}:{parse.quote_plus(os.environ.get('DB_PASSWORD'))}@{config['DB_HOST']}/library"
34+
POSTGRESQL_DATABASE_URI = f"postgresql://{os.environ.get('DB_USERNAME')}:{parse.quote_plus(os.environ.get('DB_PASSWORD'))}@{config['DB_HOST']}/library"
35+
GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
36+
"""
37+
https://docs.python.org/3/library/logging.html
38+
The level parameter now accepts a string representation of the level such as ‘INFO’ as an alternative to the integer constants such as INFO.
39+
"""
40+
logging.getLogger("httpx").setLevel(logging.WARNING)
41+
"""
42+
https://realpython.com/python-modulo-string-formatting/#fine-tune-your-output-with-conversion-flags
43+
- Justification of values that are shorter than the specified field width
44+
The Hyphen-Minus Flag (-)
45+
When a formatted value is shorter than the specified field width, it’s usually right-justified in the field. The hyphen-minus (-) flag causes the value to be left-justified in the specified field instead.
46+
"""
47+
if environment == "development":
48+
logging.basicConfig(filename='/var/log/pythonrestapi/log', filemode='w', format='%(asctime)s %(levelname)-8s %(message)s', level=LOGLEVEL, datefmt='%Y-%m-%d %H:%M:%S')
49+
else:
50+
logging.basicConfig(handlers=[
51+
TimedRotatingFileHandler(filename='/var/log/pythonrestapi/log', when='d', interval=1, backupCount=3),
52+
logging.StreamHandler(sys.stdout)
53+
], format='%(asctime)s %(levelname)-8s %(message)s', level=LOGLEVEL, datefmt='%Y-%m-%d %H:%M:%S')
6354

6455
config = Config()

‎src/main.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def _add_secure_headers(response: Response) -> Response:
3434
response.headers["X-Content-Type-Options"] = "nosniff"
3535
return response
3636

37-
async def create_app() -> Quart:
37+
def create_app() -> Quart:
3838
"""
3939
Create App
4040
"""
@@ -78,7 +78,8 @@ async def handle_csrf_error(e):
7878
return app
7979

8080
logging.info(f"Running app...")
81-
app = asyncio.run(create_app())
81+
app = create_app()
82+
#app = asyncio.run(create_app())
8283
#app = trio.run(create_app)
8384
#app = asyncio.get_event_loop().run_until_complete(create_app())
8485
#asyncio.run(serve(app, config), debug=True)

0 commit comments

Comments
 (0)