Compare commits
3
Commits
d9d2dbab74
...
38fc595725
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38fc595725 | ||
|
|
e04ce33891 | ||
|
|
bc653a0be4 |
+16
-17
@@ -1,21 +1,20 @@
|
||||
version: '3.7'
|
||||
services:
|
||||
# app:
|
||||
# image: visual_critical_discourse_analysis:dev
|
||||
# container_name: visual_critical_discourse_analysis
|
||||
# build:
|
||||
# context: .
|
||||
# dockerfile: Dockerfile
|
||||
# env_file:
|
||||
# - local.env
|
||||
# environment:
|
||||
# - ENV=DEV
|
||||
# ports:
|
||||
# - 8050:8050
|
||||
# networks:
|
||||
# - backend
|
||||
# depends_on:
|
||||
# - mongo
|
||||
app:
|
||||
image: visual_critical_discourse_analysis:dev
|
||||
container_name: visual_critical_discourse_analysis
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./web_ui/Dockerfile
|
||||
env_file:
|
||||
- local.env
|
||||
environment:
|
||||
- ENV=DEV
|
||||
ports:
|
||||
- 8050:8050
|
||||
networks:
|
||||
- backend
|
||||
depends_on:
|
||||
- mongo
|
||||
mongo:
|
||||
image: mongo:latest
|
||||
container_name: mongo
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
version: '3.7'
|
||||
services:
|
||||
app:
|
||||
image: visual_critical_discourse_analysis:dev
|
||||
container_name: visual_critical_discourse_analysis
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
dockerfile: ./web_ui/Dockerfile
|
||||
env_file:
|
||||
- server.env
|
||||
ports:
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
from .classes import VisualSyntaxModelOutput
|
||||
@@ -1,89 +0,0 @@
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from typing import List
|
||||
import random
|
||||
|
||||
|
||||
class OptionNotSetException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class ModelOutput(BaseModel):
|
||||
|
||||
@classmethod
|
||||
def classname(cls) -> str:
|
||||
"""Return classname."""
|
||||
return cls.__name__
|
||||
|
||||
@classmethod
|
||||
def list_fields(cls) -> List[str]:
|
||||
"""List options that are stored as attributes."""
|
||||
return list(cls.model_fields.keys())
|
||||
|
||||
@classmethod
|
||||
def from_random(cls):
|
||||
"""Instantiate with random numbers."""
|
||||
kwargs = {field: random.random() for field in cls.list_fields()}
|
||||
return cls(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def from_choice(cls, option: str):
|
||||
"""Instantiate from choice."""
|
||||
if option is None:
|
||||
raise ValidationError()
|
||||
assert isinstance(option, str), "option is not a string"
|
||||
allowed_options_list = cls.list_fields()
|
||||
assert option in allowed_options_list, \
|
||||
f"{option} is not among allowed fields {allowed_options_list}"
|
||||
kwargs = {field: 0 for field in cls.list_fields()}
|
||||
kwargs[option] = 1
|
||||
return cls(**kwargs)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
model_dict = self.model_dump()
|
||||
model_repr_str = f"{self.classname()}("
|
||||
model_repr_str += ", ".join([
|
||||
f"{field}={value:.3f}"
|
||||
for field, value
|
||||
in model_dict.items()
|
||||
])
|
||||
model_repr_str += ")"
|
||||
return model_repr_str
|
||||
|
||||
def highest_score_field(self) -> str:
|
||||
"""Return name of field with highest score."""
|
||||
model_dict = self.model_dump()
|
||||
return max(model_dict, key=lambda k: model_dict[k])
|
||||
|
||||
def highest_score_value(self) -> float:
|
||||
"""Return value of field with highest score."""
|
||||
model_dict = self.model_dump()
|
||||
return max(model_dict.values())
|
||||
|
||||
|
||||
class VisualSyntaxModelOutput(ModelOutput):
|
||||
non_transactional_action: float
|
||||
non_transactional_reaction: float
|
||||
unidirectional_transactional_action: float
|
||||
unidirectional_transactional_reaction: float
|
||||
bidirectional_transactional_action: float
|
||||
bidirectional_transactional_reaction: float
|
||||
conversion: float
|
||||
speech_process: float
|
||||
classification_overt_taxonomy: float
|
||||
analytical_exhaustive: float
|
||||
analytical_disarranged: float
|
||||
analytical_temporal: float
|
||||
analytical_distributed: float
|
||||
analytical_topological: float
|
||||
analytical_exploded: float
|
||||
analytical_inclusive: float
|
||||
symbolic_suggestive: float
|
||||
symbolic_attributive: float
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
m = VisualSyntaxModelOutput.from_random()
|
||||
print(m)
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
@@ -1,20 +0,0 @@
|
||||
CLASS_NAMES = [
|
||||
"non transactional action",
|
||||
"non transactional reaction",
|
||||
"unidirectional transactional action",
|
||||
"unidirectional transactional reaction",
|
||||
"bidirectional transactional action",
|
||||
"bidirectional transactional reaction",
|
||||
"conversion",
|
||||
"speech process",
|
||||
"classification overt taxonomy",
|
||||
"analytical exhaustive",
|
||||
"analytical disarranged",
|
||||
"analytical temporal",
|
||||
"analytical distributed",
|
||||
"anaytical topological",
|
||||
"analytical exploded",
|
||||
"analytical inclusive",
|
||||
"symbolic suggestive",
|
||||
"symbolic attributive"
|
||||
]
|
||||
@@ -1,9 +0,0 @@
|
||||
from .classes import (
|
||||
ContactModelOutput,
|
||||
AngleModelOutput,
|
||||
PointOfViewModelOutput,
|
||||
DistanceModelOutput,
|
||||
ModalityLightingModelOutput,
|
||||
ModalityColorModelOutput,
|
||||
ModalityDepthModelOutput
|
||||
)
|
||||
@@ -1,137 +0,0 @@
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from typing import List
|
||||
import random
|
||||
|
||||
|
||||
class ModelOutput(BaseModel):
|
||||
|
||||
@classmethod
|
||||
def classname(cls) -> str:
|
||||
"""Return classname."""
|
||||
return cls.__name__
|
||||
|
||||
@classmethod
|
||||
def list_fields(cls) -> List[str]:
|
||||
"""List options that are stored as attributes."""
|
||||
return list(cls.model_fields.keys())
|
||||
|
||||
@classmethod
|
||||
def from_random(cls):
|
||||
"""Instantiate with random numbers."""
|
||||
kwargs = {field: random.random() for field in cls.list_fields()}
|
||||
return cls(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def from_choice(cls, option: str):
|
||||
"""Instantiate from choice."""
|
||||
if option is None:
|
||||
raise ValidationError()
|
||||
assert isinstance(option, str)
|
||||
allowed_options_list = cls.list_fields()
|
||||
assert option in allowed_options_list, \
|
||||
f"{option} is not among allowed fields {allowed_options_list}"
|
||||
kwargs = {field: 0 for field in cls.list_fields()}
|
||||
kwargs[option] = 1
|
||||
return cls(**kwargs)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
model_dict = self.model_dump()
|
||||
model_repr_str = f"{self.classname()}("
|
||||
model_repr_str += ", ".join([
|
||||
f"{field}={value:.3f}"
|
||||
for field, value
|
||||
in model_dict.items()
|
||||
])
|
||||
model_repr_str += ")"
|
||||
return model_repr_str
|
||||
|
||||
def highest_score_field(self) -> str:
|
||||
"""Return name of field with highest score."""
|
||||
model_dict = self.model_dump()
|
||||
return max(model_dict, key=lambda k: model_dict[k])
|
||||
|
||||
def highest_score_value(self) -> float:
|
||||
"""Return value of field with highest score."""
|
||||
model_dict = self.model_dump()
|
||||
return max(model_dict.values())
|
||||
|
||||
|
||||
class ContactModelOutput(ModelOutput):
|
||||
offer: float
|
||||
demand: float
|
||||
|
||||
|
||||
class AngleModelOutput(ModelOutput):
|
||||
high: float
|
||||
eye_level: float
|
||||
low: float
|
||||
|
||||
|
||||
class PointOfViewModelOutput(ModelOutput):
|
||||
frontal: float
|
||||
oblique: float
|
||||
|
||||
|
||||
class DistanceModelOutput(ModelOutput):
|
||||
long: float
|
||||
medium: float
|
||||
close: float
|
||||
|
||||
|
||||
class ModalityLightingModelOutput(ModelOutput):
|
||||
high: float
|
||||
medium: float
|
||||
low: float
|
||||
|
||||
|
||||
class ModalityColorModelOutput(ModelOutput):
|
||||
high: float
|
||||
medium: float
|
||||
low: float
|
||||
|
||||
|
||||
class ModalityDepthModelOutput(ModelOutput):
|
||||
high: float
|
||||
medium: float
|
||||
low: float
|
||||
|
||||
|
||||
# class InterpersonalModelOutput(BaseModel):
|
||||
# contact: ContactModelOutput
|
||||
# angle: AngleModelOutput
|
||||
# point_of_view: PointOfViewModelOutput
|
||||
# distance: DistanceModelOutput
|
||||
# modality_lighting: ModalityLightingModelOutput
|
||||
# modality_color: ModalityColorModelOutput
|
||||
# modality_depth: ModalityDepthModelOutput
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
m = ContactModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = AngleModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = PointOfViewModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = DistanceModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = ModalityLightingModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = ModalityColorModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = ModalityDepthModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
@@ -1,36 +0,0 @@
|
||||
|
||||
model_labels = {
|
||||
"contact": [
|
||||
"offer",
|
||||
"demand"
|
||||
],
|
||||
"angle": [
|
||||
"high",
|
||||
"eye-level",
|
||||
"low"
|
||||
],
|
||||
"point-of-view": [
|
||||
"frontal",
|
||||
"oblique"
|
||||
],
|
||||
"distance": [
|
||||
"long",
|
||||
"medium",
|
||||
"close"
|
||||
],
|
||||
"modality lighting": [
|
||||
"high",
|
||||
"medium",
|
||||
"low"
|
||||
],
|
||||
"modality color": [
|
||||
"high",
|
||||
"medium",
|
||||
"low"
|
||||
],
|
||||
"modality depth": [
|
||||
"high",
|
||||
"medium",
|
||||
"low"
|
||||
]
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
from .classes import (
|
||||
InformationValueModelOutput,
|
||||
FramingModelOutput,
|
||||
SalienceModelOutput
|
||||
)
|
||||
@@ -1,92 +0,0 @@
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from typing import List
|
||||
import random
|
||||
|
||||
|
||||
class ModelOutput(BaseModel):
|
||||
|
||||
@classmethod
|
||||
def classname(cls) -> str:
|
||||
"""Return classname."""
|
||||
return cls.__name__
|
||||
|
||||
@classmethod
|
||||
def list_fields(cls) -> List[str]:
|
||||
"""List options that are stored as attributes."""
|
||||
return list(cls.model_fields.keys())
|
||||
|
||||
@classmethod
|
||||
def from_random(cls):
|
||||
"""Instantiate with random numbers."""
|
||||
kwargs = {field: random.random() for field in cls.list_fields()}
|
||||
return cls(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def from_choice(cls, option: str):
|
||||
"""Instantiate from choice."""
|
||||
if option is None:
|
||||
raise ValidationError()
|
||||
assert isinstance(option, str)
|
||||
allowed_options_list = cls.list_fields()
|
||||
assert option in allowed_options_list, \
|
||||
f"{option} is not among allowed fields {allowed_options_list}"
|
||||
kwargs = {field: 0 for field in cls.list_fields()}
|
||||
kwargs[option] = 1
|
||||
return cls(**kwargs)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
model_dict = self.model_dump()
|
||||
model_repr_str = f"{self.classname()}("
|
||||
model_repr_str += ", ".join([
|
||||
f"{field}={value:.3f}"
|
||||
for field, value
|
||||
in model_dict.items()
|
||||
])
|
||||
model_repr_str += ")"
|
||||
return model_repr_str
|
||||
|
||||
def highest_score_field(self) -> str:
|
||||
"""Return name of field with highest score."""
|
||||
model_dict = self.model_dump()
|
||||
return max(model_dict, key=lambda k: model_dict[k])
|
||||
|
||||
def highest_score_value(self) -> float:
|
||||
"""Return value of field with highest score."""
|
||||
model_dict = self.model_dump()
|
||||
return max(model_dict.values())
|
||||
|
||||
|
||||
class InformationValueModelOutput(ModelOutput):
|
||||
given_new: float
|
||||
ideal_real: float
|
||||
central_marginal: float
|
||||
|
||||
|
||||
class FramingModelOutput(ModelOutput):
|
||||
frame_lines: float
|
||||
empty_space: float
|
||||
colour_contrast: float
|
||||
form_contrast: float
|
||||
|
||||
|
||||
class SalienceModelOutput(ModelOutput):
|
||||
size: float
|
||||
colour: float
|
||||
tone: float
|
||||
form: float
|
||||
positioning: float
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
m = InformationValueModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = FramingModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = SalienceModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
model_labels = {
|
||||
"information value": [
|
||||
"given-new",
|
||||
"ideal-real",
|
||||
"central-marginal"
|
||||
],
|
||||
"framing": [
|
||||
"frame lines",
|
||||
"empty space",
|
||||
"colour contrast",
|
||||
"form contrast"
|
||||
],
|
||||
"salience": [
|
||||
"size",
|
||||
"colour",
|
||||
"tone",
|
||||
"form",
|
||||
"positioning"
|
||||
]
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from src.web.app import app
|
||||
from src.web.app import server
|
||||
@@ -1 +0,0 @@
|
||||
from .layout import app_layout
|
||||
@@ -1,21 +0,0 @@
|
||||
import dash_mantine_components as dmc
|
||||
from dash import html
|
||||
from pathlib import Path
|
||||
from base64 import b64encode
|
||||
|
||||
# read init img
|
||||
init_img_path = Path(__file__).parent / "init_img.png"
|
||||
with open(init_img_path.absolute(), "rb") as fh:
|
||||
init_img_enc = b64encode(fh.read()).decode("utf-8")
|
||||
# generate init img string
|
||||
init_img_src = f"data:image/png;base64, {init_img_enc}"
|
||||
|
||||
image_element = dmc.Center(
|
||||
html.Img(
|
||||
style={
|
||||
"width": "100%",
|
||||
},
|
||||
id="image-container",
|
||||
src=init_img_src
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,57 @@
|
||||
# build stage
|
||||
FROM python:3.12-slim-bookworm as BUILDER
|
||||
|
||||
# set environment variables
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
PYTHONDONTWRITEBYTECODE=1 \
|
||||
PIP_NO_CACHE_DIR=off \
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=ON \
|
||||
PIP_DEFAULT_TIMEOUT=100 \
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
POETRY_HOME=/etc/poetry \
|
||||
POETRY_VERSION=1.7.1 \
|
||||
POETRY_VIRTUALENVS_IN_PROJECT=1 \
|
||||
POETRY_VIRTUALENVS_CREATE=1 \
|
||||
POETRY_NO_INTERACTION=1 \
|
||||
POETRY_CACHE_DIR=/tmp/poetry_cache \
|
||||
APP_HOME=/home/app
|
||||
|
||||
# update system
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
curl \
|
||||
&& apt-get clean
|
||||
|
||||
# install poetry
|
||||
RUN curl -sSL https://install.python-poetry.org | python3 -
|
||||
ENV PATH="${POETRY_HOME}/bin:$PATH"
|
||||
|
||||
# install runtime dependencies
|
||||
WORKDIR ${APP_HOME}
|
||||
COPY poetry.lock pyproject.toml ./
|
||||
RUN --mount=type=cache,target=${POETRY_CACHE_DIR} poetry install --without model
|
||||
|
||||
# final stage
|
||||
FROM python:3.12-slim-bookworm
|
||||
|
||||
# copy virtualenv made by poetry
|
||||
ENV APP_HOME=/home/app \
|
||||
VIRTUAL_ENV=/home/app/.venv
|
||||
COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}
|
||||
ENV PATH="${VIRTUAL_ENV}/bin:${PATH}"
|
||||
|
||||
# create home directory and app user
|
||||
RUN mkdir -p /home/app && \
|
||||
addgroup --system app && \
|
||||
adduser --system --group app
|
||||
|
||||
# add code while changing ownership
|
||||
WORKDIR $APP_HOME
|
||||
COPY --chown=app:app ./core ./core
|
||||
COPY --chown=app:app ./web_ui/src ./src
|
||||
|
||||
# change to the app user
|
||||
USER app
|
||||
|
||||
ENTRYPOINT [ "gunicorn", "src.main:server", "-b", "0.0.0.0:8050" ]
|
||||
@@ -0,0 +1,3 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .app import app
|
||||
@@ -245,3 +245,7 @@ def cycle_visual_communication_data(
|
||||
response[3] = annotation_values
|
||||
logging.info('finished getting visual communication: %s', vis_com_name)
|
||||
return tuple(response)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
||||
@@ -0,0 +1,3 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .layout import app_layout
|
||||
@@ -1,3 +1,5 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import dash_mantine_components as dmc
|
||||
|
||||
from .image import image_element
|
||||
@@ -11,8 +13,8 @@ body_element = dmc.Container(
|
||||
grow=True,
|
||||
children=[
|
||||
dmc.Col([image_element], span=5),
|
||||
dmc.Col([inputs_element], span=7)
|
||||
dmc.Col([inputs_element], span=7),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,24 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from base64 import b64encode
|
||||
from pathlib import Path
|
||||
|
||||
import dash_mantine_components as dmc
|
||||
from dash import html
|
||||
|
||||
# read init img
|
||||
init_img_path = Path(__file__).parent / 'init_img.png'
|
||||
with open(init_img_path.absolute(), 'rb') as fh:
|
||||
init_img_enc = b64encode(fh.read()).decode('utf-8')
|
||||
# generate init img string
|
||||
init_img_src = f"data:image/png;base64, {init_img_enc}"
|
||||
|
||||
image_element = dmc.Center(
|
||||
html.Img(
|
||||
style={
|
||||
'width': '100%',
|
||||
},
|
||||
id='image-container',
|
||||
src=init_img_src,
|
||||
),
|
||||
)
|
||||
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
@@ -1,23 +1,25 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import dash_mantine_components as dmc
|
||||
|
||||
from .labels import labels_element
|
||||
|
||||
next_button = dmc.Button(
|
||||
"next".title(),
|
||||
id="next-button",
|
||||
'next'.title(),
|
||||
id='next-button',
|
||||
n_clicks=0,
|
||||
fullWidth=True,
|
||||
color="lime",
|
||||
radius="sm",
|
||||
size="md",
|
||||
color='lime',
|
||||
radius='sm',
|
||||
size='md',
|
||||
style={
|
||||
"height": "50px"
|
||||
}
|
||||
'height': '50px',
|
||||
},
|
||||
)
|
||||
|
||||
inputs_element = dmc.SimpleGrid(
|
||||
children=[
|
||||
labels_element,
|
||||
next_button
|
||||
]
|
||||
next_button,
|
||||
],
|
||||
)
|
||||
@@ -1,22 +1,24 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import dash_mantine_components as dmc
|
||||
|
||||
from .stores import stores_element
|
||||
from .alerts import alerts_element
|
||||
from .header import header_element
|
||||
from .body import body_element
|
||||
from .header import header_element
|
||||
from .stores import stores_element
|
||||
|
||||
|
||||
app_layout = dmc.MantineProvider(
|
||||
theme={
|
||||
"fontFamily": '"Inter", sans-serif',
|
||||
"components": {
|
||||
"NavLink": {
|
||||
"styles": {
|
||||
"label": {
|
||||
"color": "#c2c7d0"
|
||||
}
|
||||
}
|
||||
}
|
||||
'fontFamily': '"Inter", sans-serif',
|
||||
'components': {
|
||||
'NavLink': {
|
||||
'styles': {
|
||||
'label': {
|
||||
'color': '#c2c7d0',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
children=[
|
||||
@@ -27,8 +29,8 @@ app_layout = dmc.MantineProvider(
|
||||
header_element,
|
||||
body_element,
|
||||
],
|
||||
fluid=True
|
||||
fluid=True,
|
||||
),
|
||||
|
||||
]
|
||||
],
|
||||
)
|
||||
@@ -6,10 +6,10 @@ from pathlib import Path
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from src.web import app
|
||||
from .app import app
|
||||
|
||||
# prepare optional local setup
|
||||
env_path = Path(__file__).parent.parent / 'local.env'
|
||||
env_path = Path(__file__).parent.parent.parent / 'local.env'
|
||||
load_dotenv(env_path)
|
||||
|
||||
# ensure env vars set
|
||||
@@ -31,18 +31,19 @@ for env_var in necesasary_var_list:
|
||||
)
|
||||
|
||||
# setup logging stream handler
|
||||
fmt = (
|
||||
FMT = (
|
||||
'%(asctime)s | '
|
||||
'%(levelname)s | '
|
||||
'%(filename)s | '
|
||||
'%(funcName)s | '
|
||||
'%(message)s'
|
||||
)
|
||||
datefmt = '%Y-%m-%d %H:%M:%S'
|
||||
logging.basicConfig(format=fmt, datefmt=datefmt, level=logging.INFO)
|
||||
DATEFMT = '%Y-%m-%d %H:%M:%S'
|
||||
logging.basicConfig(format=FMT, datefmt=DATEFMT, level=logging.INFO)
|
||||
|
||||
logging.info('initialized app')
|
||||
server = app.server
|
||||
server.config.update(SECRET_KEY=os.urandom(24))
|
||||
|
||||
if __name__ == '__main__':
|
||||
# prepare local env vars
|
||||
Reference in New Issue
Block a user