trismik 0.9.12__py3-none-any.whl → 1.0.0__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.
- trismik/__init__.py +28 -0
- trismik/_async/__init__.py +1 -0
- trismik/_async/_test_transform.py +58 -0
- trismik/_async/client.py +731 -0
- trismik/_async/helpers.py +23 -0
- trismik/_mapper.py +9 -29
- trismik/_sync/__init__.py +1 -0
- trismik/_sync/_test_transform.py +58 -0
- trismik/_sync/client.py +731 -0
- trismik/_sync/helpers.py +27 -0
- trismik/_utils.py +1 -3
- trismik-1.0.0.dist-info/METADATA +258 -0
- trismik-1.0.0.dist-info/RECORD +18 -0
- trismik/adaptive_test.py +0 -669
- trismik/client_async.py +0 -405
- trismik-0.9.12.dist-info/METADATA +0 -177
- trismik-0.9.12.dist-info/RECORD +0 -12
- {trismik-0.9.12.dist-info → trismik-1.0.0.dist-info}/WHEEL +0 -0
- {trismik-0.9.12.dist-info → trismik-1.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Async helper functions for Trismik client."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from typing import Any, Callable
|
|
5
|
+
|
|
6
|
+
from trismik.types import TrismikItem
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
async def process_item(item_processor: Callable[[TrismikItem], Any], item: TrismikItem) -> Any:
|
|
10
|
+
"""
|
|
11
|
+
Process a test item with either sync or async processor.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
item_processor: Function to process the item (can be sync or async)
|
|
15
|
+
item: The test item to process
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
The processor's response
|
|
19
|
+
"""
|
|
20
|
+
if asyncio.iscoroutinefunction(item_processor):
|
|
21
|
+
return await item_processor(item)
|
|
22
|
+
# Run sync processor in thread pool to avoid blocking
|
|
23
|
+
return await asyncio.to_thread(item_processor, item)
|
trismik/_mapper.py
CHANGED
|
@@ -115,9 +115,7 @@ class TrismikResponseMapper:
|
|
|
115
115
|
run_info=TrismikResponseMapper.to_run_info(json["runInfo"]),
|
|
116
116
|
state=TrismikResponseMapper.to_run_state(json["state"]),
|
|
117
117
|
next_item=(
|
|
118
|
-
TrismikResponseMapper.to_item(json["nextItem"])
|
|
119
|
-
if json.get("nextItem")
|
|
120
|
-
else None
|
|
118
|
+
TrismikResponseMapper.to_item(json["nextItem"]) if json.get("nextItem") else None
|
|
121
119
|
),
|
|
122
120
|
completed=json.get("completed", False),
|
|
123
121
|
)
|
|
@@ -137,13 +135,8 @@ class TrismikResponseMapper:
|
|
|
137
135
|
id=json["id"],
|
|
138
136
|
dataset_id=json["datasetId"],
|
|
139
137
|
state=TrismikResponseMapper.to_run_state(json["state"]),
|
|
140
|
-
dataset=[
|
|
141
|
-
|
|
142
|
-
for item in json.get("dataset", [])
|
|
143
|
-
],
|
|
144
|
-
responses=TrismikResponseMapper.to_responses(
|
|
145
|
-
json.get("responses", [])
|
|
146
|
-
),
|
|
138
|
+
dataset=[TrismikResponseMapper.to_item(item) for item in json.get("dataset", [])],
|
|
139
|
+
responses=TrismikResponseMapper.to_responses(json.get("responses", [])),
|
|
147
140
|
metadata=json.get("metadata", {}),
|
|
148
141
|
)
|
|
149
142
|
|
|
@@ -175,9 +168,7 @@ class TrismikResponseMapper:
|
|
|
175
168
|
)
|
|
176
169
|
else:
|
|
177
170
|
item_type = json.get("type", "unknown")
|
|
178
|
-
raise TrismikApiError(
|
|
179
|
-
f"API has returned unrecognized item type: {item_type}"
|
|
180
|
-
)
|
|
171
|
+
raise TrismikApiError(f"API has returned unrecognized item type: {item_type}")
|
|
181
172
|
|
|
182
173
|
@staticmethod
|
|
183
174
|
def to_results(json: List[Dict[str, Any]]) -> List[TrismikResult]:
|
|
@@ -235,15 +226,11 @@ class TrismikResponseMapper:
|
|
|
235
226
|
# Parse datetime strings if they exist
|
|
236
227
|
completed_at = None
|
|
237
228
|
if "completedAt" in json and json["completedAt"]:
|
|
238
|
-
completed_at = datetime.fromisoformat(
|
|
239
|
-
json["completedAt"].replace("Z", "+00:00")
|
|
240
|
-
)
|
|
229
|
+
completed_at = datetime.fromisoformat(json["completedAt"].replace("Z", "+00:00"))
|
|
241
230
|
|
|
242
231
|
created_at = None
|
|
243
232
|
if "createdAt" in json and json["createdAt"]:
|
|
244
|
-
created_at = datetime.fromisoformat(
|
|
245
|
-
json["createdAt"].replace("Z", "+00:00")
|
|
246
|
-
)
|
|
233
|
+
created_at = datetime.fromisoformat(json["createdAt"].replace("Z", "+00:00"))
|
|
247
234
|
|
|
248
235
|
return TrismikReplayResponse(
|
|
249
236
|
id=json["id"],
|
|
@@ -253,13 +240,8 @@ class TrismikResponseMapper:
|
|
|
253
240
|
completedAt=completed_at,
|
|
254
241
|
createdAt=created_at,
|
|
255
242
|
metadata=json.get("metadata", {}),
|
|
256
|
-
dataset=[
|
|
257
|
-
|
|
258
|
-
for item in json.get("dataset", [])
|
|
259
|
-
],
|
|
260
|
-
responses=TrismikResponseMapper.to_responses(
|
|
261
|
-
json.get("responses", [])
|
|
262
|
-
),
|
|
243
|
+
dataset=[TrismikResponseMapper.to_item(item) for item in json.get("dataset", [])],
|
|
244
|
+
responses=TrismikResponseMapper.to_responses(json.get("responses", [])),
|
|
263
245
|
)
|
|
264
246
|
|
|
265
247
|
@staticmethod
|
|
@@ -299,9 +281,7 @@ class TrismikResponseMapper:
|
|
|
299
281
|
return TrismikMeResponse(user=user_info, teams=teams)
|
|
300
282
|
|
|
301
283
|
@staticmethod
|
|
302
|
-
def to_classic_eval_response(
|
|
303
|
-
json: Dict[str, Any]
|
|
304
|
-
) -> TrismikClassicEvalResponse:
|
|
284
|
+
def to_classic_eval_response(json: Dict[str, Any]) -> TrismikClassicEvalResponse:
|
|
305
285
|
"""
|
|
306
286
|
Convert JSON response to a TrismikClassicEvalResponse object.
|
|
307
287
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Async implementation of Trismik client (source of truth)."""
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Minimal test file to validate unasync transformation pipeline.
|
|
3
|
+
|
|
4
|
+
This file tests that unasync correctly transforms:
|
|
5
|
+
- async def -> def
|
|
6
|
+
- await -> (removed)
|
|
7
|
+
- httpx.AsyncClient -> httpx.Client
|
|
8
|
+
- TrismikAsyncClient -> TrismikClient
|
|
9
|
+
- __aenter__/__aexit__ -> __enter__/__exit__
|
|
10
|
+
- _async -> _sync in imports
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from typing import Optional
|
|
14
|
+
|
|
15
|
+
import httpx
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TrismikClient:
|
|
19
|
+
"""Test async client to validate transformation."""
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
api_key: str,
|
|
24
|
+
http_client: Optional[httpx.Client] = None,
|
|
25
|
+
) -> None:
|
|
26
|
+
"""Initialize test client."""
|
|
27
|
+
self._api_key = api_key
|
|
28
|
+
self._owns_client = http_client is None
|
|
29
|
+
self._http_client = http_client or httpx.Client(headers={"x-api-key": api_key})
|
|
30
|
+
|
|
31
|
+
def __enter__(self) -> "TrismikClient":
|
|
32
|
+
"""Enter async context manager."""
|
|
33
|
+
return self
|
|
34
|
+
|
|
35
|
+
def __exit__(self, exc_type: object, exc_val: object, exc_tb: object) -> None:
|
|
36
|
+
"""Exit async context manager."""
|
|
37
|
+
if self._owns_client:
|
|
38
|
+
self._http_client.close()
|
|
39
|
+
|
|
40
|
+
def close(self) -> None:
|
|
41
|
+
"""Close the HTTP client."""
|
|
42
|
+
if self._owns_client:
|
|
43
|
+
self._http_client.close()
|
|
44
|
+
|
|
45
|
+
def get_data(self) -> str:
|
|
46
|
+
"""Test async method with await."""
|
|
47
|
+
response = self._http_client.get("/test")
|
|
48
|
+
response.raise_for_status()
|
|
49
|
+
return str(response.text)
|
|
50
|
+
|
|
51
|
+
def process_items(self) -> int:
|
|
52
|
+
"""Test async method with multiple awaits."""
|
|
53
|
+
count = 0
|
|
54
|
+
with self._http_client as client:
|
|
55
|
+
response = client.get("/items")
|
|
56
|
+
data = response.json()
|
|
57
|
+
count = len(data)
|
|
58
|
+
return count
|