trismik 0.9.0__py3-none-any.whl → 0.9.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.
trismik/__init__.py CHANGED
@@ -1,20 +1,21 @@
1
- from .client import TrismikClient
2
- from .client_async import TrismikAsyncClient
3
- from .exceptions import (
4
- TrismikError,
5
- TrismikApiError
6
- )
7
- from .runner import TrismikRunner
8
- from .runner_async import TrismikAsyncRunner
9
- from .types import (
10
- TrismikTest,
11
- TrismikAuth,
12
- TrismikSession,
13
- TrismikItem,
14
- TrismikMultipleChoiceTextItem,
15
- TrismikChoice,
16
- TrismikTextChoice,
17
- TrismikResult,
18
- TrismikResponse,
19
- TrismikResultsAndResponses,
20
- )
1
+ from .client import TrismikClient
2
+ from .client_async import TrismikAsyncClient
3
+ from .exceptions import (
4
+ TrismikError,
5
+ TrismikApiError
6
+ )
7
+ from .runner import TrismikRunner
8
+ from .runner_async import TrismikAsyncRunner
9
+ from .types import (
10
+ TrismikTest,
11
+ TrismikAuth,
12
+ TrismikSession,
13
+ TrismikItem,
14
+ TrismikMultipleChoiceTextItem,
15
+ TrismikChoice,
16
+ TrismikTextChoice,
17
+ TrismikResult,
18
+ TrismikResponse,
19
+ TrismikRunResults,
20
+ TrismikSessionMetadata,
21
+ )
trismik/_mapper.py CHANGED
@@ -1,79 +1,79 @@
1
- from typing import List, Any
2
-
3
- from dateutil.parser import parse as parse_date
4
-
5
- from .exceptions import TrismikApiError
6
- from .types import (
7
- TrismikItem,
8
- TrismikResult,
9
- TrismikMultipleChoiceTextItem,
10
- TrismikTextChoice,
11
- TrismikAuth,
12
- TrismikTest,
13
- TrismikSession,
14
- TrismikResponse,
15
- )
16
-
17
-
18
- class TrismikResponseMapper:
19
-
20
- @staticmethod
21
- def to_auth(json: dict[str, Any]) -> TrismikAuth:
22
- return TrismikAuth(
23
- token=json["token"],
24
- expires=parse_date(json["expires"]),
25
- )
26
-
27
- @staticmethod
28
- def to_tests(json: List[dict[str, Any]]) -> List[TrismikTest]:
29
- return [
30
- TrismikTest(
31
- id=item["id"],
32
- name=item["name"],
33
- ) for item in json
34
- ]
35
-
36
- @staticmethod
37
- def to_session(json: dict[str, Any]) -> TrismikSession:
38
- return TrismikSession(
39
- id=json["id"],
40
- url=json["url"],
41
- status=json["status"],
42
- )
43
-
44
- @staticmethod
45
- def to_item(json: dict[str, Any]) -> TrismikItem:
46
- if json["type"] == "multiple_choice_text":
47
- return TrismikMultipleChoiceTextItem(
48
- id=json["id"],
49
- question=json["question"],
50
- choices=[
51
- TrismikTextChoice(
52
- id=choice["id"],
53
- text=choice["text"],
54
- ) for choice in json["choices"]
55
- ]
56
- )
57
- else:
58
- raise TrismikApiError(
59
- f"API has returned unrecognized item type: {json['type']}")
60
-
61
- @staticmethod
62
- def to_results(json: List[dict[str, Any]]) -> List[TrismikResult]:
63
- return [
64
- TrismikResult(
65
- trait=item["trait"],
66
- name=item["name"],
67
- value=item["value"],
68
- ) for item in json
69
- ]
70
-
71
- @staticmethod
72
- def to_responses(json: List[dict[str, Any]]) -> List[TrismikResponse]:
73
- return [
74
- TrismikResponse(
75
- item_id=response["itemId"],
76
- value=response["value"],
77
- score=response["score"],
78
- ) for response in json
79
- ]
1
+ from typing import List, Any
2
+
3
+ from dateutil.parser import parse as parse_date
4
+
5
+ from .exceptions import TrismikApiError
6
+ from .types import (
7
+ TrismikItem,
8
+ TrismikResult,
9
+ TrismikMultipleChoiceTextItem,
10
+ TrismikTextChoice,
11
+ TrismikAuth,
12
+ TrismikTest,
13
+ TrismikSession,
14
+ TrismikResponse,
15
+ )
16
+
17
+
18
+ class TrismikResponseMapper:
19
+
20
+ @staticmethod
21
+ def to_auth(json: dict[str, Any]) -> TrismikAuth:
22
+ return TrismikAuth(
23
+ token=json["token"],
24
+ expires=parse_date(json["expires"]),
25
+ )
26
+
27
+ @staticmethod
28
+ def to_tests(json: List[dict[str, Any]]) -> List[TrismikTest]:
29
+ return [
30
+ TrismikTest(
31
+ id=item["id"],
32
+ name=item["name"],
33
+ ) for item in json
34
+ ]
35
+
36
+ @staticmethod
37
+ def to_session(json: dict[str, Any]) -> TrismikSession:
38
+ return TrismikSession(
39
+ id=json["id"],
40
+ url=json["url"],
41
+ status=json["status"],
42
+ )
43
+
44
+ @staticmethod
45
+ def to_item(json: dict[str, Any]) -> TrismikItem:
46
+ if json["type"] == "multiple_choice_text":
47
+ return TrismikMultipleChoiceTextItem(
48
+ id=json["id"],
49
+ question=json["question"],
50
+ choices=[
51
+ TrismikTextChoice(
52
+ id=choice["id"],
53
+ text=choice["text"],
54
+ ) for choice in json["choices"]
55
+ ]
56
+ )
57
+ else:
58
+ raise TrismikApiError(
59
+ f"API has returned unrecognized item type: {json['type']}")
60
+
61
+ @staticmethod
62
+ def to_results(json: List[dict[str, Any]]) -> List[TrismikResult]:
63
+ return [
64
+ TrismikResult(
65
+ trait=item["trait"],
66
+ name=item["name"],
67
+ value=item["value"],
68
+ ) for item in json
69
+ ]
70
+
71
+ @staticmethod
72
+ def to_responses(json: List[dict[str, Any]]) -> List[TrismikResponse]:
73
+ return [
74
+ TrismikResponse(
75
+ item_id=response["itemId"],
76
+ value=response["value"],
77
+ score=response["score"],
78
+ ) for response in json
79
+ ]
trismik/_utils.py CHANGED
@@ -1,44 +1,44 @@
1
- import os
2
-
3
- import httpx
4
-
5
- from .exceptions import TrismikError
6
-
7
-
8
- class TrismikUtils:
9
-
10
- @staticmethod
11
- def get_error_message(response: httpx.Response) -> str:
12
- try:
13
- return (response.json()).get("message", "Unknown error")
14
- except (httpx.RequestError, ValueError):
15
- error_message = response.content.decode("utf-8", errors="ignore")
16
- return error_message
17
-
18
- @staticmethod
19
- def required_option(
20
- value: str | None,
21
- name: str,
22
- env: str
23
- ) -> str:
24
- if value is None:
25
- value = os.environ.get(env)
26
- if value is None:
27
- raise TrismikError(
28
- f"The {name} client option must be set either by passing "
29
- f"{env} to the client or by setting the {env} "
30
- "environment variable"
31
- )
32
- return value
33
-
34
- @staticmethod
35
- def option(
36
- value: str | None,
37
- default: str,
38
- env: str,
39
- ) -> str:
40
- if value is None:
41
- value = os.environ.get(env)
42
- if value is None:
43
- return default
44
- return value
1
+ import os
2
+
3
+ import httpx
4
+
5
+ from .exceptions import TrismikError
6
+
7
+
8
+ class TrismikUtils:
9
+
10
+ @staticmethod
11
+ def get_error_message(response: httpx.Response) -> str:
12
+ try:
13
+ return (response.json()).get("message", "Unknown error")
14
+ except (httpx.RequestError, ValueError):
15
+ error_message = response.content.decode("utf-8", errors="ignore")
16
+ return error_message
17
+
18
+ @staticmethod
19
+ def required_option(
20
+ value: str | None,
21
+ name: str,
22
+ env: str
23
+ ) -> str:
24
+ if value is None:
25
+ value = os.environ.get(env)
26
+ if value is None:
27
+ raise TrismikError(
28
+ f"The {name} client option must be set either by passing "
29
+ f"{env} to the client or by setting the {env} "
30
+ "environment variable"
31
+ )
32
+ return value
33
+
34
+ @staticmethod
35
+ def option(
36
+ value: str | None,
37
+ default: str,
38
+ env: str,
39
+ ) -> str:
40
+ if value is None:
41
+ value = os.environ.get(env)
42
+ if value is None:
43
+ return default
44
+ return value
trismik/client.py CHANGED
@@ -12,6 +12,7 @@ from .types import (
12
12
  TrismikItem,
13
13
  TrismikResult,
14
14
  TrismikResponse,
15
+ TrismikSessionMetadata
15
16
  )
16
17
 
17
18
 
@@ -120,7 +121,7 @@ class TrismikClient:
120
121
  except httpx.HTTPError as e:
121
122
  raise TrismikApiError(str(e)) from e
122
123
 
123
- def create_session(self, test_id: str, token: str) -> TrismikSession:
124
+ def create_session(self, test_id: str, metadata: TrismikSessionMetadata, token: str) -> TrismikSession:
124
125
  """
125
126
  Creates a new session for a test.
126
127
 
@@ -137,7 +138,7 @@ class TrismikClient:
137
138
  try:
138
139
  url = "/client/sessions"
139
140
  headers = {"Authorization": f"Bearer {token}"}
140
- body = {"testId": test_id, }
141
+ body = {"testId": test_id, "metadata": metadata.toDict() }
141
142
  response = self._http_client.post(url, headers=headers, json=body)
142
143
  response.raise_for_status()
143
144
  json = response.json()
@@ -147,6 +148,61 @@ class TrismikClient:
147
148
  TrismikUtils.get_error_message(e.response)) from e
148
149
  except httpx.HTTPError as e:
149
150
  raise TrismikApiError(str(e)) from e
151
+
152
+ def create_replay_session(self, previous_session_id: str, metadata: TrismikSessionMetadata, token: str) -> TrismikSession:
153
+ """
154
+ Creates a new session that replays exactly the question sequence of a previous session
155
+
156
+ Args:
157
+ previous_session_id (str): Session id of the session to replay.
158
+ token (str): Authentication token.
159
+
160
+ Returns:
161
+ TrismikSession: New session
162
+
163
+ Raises:
164
+ TrismikApiError: If API request fails.
165
+ """
166
+ try:
167
+ url = "/client/sessions/replay"
168
+ headers = {"Authorization": f"Bearer {token}"}
169
+ body = {"previousSessionToken": previous_session_id, "metadata": metadata.toDict(), }
170
+ response = self._http_client.post(url, headers=headers, json=body)
171
+ response.raise_for_status()
172
+ json = response.json()
173
+ return TrismikResponseMapper.to_session(json)
174
+ except httpx.HTTPStatusError as e:
175
+ raise TrismikApiError(
176
+ TrismikUtils.get_error_message(e.response)) from e
177
+ except httpx.HTTPError as e:
178
+ raise TrismikApiError(str(e)) from e
179
+
180
+ def add_metadata(self, session_id: str, metadata: TrismikSessionMetadata, token: str) -> None:
181
+ """
182
+ Adds metadata to the session, merging it with any already stored
183
+
184
+ Args:
185
+ session_id (str): id of the session object
186
+ metadata: object cotaining the metadata to add
187
+ token (str): Authentication token.
188
+
189
+ Returns:
190
+ None
191
+
192
+ Raises:
193
+ TrismikApiError: If API request fails.
194
+ """
195
+ try:
196
+ url = f"/client/sessions/{session_id}/metadata"
197
+ headers = {"Authorization": f"Bearer {token}"}
198
+ body = metadata.toDict()
199
+ response = self._http_client.post(url, headers=headers, json=body)
200
+ response.raise_for_status()
201
+ except httpx.HTTPStatusError as e:
202
+ raise TrismikApiError(
203
+ TrismikUtils.get_error_message(e.response)) from e
204
+ except httpx.HTTPError as e:
205
+ raise TrismikApiError(str(e)) from e
150
206
 
151
207
  def current_item(
152
208
  self,