generated from MinBZK/python-project-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
197 additions
and
41 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from pydantic import BaseModel | ||
from pydantic import Field as PydanticField # type: ignore | ||
|
||
|
||
class SystemCard(BaseModel): | ||
title: str = PydanticField(default=None) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from abc import ABC, abstractmethod | ||
from pathlib import Path | ||
from typing import Any | ||
|
||
from yaml import dump | ||
|
||
|
||
class Writer(ABC): | ||
@abstractmethod | ||
def write(self, data: dict[str, Any]) -> None: | ||
"""This is an abstract method to write with the writer""" | ||
|
||
@abstractmethod | ||
def close(self) -> None: | ||
"""This is an abstract method to close the writer""" | ||
|
||
|
||
class WriterFactory: | ||
@staticmethod | ||
def get_writer(writer_type: str = "file", **kwargs: str) -> Writer: | ||
match writer_type: | ||
case "file": | ||
if not all(k in kwargs for k in ("location", "filename")): | ||
raise KeyError("The `location` or `filename` variables are not provided as input for get_writer()") | ||
return FileSystemWriteService(location=str(kwargs["location"]), filename=str(kwargs["filename"])) | ||
case _: | ||
raise ValueError(f"Unknown writer type: {writer_type}") | ||
|
||
|
||
class FileSystemWriteService(Writer): | ||
def __init__(self, location: str = "./tests/data", filename: str = "system_card.yaml") -> None: | ||
self.location = location | ||
if not filename.endswith(".yaml"): | ||
raise ValueError(f"Filename {filename} must end with .yaml instead of .{filename.split('.')[-1]}") | ||
self.filename = filename | ||
|
||
def write(self, data: dict[str, Any]) -> None: | ||
if not Path(self.location).exists(): | ||
Path(self.location).mkdir() | ||
with open(Path(self.location) / self.filename, "w") as f: | ||
dump(data, f, default_flow_style=False, sort_keys=False) | ||
|
||
def close(self): | ||
""" | ||
This method is empty because with the `with` statement in the writer, Python will already close the writer | ||
after usage. | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
from pathlib import Path | ||
|
||
import pytest | ||
from tad.models.system_card import SystemCard | ||
from tad.services.storage import WriterFactory | ||
from yaml import safe_load | ||
|
||
|
||
@pytest.fixture() | ||
def setup_and_teardown(tmp_path: Path) -> tuple[str, str]: | ||
filename = "test.yaml" | ||
return filename, str(tmp_path.absolute()) | ||
|
||
|
||
def test_file_system_writer_empty_yaml(setup_and_teardown: tuple[str, str]) -> None: | ||
filename, location = setup_and_teardown | ||
|
||
storage_writer = WriterFactory.get_writer(writer_type="file", location=location, filename=filename) | ||
storage_writer.write({}) | ||
|
||
assert Path.is_file(Path(location) / filename), True | ||
|
||
|
||
def test_file_system_writer_no_location_variable(setup_and_teardown: tuple[str, str]) -> None: | ||
filename, _ = setup_and_teardown | ||
with pytest.raises( | ||
KeyError, match="The `location` or `filename` variables are not provided as input for get_writer()" | ||
): | ||
WriterFactory.get_writer(writer_type="file", filename=filename) | ||
|
||
|
||
def test_file_system_writer_no_filename_variable(setup_and_teardown: tuple[str, str]) -> None: | ||
_, location = setup_and_teardown | ||
with pytest.raises( | ||
KeyError, match="The `location` or `filename` variables are not provided as input for get_writer()" | ||
): | ||
WriterFactory.get_writer(writer_type="file", location=location) | ||
|
||
|
||
def test_file_system_writer_yaml_with_content(setup_and_teardown: tuple[str, str]) -> None: | ||
filename, location = setup_and_teardown | ||
data = {"test": "test"} | ||
storage_writer = WriterFactory.get_writer(writer_type="file", location=location, filename=filename) | ||
storage_writer.write(data) | ||
|
||
with open(Path(location) / filename) as f: | ||
assert safe_load(f) == data, True | ||
|
||
|
||
def test_file_system_writer_with_system_card(setup_and_teardown: tuple[str, str]) -> None: | ||
filename, location = setup_and_teardown | ||
data = SystemCard() | ||
data.title = "test" | ||
data_dict = data.model_dump() | ||
|
||
storage_writer = WriterFactory.get_writer(writer_type="file", location=location, filename=filename) | ||
storage_writer.write(data_dict) | ||
|
||
with open(Path(location) / filename) as f: | ||
assert safe_load(f) == data_dict, True | ||
|
||
|
||
def test_abstract_writer_non_yaml_filename(setup_and_teardown: tuple[str, str]) -> None: | ||
_, location = setup_and_teardown | ||
filename = "test.csv" | ||
with pytest.raises( | ||
ValueError, match=f"Filename {filename} must end with .yaml instead of .{filename.split('.')[-1]}" | ||
): | ||
WriterFactory.get_writer(writer_type="file", location=location, filename=filename) | ||
|
||
|
||
def test_not_valid_writer_type() -> None: | ||
writer_type = "kafka" | ||
with pytest.raises(ValueError, match=f"Unknown writer type: {writer_type}"): | ||
WriterFactory.get_writer(writer_type=writer_type) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import pytest | ||
from tad.models.system_card import SystemCard | ||
|
||
|
||
@pytest.fixture() | ||
def setup() -> SystemCard: | ||
system_card = SystemCard() | ||
return system_card | ||
|
||
|
||
def test_get_system_card(setup: SystemCard) -> None: | ||
system_card = setup | ||
expected = {"title": None} | ||
|
||
assert system_card.model_dump() == expected | ||
|
||
|
||
def test_system_card_update(setup: SystemCard) -> None: | ||
system_card = setup | ||
expected = {"title": "IAMA 1.1"} | ||
system_card.title = "IAMA 1.1" | ||
|
||
assert system_card.model_dump() == expected |