flake8 compliant

This commit is contained in:
Brian Bjarke Jensen
2024-02-24 23:42:55 +01:00
parent 993c9a122b
commit fa2230d5cf
23 changed files with 157 additions and 106 deletions
+31 -15
View File
@@ -25,6 +25,11 @@ from src.model_textual import (
SalienceModelOutput SalienceModelOutput
) )
class NoDocumentFoundException(Exception):
pass
class ModelOutputs(BaseModel): class ModelOutputs(BaseModel):
visual_syntax: VisualSyntaxModelOutput visual_syntax: VisualSyntaxModelOutput
contact: ContactModelOutput contact: ContactModelOutput
@@ -70,17 +75,28 @@ class ModelOutputs(BaseModel):
) -> ModelOutputs: ) -> ModelOutputs:
"""Instantiate from annotation.""" """Instantiate from annotation."""
kwargs = { kwargs = {
"visual_syntax": VisualSyntaxModelOutput.from_choice(visual_syntax), "visual_syntax": VisualSyntaxModelOutput
"contact": ContactModelOutput.from_choice(contact), .from_choice(visual_syntax),
"angle": AngleModelOutput.from_choice(angle), "contact": ContactModelOutput
"point_of_view": PointOfViewModelOutput.from_choice(point_of_view), .from_choice(contact),
"distance": DistanceModelOutput.from_choice(distance), "angle": AngleModelOutput
"modality_lighting": ModalityLightingModelOutput.from_choice(modality_lighting), .from_choice(angle),
"modality_color": ModalityColorModelOutput.from_choice(modality_color), "point_of_view": PointOfViewModelOutput
"modality_depth": ModalityDepthModelOutput.from_choice(modality_depth), .from_choice(point_of_view),
"information_value": InformationValueModelOutput.from_choice(information_value), "distance": DistanceModelOutput
"framing": FramingModelOutput.from_choice(framing), .from_choice(distance),
"salience": SalienceModelOutput.from_choice(salience) "modality_lighting": ModalityLightingModelOutput
.from_choice(modality_lighting),
"modality_color": ModalityColorModelOutput
.from_choice(modality_color),
"modality_depth": ModalityDepthModelOutput
.from_choice(modality_depth),
"information_value": InformationValueModelOutput
.from_choice(information_value),
"framing": FramingModelOutput
.from_choice(framing),
"salience": SalienceModelOutput
.from_choice(salience)
} }
return cls(**kwargs) return cls(**kwargs)
@@ -115,7 +131,10 @@ class VisualCommunication(BaseModel):
@field_validator("image", mode="before") @field_validator("image", mode="before")
@classmethod @classmethod
def convert_to_image(cls, image: Image.Image | BytesIO | bytes) -> Image.Image: def convert_to_image(
cls,
image: Image.Image | BytesIO | bytes
) -> Image.Image:
if isinstance(image, bytes): if isinstance(image, bytes):
image = BytesIO(image) image = BytesIO(image)
if isinstance(image, BytesIO): if isinstance(image, BytesIO):
@@ -138,6 +157,3 @@ class VisualCommunication(BaseModel):
if not force and self.prediction is not None: if not force and self.prediction is not None:
logging.warning("set force=True to overwrite existing values.") logging.warning("set force=True to overwrite existing values.")
self.prediction = ModelOutputs.from_random() self.prediction = ModelOutputs.from_random()
class NoDocumentFoundException(Exception):
pass
+18 -6
View File
@@ -20,7 +20,9 @@ def total_annotated(
) -> int: ) -> int:
"""Get total number of annotated documents in database.""" """Get total number of annotated documents in database."""
query = { query = {
"annotation": { "$ne": None } "annotation": {
"$ne": None
}
} }
return collection.count_documents(filter=query) return collection.count_documents(filter=query)
@@ -28,7 +30,7 @@ def total_annotated(
def get_visual_communication( def get_visual_communication(
collection: Collection, collection: Collection,
with_annotation: bool = False with_annotation: bool = False
) -> VisualCommunication: ) -> VisualCommunication:
"""Get a random visual communication from the database.""" """Get a random visual communication from the database."""
query = {} query = {}
if with_annotation: if with_annotation:
@@ -36,8 +38,14 @@ def get_visual_communication(
else: else:
query["annotation"] = None query["annotation"] = None
data = collection.aggregate([ data = collection.aggregate([
{ "$match": query }, # find using filters {
{ "$sample": { "size": 1 } } # get one random "$match": query # find using filters
},
{
"$sample": {
"size": 1 # get one random
}
}
]) ])
data = list(data) # read data from cursor object data = list(data) # read data from cursor object
if len(data) == 0: if len(data) == 0:
@@ -58,7 +66,9 @@ def upsert_predictions(
"name": vis_com_name "name": vis_com_name
} }
update = { update = {
"$set": { "prediction": predictions.model_dump() } "$set": {
"prediction": predictions.model_dump()
}
} }
res = collection.update_one( res = collection.update_one(
filter=query, filter=query,
@@ -79,7 +89,9 @@ def upsert_annotations(
"name": vis_com_name "name": vis_com_name
} }
update = { update = {
"$set": { "annotation": annotations.model_dump() } "$set": {
"annotation": annotations.model_dump()
}
} }
res = collection.update_one( res = collection.update_one(
filter=query, filter=query,
+2 -3
View File
@@ -1,9 +1,10 @@
import logging import logging
from dotenv import load_dotenv from dotenv import load_dotenv
from pathlib import Path from pathlib import Path
import logging
import os import os
from src.web import app
# prepare optional local setup # prepare optional local setup
env_path = Path(__file__).parent.parent / "local.env" env_path = Path(__file__).parent.parent / "local.env"
load_dotenv(env_path) load_dotenv(env_path)
@@ -38,8 +39,6 @@ datefmt = '%Y-%m-%d %H:%M:%S'
logging.basicConfig(format=fmt, datefmt=datefmt, level=logging.INFO) logging.basicConfig(format=fmt, datefmt=datefmt, level=logging.INFO)
logging.info("initialized app") logging.info("initialized app")
from src.web import app
server = app.server server = app.server
if __name__ == "__main__": if __name__ == "__main__":
-23
View File
@@ -1,24 +1 @@
from .classes import VisualSyntaxModelOutput from .classes import VisualSyntaxModelOutput
# CLASS_NAME_LIST = Literal[
# "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"
# ]
+8 -2
View File
@@ -6,6 +6,7 @@ import random
class OptionNotSetException(Exception): class OptionNotSetException(Exception):
pass pass
class ModelOutput(BaseModel): class ModelOutput(BaseModel):
@classmethod @classmethod
@@ -31,7 +32,8 @@ class ModelOutput(BaseModel):
raise ValidationError() raise ValidationError()
assert isinstance(option, str), "option is not a string" assert isinstance(option, str), "option is not a string"
allowed_options_list = cls.list_fields() allowed_options_list = cls.list_fields()
assert option in allowed_options_list, f"{option} is not among allowed fields {allowed_options_list}" 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 = {field: 0 for field in cls.list_fields()}
kwargs[option] = 1 kwargs[option] = 1
return cls(**kwargs) return cls(**kwargs)
@@ -39,7 +41,11 @@ class ModelOutput(BaseModel):
def __repr__(self) -> str: def __repr__(self) -> str:
model_dict = self.model_dump() model_dict = self.model_dump()
model_repr_str = f"{self.classname()}(" model_repr_str = f"{self.classname()}("
model_repr_str += ", ".join([f"{field}={value:.3f}" for field, value in model_dict.items()]) model_repr_str += ", ".join([
f"{field}={value:.3f}"
for field, value
in model_dict.items()
])
model_repr_str += ")" model_repr_str += ")"
return model_repr_str return model_repr_str
+7 -2
View File
@@ -28,7 +28,8 @@ class ModelOutput(BaseModel):
raise ValidationError() raise ValidationError()
assert isinstance(option, str) assert isinstance(option, str)
allowed_options_list = cls.list_fields() allowed_options_list = cls.list_fields()
assert option in allowed_options_list, f"{option} is not among allowed fields {allowed_options_list}" 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 = {field: 0 for field in cls.list_fields()}
kwargs[option] = 1 kwargs[option] = 1
return cls(**kwargs) return cls(**kwargs)
@@ -36,7 +37,11 @@ class ModelOutput(BaseModel):
def __repr__(self) -> str: def __repr__(self) -> str:
model_dict = self.model_dump() model_dict = self.model_dump()
model_repr_str = f"{self.classname()}(" model_repr_str = f"{self.classname()}("
model_repr_str += ", ".join([f"{field}={value:.3f}" for field, value in model_dict.items()]) model_repr_str += ", ".join([
f"{field}={value:.3f}"
for field, value
in model_dict.items()
])
model_repr_str += ")" model_repr_str += ")"
return model_repr_str return model_repr_str
+7 -2
View File
@@ -28,7 +28,8 @@ class ModelOutput(BaseModel):
raise ValidationError() raise ValidationError()
assert isinstance(option, str) assert isinstance(option, str)
allowed_options_list = cls.list_fields() allowed_options_list = cls.list_fields()
assert option in allowed_options_list, f"{option} is not among allowed fields {allowed_options_list}" 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 = {field: 0 for field in cls.list_fields()}
kwargs[option] = 1 kwargs[option] = 1
return cls(**kwargs) return cls(**kwargs)
@@ -36,7 +37,11 @@ class ModelOutput(BaseModel):
def __repr__(self) -> str: def __repr__(self) -> str:
model_dict = self.model_dump() model_dict = self.model_dump()
model_repr_str = f"{self.classname()}(" model_repr_str = f"{self.classname()}("
model_repr_str += ", ".join([f"{field}={value:.3f}" for field, value in model_dict.items()]) model_repr_str += ", ".join([
f"{field}={value:.3f}"
for field, value
in model_dict.items()
])
model_repr_str += ")" model_repr_str += ")"
return model_repr_str return model_repr_str
+4 -2
View File
@@ -30,6 +30,7 @@ BasicAuth(app, AUTH_DICT)
# connect to database # connect to database
collection, db, client = connect() collection, db, client = connect()
# define callbacks # define callbacks
@app.callback( @app.callback(
Output("alert-element", "is_open"), Output("alert-element", "is_open"),
@@ -44,6 +45,7 @@ def show_alert(
logging.info(f"updated alert message: {msg}") logging.info(f"updated alert message: {msg}")
return True, msg return True, msg
@app.callback( @app.callback(
Output("alert-message", "data"), Output("alert-message", "data"),
Output("vis-com-name", "data"), Output("vis-com-name", "data"),
@@ -108,7 +110,7 @@ def cycle_visual_communication_data(
} }
# instantiate ModelOutputs object # instantiate ModelOutputs object
annotations = ModelOutputs.from_annotations(**annotations) annotations = ModelOutputs.from_annotations(**annotations)
# save data to # save data to database
upsert_annotations( upsert_annotations(
collection=collection, collection=collection,
vis_com_name=vis_com_name, vis_com_name=vis_com_name,
@@ -137,7 +139,7 @@ def cycle_visual_communication_data(
# reset annotations # reset annotations
annotation_values = [None for elem in annotation_values] annotation_values = [None for elem in annotation_values]
except NoDocumentFoundException: except NoDocumentFoundException:
msg = f"no unannotated data in database" msg = "no unannotated data in database"
logging.warning(msg) logging.warning(msg)
response[0] = msg response[0] = msg
return tuple(response) return tuple(response)
+1 -1
View File
@@ -1,4 +1,4 @@
from dash import html, dcc from dash import html
import dash_bootstrap_components as dbc import dash_bootstrap_components as dbc
-2
View File
@@ -1,6 +1,4 @@
import dash_mantine_components as dmc import dash_mantine_components as dmc
from dash import dcc, html
from typing import List
from .image import image_element from .image import image_element
from .inputs import inputs_element from .inputs import inputs_element
+23 -6
View File
@@ -20,6 +20,7 @@ from src.model_textual import (
SalienceModelOutput SalienceModelOutput
) )
def generate_option_labels(model) -> List[str]: def generate_option_labels(model) -> List[str]:
"""Generate presentable list of attributes from an OutputModel.""" """Generate presentable list of attributes from an OutputModel."""
labels = [ labels = [
@@ -28,35 +29,51 @@ def generate_option_labels(model) -> List[str]:
] ]
return labels return labels
def generate_visual_syntax_options_map(): def generate_visual_syntax_options_map():
"""Generate map of titles and options for visual syntax labels.""" """Generate map of titles and options for visual syntax labels."""
options_map = {} options_map = {}
# add experiential labels # add experiential labels
options_map["visual syntax"] = generate_option_labels(VisualSyntaxModelOutput) options_map["visual syntax"] = generate_option_labels(
VisualSyntaxModelOutput
)
return options_map return options_map
def generate_interpersonal_options_map(): def generate_interpersonal_options_map():
"""Generate map of titles and options for interpersonal labels.""" """Generate map of titles and options for interpersonal labels."""
options_map = {} options_map = {}
# add interpersonal labels # add interpersonal labels
options_map["contact"] = generate_option_labels(ContactModelOutput) options_map["contact"] = generate_option_labels(ContactModelOutput)
options_map["angle"] = generate_option_labels(AngleModelOutput) options_map["angle"] = generate_option_labels(AngleModelOutput)
options_map["point of view"] = generate_option_labels(PointOfViewModelOutput) options_map["point of view"] = generate_option_labels(
PointOfViewModelOutput
)
options_map["distance"] = generate_option_labels(DistanceModelOutput) options_map["distance"] = generate_option_labels(DistanceModelOutput)
options_map["modality lighting"] = generate_option_labels(ModalityLightingModelOutput) options_map["modality lighting"] = generate_option_labels(
options_map["modality color"] = generate_option_labels(ModalityColorModelOutput) ModalityLightingModelOutput
options_map["modality depth"] = generate_option_labels(ModalityDepthModelOutput) )
options_map["modality color"] = generate_option_labels(
ModalityColorModelOutput
)
options_map["modality depth"] = generate_option_labels(
ModalityDepthModelOutput
)
return options_map return options_map
def generate_textual_options_map(): def generate_textual_options_map():
"""Generate map of titles and options for textual labels.""" """Generate map of titles and options for textual labels."""
options_map = {} options_map = {}
# add textual labels # add textual labels
options_map["information value"] = generate_option_labels(InformationValueModelOutput) options_map["information value"] = generate_option_labels(
InformationValueModelOutput
)
options_map["framing"] = generate_option_labels(FramingModelOutput) options_map["framing"] = generate_option_labels(FramingModelOutput)
options_map["salience"] = generate_option_labels(SalienceModelOutput) options_map["salience"] = generate_option_labels(SalienceModelOutput)
return options_map return options_map
# prepare experiential container # prepare experiential container
experiential_map = generate_visual_syntax_options_map() experiential_map = generate_visual_syntax_options_map()
experiential_container = dmc.Col( experiential_container = dmc.Col(
-1
View File
@@ -1,4 +1,3 @@
from dash import dcc
import dash_mantine_components as dmc import dash_mantine_components as dmc
from .stores import stores_element from .stores import stores_element
+4 -2
View File
@@ -5,8 +5,10 @@ import os
storage_type = "session" storage_type = "session"
if "ENV" in os.environ and os.getenv("ENV") == "DEV": if "ENV" in os.environ and os.getenv("ENV") == "DEV":
storage_type = "memory" storage_type = "memory"
logging.info(f"ENV=DEV -> dcc.Stores changed to storage_type={storage_type}") logging.info(
"ENV=DEV -> dcc.Stores changed to storage_type=%s",
storage_type
)
stores_element = html.Div( stores_element = html.Div(
children=[ children=[
+5 -1
View File
@@ -10,7 +10,11 @@ if __name__ == "__main__":
img_path_list = [path for path in img_dir.glob("*.jpeg") if path.is_file()] img_path_list = [path for path in img_dir.glob("*.jpeg") if path.is_file()]
print(img_path_list) print(img_path_list)
# instantiate data object # instantiate data object
vis_com_list = [VisualCommunication.from_file(path) for path in img_path_list] vis_com_list = [
VisualCommunication.from_file(path)
for path
in img_path_list
]
# generate random predictions # generate random predictions
[vis_com.generate_random_prediction() for vis_com in vis_com_list] [vis_com.generate_random_prediction() for vis_com in vis_com_list]
for vis_com in vis_com_list: for vis_com in vis_com_list:
+5 -1
View File
@@ -12,7 +12,11 @@ if __name__ == "__main__":
img_path_list = [path for path in img_dir.glob("*.jpeg") if path.is_file()] img_path_list = [path for path in img_dir.glob("*.jpeg") if path.is_file()]
print(img_path_list) print(img_path_list)
# instantiate data object # instantiate data object
vis_com_list = [VisualCommunication.from_file(path) for path in img_path_list] vis_com_list = [
VisualCommunication.from_file(path)
for path
in img_path_list
]
for vis_com in vis_com_list: for vis_com in vis_com_list:
print(repr(vis_com)) print(repr(vis_com))
# prepare env vars # prepare env vars
+5 -4
View File
@@ -3,10 +3,11 @@ from src.database import ModelOutputs
if __name__ == "__main__": if __name__ == "__main__":
# instantiate data object # instantiate data object
annotation = { vis_com_list = [
ModelOutputs.from_random()
} for i
vis_com_list = [ModelOutputs.from_annotation(path) for path in img_path_list] in range(3)
]
# generate random predictions # generate random predictions
[vis_com.generate_random_prediction() for vis_com in vis_com_list] [vis_com.generate_random_prediction() for vis_com in vis_com_list]
for vis_com in vis_com_list: for vis_com in vis_com_list:
+5 -1
View File
@@ -25,7 +25,11 @@ if __name__ == "__main__":
img_dir = test_dir / "imgs" img_dir = test_dir / "imgs"
img_path_list = [path for path in img_dir.glob("*.jpeg") if path.is_file()] img_path_list = [path for path in img_dir.glob("*.jpeg") if path.is_file()]
# instantiate data object # instantiate data object
vis_com_list = [VisualCommunication.from_file(path) for path in img_path_list] vis_com_list = [
VisualCommunication.from_file(path)
for path
in img_path_list
]
# generate random predictions # generate random predictions
[vis_com.generate_random_prediction() for vis_com in vis_com_list] [vis_com.generate_random_prediction() for vis_com in vis_com_list]
# prepare env vars # prepare env vars