new dual linked dictionary and usage as feature map

This commit is contained in:
Florian Förster 2025-03-12 15:58:30 +01:00
parent 46182855a4
commit e53709e3fb
2 changed files with 86 additions and 10 deletions

View File

@ -1,7 +1,7 @@
import enum
from typing import Final
from delta_barth.types import HttpContentHeaders
from delta_barth.types import DualDict, HttpContentHeaders
# ** error handling
DEFAULT_INTERNAL_ERR_CODE: Final[int] = 100
@ -20,13 +20,14 @@ class KnownDelBarApiErrorCodes(enum.Enum):
# ** API response parsing
# ** column mapping [API-Response --> Target-Features]
COL_MAP_SALES_PROGNOSIS: Final[dict[str, str]] = {
"artikelId": "artikel_refid",
"firmaId": "firma_refid",
"betrag": "betrag",
"menge": "menge",
"buchungsDatum": "buchungs_datum",
}
COL_MAP_SALES_PROGNOSIS: Final[DualDict[str, str]] = DualDict(
artikelId="artikel_refid",
firmaId="firma_refid",
betrag="betrag",
menge="menge",
buchungsDatum="buchungs_datum",
)
FEATURES_SALES_PROGNOSIS: Final[frozenset[str]] = frozenset(
(
"firma_refid",
@ -34,3 +35,5 @@ FEATURES_SALES_PROGNOSIS: Final[frozenset[str]] = frozenset(
"buchungs_datum",
)
)
MIN_NUMBER_DATAPOINTS: Final[int] = 100

View File

@ -2,13 +2,51 @@ from __future__ import annotations
import enum
import typing as t
from collections.abc import Iterator, MutableMapping
from dataclasses import dataclass, field
import pandas as pd
from pydantic import BaseModel, ConfigDict, SkipValidation
# ** Data Structures
K = t.TypeVar("K")
V = t.TypeVar("V")
class DualDict(MutableMapping[K, V]):
def __init__(self, **kwargs: V):
self._store: dict[K, V] = dict(**kwargs)
self._inverted = self._calc_inverted()
@property
def inverted(self) -> dict[V, K]:
return self._inverted
def _calc_inverted(self) -> dict[V, K]:
return {val: key for key, val in self.items()}
def __setitem__(self, key: K, value: V) -> None:
self._store[key] = value
self._inverted[value] = key
def __getitem__(self, key: K) -> V:
return self._store[key]
def __delitem__(self, key: K) -> None:
value = self._store[key]
del self._store[key]
del self._inverted[value]
def __iter__(self) -> Iterator[K]:
return iter(self._store)
def __len__(self) -> int:
return len(self._store)
# ** Pipeline state management
StatusDescription: t.TypeAlias = tuple[str, int, str]
R = t.TypeVar("R", bound="ExportResponse")
class IError(t.Protocol):
@ -24,6 +62,15 @@ class Status(BaseModel):
api_server_error: SkipValidation[DelBarApiError | None] = None
class ResponseType(BaseModel):
pass
class ExportResponse(BaseModel):
response: ResponseType
status: Status
@dataclass(slots=True)
class DataPipeStates:
SUCCESS: Status
@ -32,9 +79,35 @@ class DataPipeStates:
@dataclass(slots=True)
class PipeResult:
status: Status
class PipeResult(t.Generic[R]):
data: pd.DataFrame | None
status: Status
results: R | None = None
def success(
self,
data: pd.DataFrame,
status: Status,
) -> None:
self.data = data
self.status = status
self.results = None
def fail(
self,
status: Status,
) -> None:
self.data = None
self.status = status
self.results = None
def export(
self,
response: R,
) -> None:
self.data = None
self.status = response.status
self.results = response
# ** API