Skip to content

Commit 0525690

Browse files
committed
fix: test
1 parent f48da60 commit 0525690

File tree

4 files changed

+129
-80
lines changed

4 files changed

+129
-80
lines changed

Pipfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ boto3 = "==1.34.162"
2929

3030
[dev-packages]
3131
codeforlife = {version = "==0.22.12", extras = ["dev"]}
32-
boto3-stubs = {version = "==1.35.71", extras = ["ec2", "s3"]}
32+
boto3-stubs = {version = "==1.35.71", extras = ["essential"]}
3333
# codeforlife = {file = "../codeforlife-package-python", editable = true, extras = ["dev"]}
3434
# 🚫 Don't add [dev-packages] below that are inherited from the CFL package.
3535

Pipfile.lock

+37-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

application.py

+44-1
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,55 @@
77

88
import os
99

10-
from codeforlife.app import StandaloneApplication
10+
# from codeforlife.app import StandaloneApplication
1111
from django.core.asgi import get_asgi_application
1212
from django.core.wsgi import get_wsgi_application
1313

1414
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
1515

16+
# TODO: delete this
17+
# pylint: disable-all
18+
19+
import multiprocessing
20+
import typing as t
21+
22+
from django.core.management import call_command
23+
from gunicorn.app.base import BaseApplication # type: ignore[import-untyped]
24+
25+
26+
# pylint: disable-next=abstract-method
27+
class StandaloneApplication(BaseApplication):
28+
"""A server for an app in a live environment.
29+
30+
Based off of:
31+
https://gist.github.com/Kludex/c98ed6b06f5c0f89fd78dd75ef58b424
32+
https://docs.gunicorn.org/en/stable/custom.html
33+
"""
34+
35+
def __init__(self, app: t.Callable):
36+
call_command("migrate", interactive=False)
37+
38+
self.options = {
39+
"bind": "0.0.0.0:8080",
40+
# https://docs.gunicorn.org/en/stable/design.html#how-many-workers
41+
"workers": 1,
42+
"worker_class": "uvicorn.workers.UvicornWorker",
43+
}
44+
self.application = app
45+
super().__init__()
46+
47+
def load_config(self):
48+
config = {
49+
key: value
50+
for key, value in self.options.items()
51+
if key in self.cfg.settings and value is not None
52+
}
53+
for key, value in config.items():
54+
self.cfg.set(key.lower(), value)
55+
56+
def load(self):
57+
return self.application
58+
1659

1760
if __name__ == "__main__":
1861
StandaloneApplication(app=get_asgi_application()).run()

settings.py

+47-75
Original file line numberDiff line numberDiff line change
@@ -67,97 +67,69 @@
6767

6868
import json
6969
import logging
70+
import typing as t
7071

7172
import boto3
73+
from codeforlife.types import JsonDict
7274

75+
if t.TYPE_CHECKING:
76+
from mypy_boto3_s3.client import S3Client
7377

74-
def check_for_pointer_file(S3_APP_BUCKET, S3_APP_KEY):
75-
s3 = boto3.client("s3")
7678

77-
pointer = s3.list_objects(
78-
Bucket=S3_APP_BUCKET, Prefix=f"{S3_APP_KEY}/dbMetadata/pointer"
79-
)
80-
81-
if pointer.get("Contents"):
82-
resp = s3.get_object(
83-
Bucket=S3_APP_BUCKET, Key=pointer["Contents"][0]["Key"]
84-
)
85-
return resp["Body"].read().decode("utf-8")
86-
87-
return None
88-
89-
90-
def construct_db_config(S3_APP_BUCKET, S3_KEY, DB_DATA):
91-
s3 = boto3.client("s3")
92-
93-
print(f'connecting with bucket: "{S3_APP_BUCKET}", key: "{S3_KEY}"')
94-
logging.info(f'connecting with bucket: "{S3_APP_BUCKET}", key: "{S3_KEY}"')
79+
AWS_S3_APP_BUCKET = os.getenv("aws_s3_app_bucket")
80+
AWS_S3_APP_FOLDER = os.getenv("aws_s3_app_folder")
81+
# AWS_REGION = os.getenv("aws_region")
82+
APP_ID = os.getenv("APP_ID") # type: ignore[assignment]
83+
APP_VERSION = os.getenv("APP_VERSION") # type: ignore[assignment]
9584

96-
cfg = s3.get_object(Bucket=S3_APP_BUCKET, Key=S3_KEY)
9785

98-
config = json.loads(cfg["Body"].read().decode("utf-8"))
86+
def get_databases():
87+
if AWS_S3_APP_BUCKET and AWS_S3_APP_FOLDER and APP_ID:
88+
key = f"{AWS_S3_APP_FOLDER}/dbMetadata/{APP_ID}/app.dbdata"
9989

100-
if config and config["DBEngine"] == "postgres":
101-
DB_DATA["default"].update(
102-
{
103-
"NAME": config["Database"],
104-
"USER": config["user"],
105-
"PASSWORD": config["password"],
106-
"HOST": config["Endpoint"],
107-
"PORT": config["Port"],
108-
}
90+
print(
91+
f'(print) connecting with bucket: "{AWS_S3_APP_BUCKET}", key: "{key}"'
92+
)
93+
logging.info(
94+
f'(log) connecting with bucket: "{AWS_S3_APP_BUCKET}", key: "{key}"'
10995
)
11096

111-
return DB_DATA
112-
97+
s3: "S3Client" = boto3.client("s3")
98+
db_data_object = s3.get_object(Bucket=AWS_S3_APP_BUCKET, Key=key)
11399

114-
def load_db_config(S3_APP_BUCKET, S3_APP_KEY):
115-
s3 = boto3.client("s3")
100+
db_data: JsonDict = json.loads(
101+
db_data_object["Body"].read().decode("utf-8")
102+
)
116103

117-
default_dict = {
104+
if not db_data or db_data["DBEngine"] != "postgres":
105+
raise ConnectionAbortedError("Invalid database data.")
106+
107+
name = db_data["Database"]
108+
user = db_data["user"]
109+
password = db_data["password"]
110+
host = db_data["Endpoint"]
111+
port = db_data["Port"]
112+
else:
113+
name = os.getenv("DB_NAME", SERVICE_NAME)
114+
user = os.getenv("DB_USER", "root")
115+
password = os.getenv("DB_PASSWORD", "password")
116+
host = os.getenv("DB_HOST", "localhost")
117+
port = int(os.getenv("DB_PORT", "5432"))
118+
119+
return {
118120
"default": {
119-
# "ENGINE": "django.db.backends.postgresql_psycopg2",
120121
"ENGINE": "django.db.backends.postgresql",
121-
"NAME": "",
122-
"USER": "",
123-
"PASSWORD": "",
124-
"HOST": "",
125-
"PORT": "",
126-
"OPTIONS": {
127-
"connect_timeout": 300,
128-
},
122+
"NAME": name,
123+
"USER": user,
124+
"PASSWORD": password,
125+
"HOST": host,
126+
"PORT": port,
127+
# "OPTIONS": {
128+
# "connect_timeout": 300,
129+
# },
129130
"ATOMIC_REQUESTS": True,
130131
}
131132
}
132133

133-
link = check_for_pointer_file(S3_APP_BUCKET, S3_APP_KEY)
134-
if link:
135-
return construct_db_config(S3_APP_BUCKET, link, default_dict)
136-
137-
objs = s3.list_objects(
138-
Bucket=S3_APP_BUCKET, Prefix=f"{S3_APP_KEY}/dbMetadata/"
139-
)
140-
for config_file in objs.get("Contents", []):
141-
return construct_db_config(
142-
S3_APP_BUCKET, config_file["Key"], default_dict
143-
)
144-
145-
146-
S3_BUCKET = os.getenv("aws_s3_app_bucket")
147-
S3_PREFIX = os.getenv("aws_s3_app_folder")
148-
# AWS_REGION = os.getenv("aws_region")
149134

150-
if S3_BUCKET and S3_PREFIX:
151-
DATABASES = load_db_config(S3_BUCKET, S3_PREFIX)
152-
153-
# DATABASES = {
154-
# "default": {
155-
# "ENGINE": "django.db.backends.postgresql",
156-
# "NAME": os.getenv("DB_NAME", SERVICE_NAME),
157-
# "HOST": os.getenv("DB_HOST", "localhost"),
158-
# "PORT": int(os.getenv("DB_PORT", "5432")),
159-
# # "USER": os.getenv("DB_USER", "root"),
160-
# # "PASSWORD": os.getenv("DB_PASSWORD", "password"),
161-
# "ATOMIC_REQUESTS": True,
162-
# }
163-
# }
135+
DATABASES = get_databases()

0 commit comments

Comments
 (0)