perfact-api-pd-fastapi 1.5__tar.gz → 1.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/PKG-INFO +1 -1
  2. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/src/perfact/api/pd_fastapi/kpi.py +3 -21
  3. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/src/perfact/api/pd_fastapi/pdunitlch.py +8 -3
  4. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/src/perfact_api_pd_fastapi.egg-info/PKG-INFO +1 -1
  5. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/src/perfact_api_pd_fastapi.egg-info/SOURCES.txt +1 -0
  6. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/src/perfact_api_pd_fastapi.egg-info/scm_file_list.json +1 -0
  7. perfact_api_pd_fastapi-1.7/src/perfact_api_pd_fastapi.egg-info/scm_version.json +8 -0
  8. perfact_api_pd_fastapi-1.7/tests/test_pdunitlch.py +76 -0
  9. perfact_api_pd_fastapi-1.5/src/perfact_api_pd_fastapi.egg-info/scm_version.json +0 -8
  10. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/README.md +0 -0
  11. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/pyproject.toml +0 -0
  12. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/setup.cfg +0 -0
  13. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/src/perfact/api/pd_fastapi/__init__.py +0 -0
  14. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/src/perfact/api/pd_fastapi/grafana.py +0 -0
  15. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/src/perfact/api/pd_fastapi/pdunit.py +0 -0
  16. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/src/perfact/api/pd_fastapi/performancedata.py +0 -0
  17. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/src/perfact/api/pd_fastapi/py.typed +0 -0
  18. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/src/perfact_api_pd_fastapi.egg-info/dependency_links.txt +0 -0
  19. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/src/perfact_api_pd_fastapi.egg-info/entry_points.txt +0 -0
  20. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/src/perfact_api_pd_fastapi.egg-info/requires.txt +0 -0
  21. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/src/perfact_api_pd_fastapi.egg-info/top_level.txt +0 -0
  22. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/tests/__init__.py +0 -0
  23. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/tests/conftest.py +0 -0
  24. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/tests/helpers.py +0 -0
  25. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/tests/locustfile.py +0 -0
  26. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/tests/test_init.py +0 -0
  27. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/tests/test_kpi.py +0 -0
  28. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/tests/test_pdunit.py +0 -0
  29. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/tests/test_performance.py +0 -0
  30. {perfact_api_pd_fastapi-1.5 → perfact_api_pd_fastapi-1.7}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: perfact-api-pd-fastapi
3
- Version: 1.5
3
+ Version: 1.7
4
4
  Summary: PerFact API - SQLAlchemy+FastAPI pd apis package
5
5
  Author-email: Viktor Dick <viktor.dick@perfact.de>
6
6
  License-Expression: GPL-2.0-or-later
@@ -16,8 +16,7 @@ from perfact.api.pd.services.oee.prod_records import get_prod_records
16
16
  from perfact.api.pd.services.oee.state_spans import get_state_spans
17
17
  from perfact.api.pd.services.oee.summary import oee_workcenter_time_computation
18
18
  from perfact.api.pd.services.oee.trend import (
19
- compute_trend_for_candidates,
20
- compute_trend_for_collections,
19
+ compute_trend,
21
20
  get_oee_trend_candidate_days,
22
21
  )
23
22
  from pydantic import BaseModel, BeforeValidator
@@ -191,28 +190,11 @@ def oee_trend_aggregation(
191
190
  ) -> dict:
192
191
  """
193
192
  Calculate and persist daily OEE values into dgval for eligible pdunit/day pairs.
193
+ Commits day by day so an execution cut short by a timeout keeps its progress.
194
194
  """
195
195
 
196
196
  candidates = get_oee_trend_candidate_days(session, lookback_months)
197
-
198
- # compute trend for candidate days
199
- c, u, s, impacted_days = compute_trend_for_candidates(session, candidates)
200
-
201
- # create or update pdunitgroups and pdplants
202
- # if possible for each of the impacted days
203
- pdgrp_c, pdgrp_u, pdplt_c, pdplt_u = compute_trend_for_collections(
204
- session, impacted_days
205
- )
206
-
207
- return {
208
- "created": c,
209
- "updated": u,
210
- "skipped": s,
211
- "pdunitgroup_created": pdgrp_c,
212
- "pdunitgroup_updated": pdgrp_u,
213
- "pdplant_created": pdplt_c,
214
- "pdplant_updated": pdplt_u,
215
- }
197
+ return compute_trend(session, candidates)
216
198
 
217
199
 
218
200
  @routes.get("/kpi/downtime", tags=["pd"], summary="PdUnit downtime")
@@ -1,7 +1,7 @@
1
1
  import datetime
2
2
  from typing import Optional, Sequence
3
3
 
4
- from fastapi import HTTPException
4
+ from fastapi import HTTPException, Query
5
5
  from perfact.api.base.model import PydanticBase
6
6
  from perfact.api.main import Auth, DBSession, VisibilityRegistryDep, require_roles
7
7
  from perfact.api.main.dbsession import APIRouter
@@ -19,10 +19,13 @@ from sqlalchemy import select
19
19
 
20
20
  routes = APIRouter()
21
21
 
22
+ MAX_SAMPLE_COUNT = 9_000
23
+
22
24
 
23
25
  class PdUnitLcGet(PydanticBase):
24
26
  name: str
25
27
  seqnum: Optional[int]
28
+ color: Optional[str]
26
29
 
27
30
 
28
31
  class PdUnitLctGet(PydanticBase):
@@ -38,6 +41,7 @@ class PdOrdLcGet(PydanticBase):
38
41
  isfinal: bool
39
42
  issetup: bool
40
43
  isdowntime: bool
44
+ color: Optional[str]
41
45
 
42
46
 
43
47
  class PdOrdLctGet(PydanticBase):
@@ -58,6 +62,7 @@ class PdUnitLchEntryGet(BaseModel):
58
62
  pdunitlct_name: str
59
63
  pdunitlc_name: str
60
64
  pdord_num: Optional[str]
65
+ pdordlc_name: Optional[str]
61
66
 
62
67
 
63
68
  @routes.get(
@@ -128,7 +133,7 @@ def pdunitlch_get(
128
133
  visibility: VisibilityRegistryDep,
129
134
  pdunit_id: Optional[int] = None,
130
135
  pdunit_num: Optional[str] = None,
131
- duration_s: Optional[int] = None,
136
+ sample_count: Optional[int] = Query(default=None, ge=1, le=MAX_SAMPLE_COUNT),
132
137
  starttime: Optional[datetime.datetime] = None,
133
138
  endtime: Optional[datetime.datetime] = None,
134
139
  ) -> list[UnitLchHistoryEntry]:
@@ -167,7 +172,7 @@ def pdunitlch_get(
167
172
  pdunit_id=unit.id,
168
173
  starttime=starttime,
169
174
  endtime=endtime,
170
- duration_s=duration_s,
175
+ sample_count=sample_count,
171
176
  )
172
177
  except ValueError as exc:
173
178
  raise HTTPException(status_code=422, detail=str(exc)) from exc
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: perfact-api-pd-fastapi
3
- Version: 1.5
3
+ Version: 1.7
4
4
  Summary: PerFact API - SQLAlchemy+FastAPI pd apis package
5
5
  Author-email: Viktor Dick <viktor.dick@perfact.de>
6
6
  License-Expression: GPL-2.0-or-later
@@ -23,4 +23,5 @@ tests/locustfile.py
23
23
  tests/test_init.py
24
24
  tests/test_kpi.py
25
25
  tests/test_pdunit.py
26
+ tests/test_pdunitlch.py
26
27
  tests/test_performance.py
@@ -17,6 +17,7 @@
17
17
  "tests/__init__.py",
18
18
  "tests/test_pdunit.py",
19
19
  "tests/conftest.py",
20
+ "tests/test_pdunitlch.py",
20
21
  "tests/test_performance.py"
21
22
  ]
22
23
  }
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "1.7",
3
+ "distance": 0,
4
+ "node": "g4aa2bc0baa5e5d3232ee124539082fc3c08f47a1",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-07-09"
8
+ }
@@ -0,0 +1,76 @@
1
+ import datetime
2
+ from types import SimpleNamespace
3
+
4
+ from perfact.api.main.dbsession import APIRouter
5
+ from perfact.api.pd.services.pdunitlch import UnitLchHistoryEntry
6
+ from perfact.api.pd_fastapi import pdunitlch
7
+
8
+ MODTIME = datetime.datetime(2024, 1, 1, tzinfo=datetime.timezone.utc)
9
+
10
+
11
+ def test_pdunitlcget_exposes_color() -> None:
12
+ row = SimpleNamespace(
13
+ id=1, author=None, modtime=MODTIME, name="Production", seqnum=1, color="#0f0"
14
+ )
15
+
16
+ serialized = pdunitlch.PdUnitLcGet.model_validate(row)
17
+
18
+ assert serialized.color == "#0f0"
19
+
20
+
21
+ def test_pdordlcget_exposes_color() -> None:
22
+ row = SimpleNamespace(
23
+ id=1,
24
+ author=None,
25
+ modtime=MODTIME,
26
+ name="Running",
27
+ isactive=True,
28
+ isexecution=False,
29
+ isfinal=False,
30
+ issetup=False,
31
+ isdowntime=False,
32
+ color="#f00",
33
+ )
34
+
35
+ serialized = pdunitlch.PdOrdLcGet.model_validate(row)
36
+
37
+ assert serialized.color == "#f00"
38
+
39
+
40
+ def test_pdunitlchentryget_exposes_pdordlc_name() -> None:
41
+ entry = UnitLchHistoryEntry(
42
+ createtime=datetime.datetime(2024, 1, 1, tzinfo=datetime.timezone.utc),
43
+ pdunitlct_name="start",
44
+ pdunitlc_name="running",
45
+ pdord_num="ORD-1",
46
+ pdordlc_name="active",
47
+ )
48
+
49
+ serialized = pdunitlch.PdUnitLchEntryGet.model_validate(entry)
50
+
51
+ assert serialized.pdordlc_name == "active"
52
+
53
+
54
+ def test_pdunitlchentryget_pdordlc_name_none_when_no_active_operation() -> None:
55
+ entry = UnitLchHistoryEntry(
56
+ createtime=datetime.datetime(2024, 1, 1, tzinfo=datetime.timezone.utc),
57
+ pdunitlct_name="start",
58
+ pdunitlc_name="running",
59
+ pdord_num=None,
60
+ pdordlc_name=None,
61
+ )
62
+
63
+ serialized = pdunitlch.PdUnitLchEntryGet.model_validate(entry)
64
+
65
+ assert serialized.pdordlc_name is None
66
+
67
+
68
+ def test_mount_includes_pdunitlch_route() -> None:
69
+ from .helpers import collect_paths
70
+
71
+ app_router = APIRouter()
72
+
73
+ pdunitlch.mount(app_router)
74
+
75
+ paths = collect_paths(app_router)
76
+ assert "/pdunitlch" in paths
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "1.5",
3
- "distance": 0,
4
- "node": "ge0c4d91c83ebe49c587a5f576ac6030a84fefce4",
5
- "dirty": false,
6
- "branch": "HEAD",
7
- "node_date": "2026-07-03"
8
- }