moved webui and updated poetry packages
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
"""Database module content."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .classes.dataset import Dataset
|
||||
from .classes.exceptions import NoDocumentFoundException
|
||||
from .classes.visual_communication import VisualCommunication
|
||||
from .utils.connect import connect
|
||||
from .utils.count_documents import count_documents
|
||||
from .utils.get_visual_communication import get_visual_communication
|
||||
from .utils.list_names import list_names
|
||||
from .utils.upsert_annotation import upsert_annotation
|
||||
from .utils.upsert_prediction import upsert_prediction
|
||||
from .utils.upsert_visual_communication import upsert_visual_communication
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
"""Database classes module content."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .dataset import Dataset
|
||||
from .exceptions import NoDocumentFoundException
|
||||
from .visual_communication import VisualCommunication
|
||||
Executable
+71
@@ -0,0 +1,71 @@
|
||||
"""Definition of database Dataset class."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import random
|
||||
from datetime import datetime
|
||||
from datetime import UTC
|
||||
|
||||
from pydantic import BaseModel
|
||||
from pydantic import Field
|
||||
from pymongo.collection import Collection
|
||||
|
||||
|
||||
class Dataset(BaseModel):
|
||||
"""Database Dataset model."""
|
||||
create_time: datetime = Field(default_factory=lambda: datetime.now(UTC))
|
||||
train_names: list[str]
|
||||
test_names: list[str]
|
||||
validation_names: list[str]
|
||||
|
||||
@classmethod
|
||||
def fraction_map(cls) -> dict[str, float]:
|
||||
"""Dict with train, test and validation fractions."""
|
||||
# define map
|
||||
split_map = {
|
||||
'train': 0.7,
|
||||
'test': 0.2,
|
||||
'validation': 0.1,
|
||||
}
|
||||
# sanity check
|
||||
assert sum(split_map.values()) == 1.0
|
||||
return split_map
|
||||
|
||||
@classmethod
|
||||
def new_from_name_list(
|
||||
cls,
|
||||
name_list: list[str],
|
||||
) -> Dataset:
|
||||
"""Generate new dataset from list of filenames."""
|
||||
# calculate split fractions
|
||||
fraction_map = cls.fraction_map()
|
||||
num_total = len(name_list)
|
||||
num_validation = round(num_total * fraction_map['validation'])
|
||||
num_test = round(num_total * fraction_map['test'])
|
||||
# split data
|
||||
validation_name_list = random.choices(name_list, k=num_validation)
|
||||
name_list = [
|
||||
name for name in name_list if name not in validation_name_list
|
||||
]
|
||||
test_name_list = random.choices(name_list, k=num_test)
|
||||
train_name_list = [
|
||||
name for name in name_list if name not in test_name_list
|
||||
]
|
||||
# instantiate object
|
||||
dataset = Dataset(
|
||||
train_names=train_name_list,
|
||||
test_names=test_name_list,
|
||||
validation_names=validation_name_list,
|
||||
)
|
||||
logging.debug('finished')
|
||||
return dataset
|
||||
|
||||
def save(
|
||||
self,
|
||||
collection: Collection,
|
||||
) -> None:
|
||||
"""Save dataset to database."""
|
||||
res = collection.insert_one(
|
||||
document=self.model_dump(),
|
||||
)
|
||||
logging.debug('inserted document: %s', res)
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
"""Definition of database exception."""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
class NoDocumentFoundException(Exception):
|
||||
"""Database exception for when no documents are found."""
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
"""Definition of VisualCommunication model."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from base64 import b64decode
|
||||
from base64 import b64encode
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image
|
||||
from pydantic import BaseModel
|
||||
from pydantic import field_serializer
|
||||
from pydantic import field_validator
|
||||
|
||||
from shared.dto import ModelData
|
||||
|
||||
|
||||
class VisualCommunication(BaseModel):
|
||||
"""Visual communication model."""
|
||||
|
||||
name: str
|
||||
image: Image.Image
|
||||
annotation: ModelData | None = None
|
||||
prediction: ModelData | None = None
|
||||
|
||||
class Config:
|
||||
"""BaseModel configuration."""
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
@classmethod
|
||||
def classname(cls) -> str:
|
||||
"""Return classname."""
|
||||
return cls.__name__
|
||||
|
||||
@classmethod
|
||||
def from_file(cls, path: Path) -> VisualCommunication:
|
||||
"""Instantiate from file."""
|
||||
name = path.stem
|
||||
image = Image.open(path)
|
||||
image.load()
|
||||
return VisualCommunication(name=name, image=image)
|
||||
|
||||
@classmethod
|
||||
def decode_image(cls, content: str) -> Image.Image:
|
||||
"""Extract image from webencoded content."""
|
||||
_, content_data = content.split(',')
|
||||
return Image.open(BytesIO(b64decode(content_data)))
|
||||
|
||||
@field_serializer('image')
|
||||
@classmethod
|
||||
def serialize_image(cls, image: Image.Image) -> bytes: # type: ignore
|
||||
"""Convert image to bytes for storage in database."""
|
||||
buffer = BytesIO()
|
||||
image.save(buffer, format='JPEG')
|
||||
return buffer.getvalue()
|
||||
|
||||
@field_validator('image', mode='before')
|
||||
@classmethod
|
||||
def convert_to_image(
|
||||
cls,
|
||||
image: Image.Image | BytesIO | bytes,
|
||||
) -> Image.Image:
|
||||
"""Convert bytes input from database into image."""
|
||||
if isinstance(image, bytes):
|
||||
image = BytesIO(image)
|
||||
if isinstance(image, BytesIO):
|
||||
image = Image.open(image)
|
||||
return image
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"{self.classname()}(name='{self.name}')"
|
||||
|
||||
def webencoded_image(self) -> str:
|
||||
"""Convert image to be displayed on webpage."""
|
||||
# convert images to bytes string
|
||||
buffer = BytesIO()
|
||||
self.image.save(buffer, format='png')
|
||||
img_enc = b64encode(buffer.getvalue()).decode('utf-8')
|
||||
return f"data:image/png;base64, {img_enc}"
|
||||
|
||||
def generate_random_prediction(self, force: bool = False) -> None:
|
||||
"""Generate random prediction values."""
|
||||
if not force and self.prediction is not None:
|
||||
logging.warning('set force=True to overwrite existing values.')
|
||||
self.prediction = ModelData.from_random()
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
"""Database utils module content."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .connect import connect
|
||||
@@ -0,0 +1,33 @@
|
||||
"""
|
||||
Definition of function to connect to database
|
||||
using environment variables.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from pymongo import MongoClient
|
||||
|
||||
|
||||
def connect():
|
||||
"""Connect to MongoDB using env vars."""
|
||||
# load env vars
|
||||
load_dotenv()
|
||||
necessary_env_vars = [
|
||||
'MONGO_HOST',
|
||||
'MONGO_DB',
|
||||
'MONGO_COLLECTION',
|
||||
]
|
||||
for env_var in necessary_env_vars:
|
||||
assert env_var in os.environ, f"{env_var} not found"
|
||||
# connect to database
|
||||
client = MongoClient(os.getenv('MONGO_HOST'))
|
||||
db = client[os.getenv('MONGO_DB')]
|
||||
# extract collection
|
||||
collection = db[os.getenv('MONGO_COLLECTION')]
|
||||
# set unique index on "name"
|
||||
collection.create_index('name', unique=True)
|
||||
logging.debug('finished')
|
||||
return collection, db, client
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
"""Definition of function to count documents in database."""
|
||||
from __future__ import annotations
|
||||
|
||||
from pymongo.collection import Collection
|
||||
|
||||
|
||||
def count_documents(
|
||||
collection: Collection,
|
||||
only_with_annotation: bool = False,
|
||||
) -> int:
|
||||
"""
|
||||
Get the total number of documents
|
||||
in database that matches the filters.
|
||||
"""
|
||||
assert isinstance(collection, Collection)
|
||||
assert isinstance(only_with_annotation, bool)
|
||||
# build query
|
||||
query = {}
|
||||
if only_with_annotation:
|
||||
query['annotation'] = {'$ne': None}
|
||||
return collection.count_documents(filter=query)
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Literal
|
||||
|
||||
from pymongo.collection import Collection
|
||||
|
||||
|
||||
def get_dataset(
|
||||
collection: Collection,
|
||||
type: Literal['train', 'test', 'validation'],
|
||||
) -> list[str]:
|
||||
"""Get list of data names for the corresponding type."""
|
||||
return []
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
"""Definition of function to get visual communication from database."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from pymongo.collection import Collection
|
||||
|
||||
from shared.database import NoDocumentFoundException
|
||||
from shared.database import VisualCommunication
|
||||
|
||||
|
||||
def get_visual_communication(
|
||||
collection: Collection,
|
||||
with_annotation: bool = False,
|
||||
) -> VisualCommunication:
|
||||
"""Get a random visual communication from the database."""
|
||||
query = {}
|
||||
if with_annotation:
|
||||
query['annotation'] = {'$ne': None}
|
||||
else:
|
||||
query['annotation'] = {'$eq': None}
|
||||
data = collection.aggregate(
|
||||
pipeline=[
|
||||
{
|
||||
'$match': query, # find using filters
|
||||
},
|
||||
{
|
||||
'$sample': {
|
||||
'size': 1, # get one random
|
||||
},
|
||||
},
|
||||
],
|
||||
)
|
||||
data_list = list(data) # read data from cursor object
|
||||
if len(data_list) == 0:
|
||||
raise NoDocumentFoundException()
|
||||
vis_com = VisualCommunication.model_validate(data_list[0])
|
||||
logging.debug('finished')
|
||||
return vis_com
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
"""
|
||||
Definition of function to list names
|
||||
of all visual communication documents in database.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from pymongo.collection import Collection
|
||||
|
||||
|
||||
def list_names(
|
||||
collection: Collection,
|
||||
only_with_annotation: bool = True,
|
||||
) -> list[str]:
|
||||
"""List the names of entries that match the filters."""
|
||||
assert isinstance(collection, Collection)
|
||||
assert isinstance(only_with_annotation, bool)
|
||||
# build query
|
||||
query = {}
|
||||
if only_with_annotation:
|
||||
query['annotation'] = {'$ne': None}
|
||||
# execute query
|
||||
res_list = collection.find(
|
||||
filter=query,
|
||||
projection={
|
||||
'_id': False,
|
||||
'name': True,
|
||||
},
|
||||
)
|
||||
# extract information
|
||||
name_list = [elem['name'] for elem in res_list]
|
||||
return name_list
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from pymongo.collection import Collection
|
||||
|
||||
from shared.database import Dataset
|
||||
|
||||
|
||||
def save_dataset(
|
||||
collection: Collection,
|
||||
dataset: Dataset,
|
||||
) -> None:
|
||||
"""Save dataset to database."""
|
||||
res = collection.insert_one(
|
||||
document=dataset.model_dump(),
|
||||
)
|
||||
logging.debug('inserted document: %s', res)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv('local.env')
|
||||
from shared.database import list_names, connect
|
||||
# connect to database
|
||||
collection, db, client = connect()
|
||||
print(client.server_info())
|
||||
|
||||
name_list = list_names(collection=collection, only_with_annotation=True)
|
||||
ds = Dataset.new_from_name_list(name_list=name_list)
|
||||
|
||||
print(ds)
|
||||
# save_dataset(
|
||||
# collection=collection,
|
||||
# dataset=ds
|
||||
# )
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from pymongo.collection import Collection
|
||||
|
||||
from shared.dto import ModelData
|
||||
|
||||
|
||||
def upsert_annotation(
|
||||
collection: Collection,
|
||||
vis_com_name: str,
|
||||
annotations: ModelData,
|
||||
) -> None:
|
||||
"""Upserts annotation data in the database."""
|
||||
query = {
|
||||
'name': vis_com_name,
|
||||
}
|
||||
update = {
|
||||
'$set': {
|
||||
'annotation': annotations.model_dump(),
|
||||
},
|
||||
}
|
||||
res = collection.update_one(
|
||||
filter=query,
|
||||
update=update,
|
||||
upsert=True,
|
||||
)
|
||||
logging.info('upserted document: %s', res)
|
||||
logging.info('finished')
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from pymongo.collection import Collection
|
||||
|
||||
from shared.dto import ModelData
|
||||
|
||||
|
||||
def upsert_prediction(
|
||||
collection: Collection,
|
||||
vis_com_name: str,
|
||||
predictions: ModelData,
|
||||
) -> None:
|
||||
"""Upsert prediction data in the database."""
|
||||
query = {
|
||||
'name': vis_com_name,
|
||||
}
|
||||
update = {
|
||||
'$set': {
|
||||
'prediction': predictions.model_dump(),
|
||||
},
|
||||
}
|
||||
res = collection.update_one(
|
||||
filter=query,
|
||||
update=update,
|
||||
upsert=True,
|
||||
)
|
||||
logging.debug('upserted document: %s', res)
|
||||
logging.info('finished')
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pymongo.collection import Collection
|
||||
|
||||
from shared.database import VisualCommunication
|
||||
|
||||
|
||||
def upsert_visual_communication(
|
||||
collection: Collection,
|
||||
visual_communication_list: list[VisualCommunication],
|
||||
) -> bool:
|
||||
"""
|
||||
Upsert VisualCommunication object in the database.
|
||||
Returns bool stating success.
|
||||
"""
|
||||
response = collection.insert_many(
|
||||
[
|
||||
vis_com.model_dump()
|
||||
for vis_com
|
||||
in visual_communication_list
|
||||
],
|
||||
)
|
||||
return response.acknowledged
|
||||
@@ -0,0 +1,15 @@
|
||||
"""Data transfer objects module content."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .angle import AngleData
|
||||
from .contact import ContactData
|
||||
from .distance import DistanceData
|
||||
from .framing import FramingData
|
||||
from .information_value import InformationValueData
|
||||
from .modality_color import ModalityColorData
|
||||
from .modality_depth import ModalityDepthData
|
||||
from .modality_lighting import ModalityLightingData
|
||||
from .model_data import ModelData
|
||||
from .point_of_view import PointOfViewData
|
||||
from .salience import SalienceData
|
||||
from .visual_syntax import VisualSyntaxData
|
||||
@@ -0,0 +1,11 @@
|
||||
"""Definition of Angle data model."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .data_model import DataModel
|
||||
|
||||
|
||||
class AngleData(DataModel):
|
||||
"""Angle data model."""
|
||||
high: float
|
||||
eye_level: float
|
||||
low: float
|
||||
@@ -0,0 +1,11 @@
|
||||
"""Definition of ContactData data model."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .data_model import DataModel
|
||||
|
||||
|
||||
class ContactData(DataModel):
|
||||
"""ContactData data model."""
|
||||
|
||||
offer: float
|
||||
demand: float
|
||||
@@ -0,0 +1,67 @@
|
||||
"""Definition of DataModel base class."""
|
||||
from __future__ import annotations
|
||||
|
||||
import random
|
||||
|
||||
from pydantic import BaseModel
|
||||
from pydantic import ValidationError
|
||||
|
||||
|
||||
class DataModel(BaseModel):
|
||||
"""DataModel base class."""
|
||||
|
||||
@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)
|
||||
|
||||
@classmethod
|
||||
def from_list(cls, data_list: list[float]):
|
||||
"""Instantiate from list of values."""
|
||||
kwargs = {key: val for key, val in zip(cls.list_fields(), data_list)}
|
||||
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())
|
||||
@@ -0,0 +1,12 @@
|
||||
"""Definition of DistanceData data model."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .data_model import DataModel
|
||||
|
||||
|
||||
class DistanceData(DataModel):
|
||||
"""DistanceData data model."""
|
||||
|
||||
long: float
|
||||
medium: float
|
||||
close: float
|
||||
@@ -0,0 +1,13 @@
|
||||
"""Definition of FramingData data model."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .data_model import DataModel
|
||||
|
||||
|
||||
class FramingData(DataModel):
|
||||
"""FramingData data model."""
|
||||
|
||||
frame_lines: float
|
||||
empty_space: float
|
||||
colour_contrast: float
|
||||
form_contrast: float
|
||||
@@ -0,0 +1,12 @@
|
||||
"""Definition of InformationValueData data model."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .data_model import DataModel
|
||||
|
||||
|
||||
class InformationValueData(DataModel):
|
||||
"""InformationValueData data model."""
|
||||
|
||||
given_new: float
|
||||
ideal_real: float
|
||||
central_marginal: float
|
||||
@@ -0,0 +1,12 @@
|
||||
"""Definition of ModalityColorData data model."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .data_model import DataModel
|
||||
|
||||
|
||||
class ModalityColorData(DataModel):
|
||||
"""ModalityColorData data model."""
|
||||
|
||||
high: float
|
||||
medium: float
|
||||
low: float
|
||||
@@ -0,0 +1,12 @@
|
||||
"""Definition of ModalityDepthData data model."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .data_model import DataModel
|
||||
|
||||
|
||||
class ModalityDepthData(DataModel):
|
||||
"""ModalityDepthData data model."""
|
||||
|
||||
high: float
|
||||
medium: float
|
||||
low: float
|
||||
@@ -0,0 +1,12 @@
|
||||
"""Definition of ModalityLightingData data model."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .data_model import DataModel
|
||||
|
||||
|
||||
class ModalityLightingData(DataModel):
|
||||
"""ModalityLightingData data model."""
|
||||
|
||||
high: float
|
||||
medium: float
|
||||
low: float
|
||||
@@ -0,0 +1,82 @@
|
||||
"""Definition of ModelData data model."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .angle import AngleData
|
||||
from .contact import ContactData
|
||||
from .data_model import DataModel
|
||||
from .distance import DistanceData
|
||||
from .framing import FramingData
|
||||
from .information_value import InformationValueData
|
||||
from .modality_color import ModalityColorData
|
||||
from .modality_depth import ModalityDepthData
|
||||
from .modality_lighting import ModalityLightingData
|
||||
from .point_of_view import PointOfViewData
|
||||
from .salience import SalienceData
|
||||
from .visual_syntax import VisualSyntaxData
|
||||
|
||||
|
||||
class ModelData(DataModel):
|
||||
"""ModelData model for data IO with combined ML model."""
|
||||
visual_syntax: VisualSyntaxData
|
||||
contact: ContactData
|
||||
angle: AngleData
|
||||
point_of_view: PointOfViewData
|
||||
distance: DistanceData
|
||||
modality_lighting: ModalityLightingData
|
||||
modality_color: ModalityColorData
|
||||
modality_depth: ModalityDepthData
|
||||
information_value: InformationValueData
|
||||
framing: FramingData
|
||||
salience: SalienceData
|
||||
|
||||
@classmethod
|
||||
def from_random(cls) -> ModelData:
|
||||
"""Instantiate with random numbers."""
|
||||
kwargs = {
|
||||
field: field_info.annotation.from_random() # type: ignore
|
||||
for field, field_info
|
||||
in cls.model_fields.items()
|
||||
}
|
||||
return cls(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def from_annotations(
|
||||
cls,
|
||||
visual_syntax: str,
|
||||
contact: str,
|
||||
angle: str,
|
||||
point_of_view: str,
|
||||
distance: str,
|
||||
modality_lighting: str,
|
||||
modality_color: str,
|
||||
modality_depth: str,
|
||||
information_value: str,
|
||||
framing: str,
|
||||
salience: str,
|
||||
) -> ModelData:
|
||||
"""Instantiate from annotation."""
|
||||
kwargs = {
|
||||
'visual_syntax': VisualSyntaxData
|
||||
.from_choice(visual_syntax),
|
||||
'contact': ContactData
|
||||
.from_choice(contact),
|
||||
'angle': AngleData
|
||||
.from_choice(angle),
|
||||
'point_of_view': PointOfViewData
|
||||
.from_choice(point_of_view),
|
||||
'distance': DistanceData
|
||||
.from_choice(distance),
|
||||
'modality_lighting': ModalityLightingData
|
||||
.from_choice(modality_lighting),
|
||||
'modality_color': ModalityColorData
|
||||
.from_choice(modality_color),
|
||||
'modality_depth': ModalityDepthData
|
||||
.from_choice(modality_depth),
|
||||
'information_value': InformationValueData
|
||||
.from_choice(information_value),
|
||||
'framing': FramingData
|
||||
.from_choice(framing),
|
||||
'salience': SalienceData
|
||||
.from_choice(salience),
|
||||
}
|
||||
return cls(**kwargs)
|
||||
@@ -0,0 +1,11 @@
|
||||
"""Definition of PointOfViewData data model."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .data_model import DataModel
|
||||
|
||||
|
||||
class PointOfViewData(DataModel):
|
||||
"""PointOfViewData data model."""
|
||||
|
||||
frontal: float
|
||||
oblique: float
|
||||
@@ -0,0 +1,14 @@
|
||||
"""Definition of SalienceData data model."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .data_model import DataModel
|
||||
|
||||
|
||||
class SalienceData(DataModel):
|
||||
"""SalienceData data model."""
|
||||
|
||||
size: float
|
||||
colour: float
|
||||
tone: float
|
||||
form: float
|
||||
positioning: float
|
||||
@@ -0,0 +1,27 @@
|
||||
"""Definition of VisualSyntaxData data model."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .data_model import DataModel
|
||||
|
||||
|
||||
class VisualSyntaxData(DataModel):
|
||||
"""VisualSyntaxData data model."""
|
||||
|
||||
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
|
||||
@@ -0,0 +1,4 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .check_env import check_env
|
||||
from .setup_logging import setup_logging
|
||||
@@ -0,0 +1,24 @@
|
||||
"""Definition of check_env function."""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
|
||||
|
||||
def check_env() -> None:
|
||||
"""Check necessary environment variables are set."""
|
||||
necesasary_var_list = {
|
||||
'MONGO_HOST',
|
||||
'MONGO_DB',
|
||||
'MONGO_COLLECTION',
|
||||
'MONGO_USER',
|
||||
'MONGO_PASSWORD',
|
||||
'DASH_AUTH_USERNAME',
|
||||
'DASH_AUTH_PASSWORD',
|
||||
}
|
||||
for env_var in necesasary_var_list:
|
||||
# ensure env var set
|
||||
assert (
|
||||
env_var in os.environ
|
||||
), (
|
||||
f"environment variable not set: {env_var}"
|
||||
)
|
||||
@@ -0,0 +1,21 @@
|
||||
"""Definition of setup_logging function."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
|
||||
def setup_logging() -> None:
|
||||
"""Setup logging."""
|
||||
requested_log_level = os.getenv('LOG_LEVEL', default='info')
|
||||
level = getattr(logging, requested_log_level.upper())
|
||||
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=level)
|
||||
logging.debug('finished')
|
||||
Reference in New Issue
Block a user