hardpy 0.19.1__py3-none-any.whl → 0.20.1__py3-none-any.whl

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 (26) hide show
  1. hardpy/__init__.py +9 -0
  2. hardpy/cli/cli.py +29 -0
  3. hardpy/common/config.py +19 -0
  4. hardpy/hardpy_panel/api.py +62 -1
  5. hardpy/hardpy_panel/frontend/dist/assets/{allPaths-C_-7WXHD.js → allPaths-CLpOX_m7.js} +1 -1
  6. hardpy/hardpy_panel/frontend/dist/assets/{allPathsLoader-DgH0Xily.js → allPathsLoader-BZScMaOY.js} +2 -2
  7. hardpy/hardpy_panel/frontend/dist/assets/{browser-ponyfill-BbOvdqIF.js → browser-ponyfill-BTcpcLno.js} +1 -1
  8. hardpy/hardpy_panel/frontend/dist/assets/{index-DEJb2W0B.js → index-1i9Rm0C7.js} +189 -322
  9. hardpy/hardpy_panel/frontend/dist/assets/index-DN3Ur-pw.css +1 -0
  10. hardpy/hardpy_panel/frontend/dist/assets/{splitPathsBySizeLoader-o5HCcdVL.js → splitPathsBySizeLoader-CfM4kXSA.js} +1 -1
  11. hardpy/hardpy_panel/frontend/dist/index.html +2 -2
  12. hardpy/pytest_hardpy/db/__init__.py +0 -2
  13. hardpy/pytest_hardpy/db/runstore.py +378 -10
  14. hardpy/pytest_hardpy/db/statestore.py +390 -5
  15. hardpy/pytest_hardpy/db/tempstore.py +219 -17
  16. hardpy/pytest_hardpy/plugin.py +2 -2
  17. hardpy/pytest_hardpy/result/__init__.py +2 -0
  18. hardpy/pytest_hardpy/result/report_loader/json_loader.py +49 -0
  19. hardpy/pytest_hardpy/result/report_synchronizer/synchronizer.py +25 -9
  20. {hardpy-0.19.1.dist-info → hardpy-0.20.1.dist-info}/METADATA +32 -15
  21. {hardpy-0.19.1.dist-info → hardpy-0.20.1.dist-info}/RECORD +24 -24
  22. hardpy/hardpy_panel/frontend/dist/assets/index-B7T9xvaW.css +0 -1
  23. hardpy/pytest_hardpy/db/base_store.py +0 -179
  24. {hardpy-0.19.1.dist-info → hardpy-0.20.1.dist-info}/WHEEL +0 -0
  25. {hardpy-0.19.1.dist-info → hardpy-0.20.1.dist-info}/entry_points.txt +0 -0
  26. {hardpy-0.19.1.dist-info → hardpy-0.20.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,179 +0,0 @@
1
- # Copyright (c) 2024 Everypin
2
- # GNU General Public License v3.0 (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
3
-
4
- from json import dumps
5
- from logging import getLogger
6
- from typing import Any
7
-
8
- from glom import assign, glom
9
- from pycouchdb import Server as DbServer
10
- from pycouchdb.client import Database
11
- from pycouchdb.exceptions import Conflict, GenericError, NotFound
12
- from pydantic._internal._model_construction import ModelMetaclass
13
- from requests.exceptions import ConnectionError # noqa: A004
14
-
15
- from hardpy.common.config import ConfigManager
16
- from hardpy.pytest_hardpy.db.const import DatabaseField as DF # noqa: N817
17
-
18
-
19
- class BaseStore:
20
- """HardPy base storage interface for CouchDB."""
21
-
22
- def __init__(self, db_name: str) -> None:
23
- config_manager = ConfigManager()
24
- config = config_manager.config
25
- self._db_srv = DbServer(config.database.url)
26
- self._db_name = db_name
27
- self._db = self._init_db()
28
- self._doc_id = config.database.doc_id
29
- self._log = getLogger(__name__)
30
- self._doc: dict = self._init_doc()
31
- self._schema: ModelMetaclass
32
-
33
- def compact(self) -> None:
34
- """Compact database."""
35
- self._db.compact()
36
-
37
- def get_field(self, key: str) -> Any: # noqa: ANN401
38
- """Get field from the state store.
39
-
40
- Args:
41
- key (str): field name
42
-
43
- Returns:
44
- Any: field value
45
- """
46
- return glom(self._doc, key)
47
-
48
- def update_doc_value(self, key: str, value: Any) -> None: # noqa: ANN401
49
- """Update document value.
50
-
51
- HardPy collecting uses a simple key without dots.
52
- Assign is used to update a document.
53
- Assign is a longer function.
54
-
55
- Args:
56
- key (str): document key
57
- value: document value
58
- """
59
- try:
60
- dumps(value)
61
- except Exception: # noqa: BLE001
62
- # serialize non-serializable objects as string
63
- value = dumps(value, default=str)
64
- if "." in key:
65
- assign(self._doc, key, value)
66
- else:
67
- self._doc[key] = value
68
-
69
- def update_db(self) -> None:
70
- """Update database by current document."""
71
- try:
72
- self._doc = self._db.save(self._doc)
73
- except Conflict:
74
- self._doc["_rev"] = self._db.get(self._doc_id)["_rev"]
75
- self._doc = self._db.save(self._doc)
76
-
77
- def update_doc(self) -> None:
78
- """Update current document by database."""
79
- self._doc["_rev"] = self._db.get(self._doc_id)["_rev"]
80
- self._doc = self._db.get(self._doc_id)
81
-
82
- def get_document(self) -> ModelMetaclass:
83
- """Get document by schema.
84
-
85
- Returns:
86
- ModelMetaclass: document by schema
87
- """
88
- self._doc = self._db.get(self._doc_id)
89
- return self._schema(**self._doc)
90
-
91
- def clear(self) -> None:
92
- """Clear database."""
93
- try:
94
- # Clear statestore and runstore databases before each launch
95
- self._db.delete(self._doc_id)
96
- except (Conflict, NotFound):
97
- self._log.debug("Database will be created for the first time")
98
- self._doc: dict = self._init_doc()
99
-
100
- def _init_db(self) -> Database:
101
- try:
102
- return self._db_srv.create(self._db_name) # type: ignore
103
- except Conflict:
104
- # database is already created
105
- return self._db_srv.database(self._db_name)
106
- except GenericError as exc:
107
- msg = f"Error initializing database {exc}"
108
- raise RuntimeError(msg) from exc
109
- except ConnectionError as exc:
110
- msg = f"Error initializing database: {exc}"
111
- raise RuntimeError(msg) from exc
112
-
113
- def _init_doc(self) -> dict:
114
- try:
115
- doc = self._db.get(self._doc_id)
116
- except NotFound:
117
- return {
118
- "_id": self._doc_id,
119
- DF.MODULES: {},
120
- DF.DUT: {
121
- DF.TYPE: None,
122
- DF.NAME: None,
123
- DF.REVISION: None,
124
- DF.SERIAL_NUMBER: None,
125
- DF.PART_NUMBER: None,
126
- DF.SUB_UNITS: [],
127
- DF.INFO: {},
128
- },
129
- DF.TEST_STAND: {
130
- DF.HW_ID: None,
131
- DF.NAME: None,
132
- DF.REVISION: None,
133
- DF.TIMEZONE: None,
134
- DF.LOCATION: None,
135
- DF.NUMBER: None,
136
- DF.INSTRUMENTS: [],
137
- DF.DRIVERS: {},
138
- DF.INFO: {},
139
- },
140
- DF.PROCESS: {
141
- DF.NAME: None,
142
- DF.NUMBER: None,
143
- DF.INFO: {},
144
- },
145
- }
146
-
147
- # init document
148
- if DF.MODULES not in doc:
149
- doc[DF.MODULES] = {}
150
-
151
- doc[DF.DUT] = {
152
- DF.TYPE: None,
153
- DF.NAME: None,
154
- DF.REVISION: None,
155
- DF.SERIAL_NUMBER: None,
156
- DF.PART_NUMBER: None,
157
- DF.SUB_UNITS: [],
158
- DF.INFO: {},
159
- }
160
-
161
- doc[DF.TEST_STAND] = {
162
- DF.HW_ID: None,
163
- DF.NAME: None,
164
- DF.REVISION: None,
165
- DF.TIMEZONE: None,
166
- DF.LOCATION: None,
167
- DF.NUMBER: None,
168
- DF.INSTRUMENTS: [],
169
- DF.DRIVERS: {},
170
- DF.INFO: {},
171
- }
172
-
173
- doc[DF.PROCESS] = {
174
- DF.NAME: None,
175
- DF.NUMBER: None,
176
- DF.INFO: {},
177
- }
178
-
179
- return doc