new dual linked dictionary and usage as feature map
This commit is contained in:
parent
46182855a4
commit
e53709e3fb
@ -1,7 +1,7 @@
|
|||||||
import enum
|
import enum
|
||||||
from typing import Final
|
from typing import Final
|
||||||
|
|
||||||
from delta_barth.types import HttpContentHeaders
|
from delta_barth.types import DualDict, HttpContentHeaders
|
||||||
|
|
||||||
# ** error handling
|
# ** error handling
|
||||||
DEFAULT_INTERNAL_ERR_CODE: Final[int] = 100
|
DEFAULT_INTERNAL_ERR_CODE: Final[int] = 100
|
||||||
@ -20,13 +20,14 @@ class KnownDelBarApiErrorCodes(enum.Enum):
|
|||||||
|
|
||||||
# ** API response parsing
|
# ** API response parsing
|
||||||
# ** column mapping [API-Response --> Target-Features]
|
# ** column mapping [API-Response --> Target-Features]
|
||||||
COL_MAP_SALES_PROGNOSIS: Final[dict[str, str]] = {
|
COL_MAP_SALES_PROGNOSIS: Final[DualDict[str, str]] = DualDict(
|
||||||
"artikelId": "artikel_refid",
|
artikelId="artikel_refid",
|
||||||
"firmaId": "firma_refid",
|
firmaId="firma_refid",
|
||||||
"betrag": "betrag",
|
betrag="betrag",
|
||||||
"menge": "menge",
|
menge="menge",
|
||||||
"buchungsDatum": "buchungs_datum",
|
buchungsDatum="buchungs_datum",
|
||||||
}
|
)
|
||||||
|
|
||||||
FEATURES_SALES_PROGNOSIS: Final[frozenset[str]] = frozenset(
|
FEATURES_SALES_PROGNOSIS: Final[frozenset[str]] = frozenset(
|
||||||
(
|
(
|
||||||
"firma_refid",
|
"firma_refid",
|
||||||
@ -34,3 +35,5 @@ FEATURES_SALES_PROGNOSIS: Final[frozenset[str]] = frozenset(
|
|||||||
"buchungs_datum",
|
"buchungs_datum",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
MIN_NUMBER_DATAPOINTS: Final[int] = 100
|
||||||
|
|||||||
@ -2,13 +2,51 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import enum
|
import enum
|
||||||
import typing as t
|
import typing as t
|
||||||
|
from collections.abc import Iterator, MutableMapping
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from pydantic import BaseModel, ConfigDict, SkipValidation
|
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
|
# ** Pipeline state management
|
||||||
StatusDescription: t.TypeAlias = tuple[str, int, str]
|
StatusDescription: t.TypeAlias = tuple[str, int, str]
|
||||||
|
R = t.TypeVar("R", bound="ExportResponse")
|
||||||
|
|
||||||
|
|
||||||
class IError(t.Protocol):
|
class IError(t.Protocol):
|
||||||
@ -24,6 +62,15 @@ class Status(BaseModel):
|
|||||||
api_server_error: SkipValidation[DelBarApiError | None] = None
|
api_server_error: SkipValidation[DelBarApiError | None] = None
|
||||||
|
|
||||||
|
|
||||||
|
class ResponseType(BaseModel):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ExportResponse(BaseModel):
|
||||||
|
response: ResponseType
|
||||||
|
status: Status
|
||||||
|
|
||||||
|
|
||||||
@dataclass(slots=True)
|
@dataclass(slots=True)
|
||||||
class DataPipeStates:
|
class DataPipeStates:
|
||||||
SUCCESS: Status
|
SUCCESS: Status
|
||||||
@ -32,9 +79,35 @@ class DataPipeStates:
|
|||||||
|
|
||||||
|
|
||||||
@dataclass(slots=True)
|
@dataclass(slots=True)
|
||||||
class PipeResult:
|
class PipeResult(t.Generic[R]):
|
||||||
status: Status
|
|
||||||
data: pd.DataFrame | None
|
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
|
# ** API
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user