Skip to content

Commit

Permalink
Add python-version of the dynamodb model. Implement test-case to veri…
Browse files Browse the repository at this point in the history
…fy that everything is parsed properly without validation issues.
  • Loading branch information
MarcTM01 committed May 17, 2024
1 parent fad5516 commit ad1a48c
Show file tree
Hide file tree
Showing 9 changed files with 298 additions and 4 deletions.
82 changes: 79 additions & 3 deletions alexa-skill/lambda-pdm/pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion alexa-skill/lambda-pdm/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ license = {text = "MIT"}
lint = "ruff check --fix ."
format = "ruff format ."
typecheck = "mypy ./src/"
test = "pytest tests/"

[tool.pdm.dev-dependencies]
lint = [
Expand All @@ -31,6 +32,9 @@ typecheck = [
i18n = [
"babel>=2.15.0",
]
test = [
"pytest>=8.2.0",
]

[tool.ruff.lint]
select = [
Expand All @@ -52,4 +56,3 @@ convention = "pep257"

[tool.pdm]
distribution = false

2 changes: 2 additions & 0 deletions alexa-skill/lambda-pdm/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[pytest]
pythonpath = "src"
2 changes: 2 additions & 0 deletions alexa-skill/lambda-pdm/src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

class DynamoDBConfig(BaseModel):
"""A configuration class for the DynamoDB table connection."""

table_name: str
region: str
assume_role_arn: str
Expand All @@ -12,6 +13,7 @@ class DynamoDBConfig(BaseModel):

class Config(BaseSettings):
"""The main configuration class for the skill."""

model_config = SettingsConfigDict(env_nested_delimiter='__', env_file='.env', env_file_encoding='utf-8')
dynamodb_config: DynamoDBConfig

Expand Down
56 changes: 56 additions & 0 deletions alexa-skill/lambda-pdm/src/data/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import datetime
from enum import Enum
from typing import List, Optional, Set

from pydantic import BaseModel, Field, field_validator


class NutritionFlag(str, Enum):
"""An enumeration of the possible nutrition flags."""

VEGETARIAN = "vegetarian"
VEGAN = "vegan"
PORK = "pork"
BEEF = "beef"
FISH = "fish"
CHICKEN = "chicken"


class MensaMenuExtra(BaseModel):
"""A model for the extra menu items."""

name: str = Field(alias='Name')
description: str = Field(alias='Description')


class MensaMenu(BaseModel):
"""A model for the menu items."""

name: str = Field(alias='Name')
contents: List[str] = Field(alias='Contents')
price: Optional[str] = Field(alias='Price', default=None)
nutrition_flags: Set[NutritionFlag] = Field(alias='NutritionFlags', default_factory=set)

@field_validator('nutrition_flags', mode='before')
def parse_nutrition_flags(cls, value):
"""Parse the nutrition flags from the expected input format to a set of NutritionFlag enums.
Sample input value: {
"NutritionFlags": {
"vegetarian": {}
},
}
"""
if isinstance(value, dict):
return {NutritionFlag(flag) for flag in value.keys()}
return value


class MensaDayMenus(BaseModel):
"""A model for the dynamodb mensa menu item."""

date: datetime.date = Field(alias='Date')
menus: List[MensaMenu] = Field(alias='Menus')
extras: List[MensaMenuExtra] = Field(alias='Extras')
mensa_id: str = Field(alias='MensaId')
LanguageKey: str = Field(alias='LanguageKey')
Empty file.
Empty file.
139 changes: 139 additions & 0 deletions alexa-skill/lambda-pdm/tests/data/example_model.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
{
"MensaId": "mensa-academica",
"Date": "2024-05-15",
"Menus": [
{
"NutritionFlags": {
"fish": {}
},
"Contents": [
"Potato creme soup",
"Smoked salmon",
"Bread roll"
],
"Price": "2,00 €",
"Name": "Stew"
},
{
"NutritionFlags": {
"vegetarian": {}
},
"Contents": [
"Potato creme soup",
"Bread roll"
],
"Price": "1,60 €",
"Name": "Vegetarian table dish"
},
{
"NutritionFlags": {
"vegetarian": {},
"vegan": {}
},
"Contents": [
"Crispy sesame-carrot-stick",
"Sweet sour sauce"
],
"Price": "2,20 €",
"Name": "Vegetarian"
},
{
"NutritionFlags": {
"pork": {}
},
"Contents": [
"Asparagus with ham",
"White wine hollandaise",
"Potatoes"
],
"Price": "6,50 €",
"Name": "Suggestion of the day"
},
{
"NutritionFlags": {
"beef": {}
},
"Contents": [
"Beef strips",
"Mushrooms"
],
"Price": "2,80 €",
"Name": "Classics"
},
{
"NutritionFlags": {
"chicken": {}
},
"Contents": [
"Sweet n spicy chicken",
"Banana peanut sauce",
"Basmati rice"
],
"Price": "3,80 €",
"Name": "Wok"
},
{
"NutritionFlags": {
"vegetarian": {},
"vegan": {}
},
"Contents": [
"Sweet-spicy vegetables",
"Banana peanut sauce",
"Basmati rice"
],
"Price": "3,80 €",
"Name": "Wok"
},
{
"NutritionFlags": {
"beef": {}
},
"Contents": [
"Cheeseburger",
"French fries",
"Soft drink 0,33 L"
],
"Price": "4,90 €",
"Name": "Burger Classics"
},
{
"NutritionFlags": {
"vegetarian": {}
},
"Contents": [
"Veggie burger",
"French fries",
"Soft drink 0,33 L"
],
"Price": "4,90 €",
"Name": "Burger Classics"
},
{
"NutritionFlags": {
"beef": {}
},
"Contents": [
"Italian burger",
"Rocket, tomatoes",
"cheese sauce",
"French fries",
"Soft drink 0,33 L"
],
"Price": "4,90 €",
"Name": "Burger of the week"
}
],
"Extras": [
{
"Name": "Main side-dish",
"Description": "potatoes or rice"
},
{
"Name": "secondary",
"Description": "Romanesco or Mixed salad"
}
],
"LanguageKey": "en",
"MensaIdLanguageKeyDate": "mensa-academica;en;2024-05-15"
}
16 changes: 16 additions & 0 deletions alexa-skill/lambda-pdm/tests/data/test_model_parsing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import json
from pathlib import Path

from data.model import MensaDayMenus


def test_model_parsing():
"""Test the parsing of the model from a json file."""
model_path = Path(__file__).parent / 'example_model.json'
assert model_path.exists()
assert model_path.is_file()

with open(model_path, 'r') as f:
model = json.load(f)

MensaDayMenus(**model)

0 comments on commit ad1a48c

Please sign in to comment.