mindbridge-api-python-client 1.4.8__tar.gz → 1.4.9__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 (43) hide show
  1. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/PKG-INFO +5 -6
  2. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/pyproject.toml +4 -4
  3. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/analyses.py +17 -35
  4. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/analysis_item.py +1 -1
  5. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/base_set.py +22 -21
  6. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/common_validators.py +2 -2
  7. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/data_tables.py +1 -1
  8. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/file_manager.py +1 -1
  9. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/generated_pydantic_model/model.py +1349 -2006
  10. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/LICENSE.txt +0 -0
  11. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/README.md +0 -0
  12. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/__init__.py +0 -0
  13. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/accounting_period.py +0 -0
  14. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/analysis_period.py +0 -0
  15. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/analysis_source_item.py +0 -0
  16. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/analysis_source_type_item.py +0 -0
  17. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/analysis_source_types.py +0 -0
  18. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/analysis_sources.py +0 -0
  19. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/analysis_type_item.py +0 -0
  20. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/analysis_types.py +0 -0
  21. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/async_results.py +0 -0
  22. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/chunked_file_item.py +0 -0
  23. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/chunked_file_part_item.py +0 -0
  24. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/chunked_files.py +0 -0
  25. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/column_mapping.py +0 -0
  26. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/engagement_item.py +0 -0
  27. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/engagements.py +0 -0
  28. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/enumerations/analysis_source_type.py +0 -0
  29. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/enumerations/analysis_type.py +0 -0
  30. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/enumerations/deprecated_enum.py +0 -0
  31. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/enumerations/system_library.py +0 -0
  32. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/exceptions.py +0 -0
  33. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/file_manager_item.py +0 -0
  34. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/libraries.py +0 -0
  35. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/library_item.py +0 -0
  36. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/organization_item.py +0 -0
  37. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/organizations.py +0 -0
  38. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/server.py +0 -0
  39. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/task_item.py +0 -0
  40. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/tasks.py +0 -0
  41. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/transaction_id_selection.py +0 -0
  42. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/users.py +0 -0
  43. {mindbridge_api_python_client-1.4.8 → mindbridge_api_python_client-1.4.9}/src/mindbridgeapi/virtual_column.py +0 -0
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mindbridge-api-python-client
3
- Version: 1.4.8
3
+ Version: 1.4.9
4
4
  Summary: Interact with the MindBridge API
5
5
  Home-page: https://www.mindbridge.ai
6
6
  License: Proprietary
7
- Author: Edgar Silva
8
- Author-email: edgar.silva@mindbridge.ai
9
- Maintainer: Kevin Paulson
10
- Maintainer-email: kevin.paulson@mindbridge.ai
7
+ Author: MBAI Support
8
+ Author-email: mbaisupport@mindbridge.ai
9
+ Maintainer: MBAI Support
10
+ Maintainer-email: mbaisupport@mindbridge.ai
11
11
  Requires-Python: >=3.8.1,<4.0
12
12
  Classifier: Development Status :: 4 - Beta
13
13
  Classifier: Framework :: Flake8
@@ -28,7 +28,6 @@ Classifier: Typing :: Typed
28
28
  Requires-Dist: pydantic (>=2.5.2,<3.0.0)
29
29
  Requires-Dist: typing-extensions (>=4.0.0,<5.0.0) ; python_version < "3.9"
30
30
  Requires-Dist: urllib3 (>=2.0.7,<3.0.0)
31
- Project-URL: Repository, https://github.com/mindbridge-ai/mindbridge-api-python-client
32
31
  Description-Content-Type: text/markdown
33
32
 
34
33
  <h1 align="center">MindBridge API Python Client</h1>
@@ -4,20 +4,20 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "mindbridge-api-python-client"
7
- version = "1.4.8"
7
+ version = "1.4.9"
8
8
  description = "Interact with the MindBridge API"
9
9
  license = "Proprietary"
10
10
  authors = [
11
+ "MBAI Support <mbaisupport@mindbridge.ai>", # Must be first so that PyPI displays this
11
12
  "Edgar Silva <edgar.silva@mindbridge.ai>",
12
13
  "Jordan Hatcher <jordan.hatcher@mindbridge.ai>",
13
14
  "Kevin Paulson <kevin.paulson@mindbridge.ai",
14
15
  "Michael Smith <msmith@mindbridge.ai>",
15
16
  "Wing-Leung Chan <wing-leung.chan@mindbridge.ai>",
16
17
  ]
17
- maintainers = [ "Kevin Paulson <kevin.paulson@mindbridge.ai>" ]
18
+ maintainers = [ "MBAI Support <mbaisupport@mindbridge.ai>" ]
18
19
  readme = "README.md"
19
20
  homepage = "https://www.mindbridge.ai"
20
- repository = "https://github.com/mindbridge-ai/mindbridge-api-python-client"
21
21
  classifiers = [
22
22
  "Development Status :: 4 - Beta",
23
23
  "Framework :: Flake8",
@@ -50,7 +50,7 @@ urllib3 = "^2.0.7"
50
50
  optional = true
51
51
 
52
52
  [tool.poetry.group.generate_model.dependencies]
53
- datamodel-code-generator = "^0.25.1"
53
+ datamodel-code-generator = "^0.26.0"
54
54
 
55
55
  [tool.poetry.group.lint]
56
56
  optional = true
@@ -56,11 +56,7 @@ class Analyses(BaseSet):
56
56
  url = self.base_url
57
57
  resp_dict = super()._create(url=url, json=item.create_json)
58
58
  analysis = AnalysisItem.model_validate(resp_dict)
59
- self.restart_analysis_sources(analysis)
60
- self.restart_data_tables(analysis)
61
- self.restart_tasks(analysis)
62
-
63
- return analysis
59
+ return self._restart_all_children(analysis)
64
60
 
65
61
  def update(self, item: AnalysisItem) -> AnalysisItem:
66
62
  if getattr(item, "id", None) is None:
@@ -70,11 +66,7 @@ class Analyses(BaseSet):
70
66
  resp_dict = super()._update(url=url, json=item.update_json)
71
67
 
72
68
  analysis = AnalysisItem.model_validate(resp_dict)
73
- self.restart_analysis_sources(analysis)
74
- self.restart_data_tables(analysis)
75
- self.restart_tasks(analysis)
76
-
77
- return analysis
69
+ return self._restart_all_children(analysis)
78
70
 
79
71
  def get(
80
72
  self, json: Optional[Dict[str, Any]] = None
@@ -85,11 +77,7 @@ class Analyses(BaseSet):
85
77
  url = f"{self.base_url}/query"
86
78
  for resp_dict in super()._get(url=url, json=json):
87
79
  analysis = AnalysisItem.model_validate(resp_dict)
88
- self.restart_analysis_sources(analysis)
89
- self.restart_data_tables(analysis)
90
- self.restart_tasks(analysis)
91
-
92
- yield analysis
80
+ yield self._restart_all_children(analysis)
93
81
 
94
82
  def delete(self, item: AnalysisItem) -> None:
95
83
  if getattr(item, "id", None) is None:
@@ -110,16 +98,7 @@ class Analyses(BaseSet):
110
98
  raise ItemNotFoundError
111
99
 
112
100
  url = f"{self.base_url}/{analysis_id}/run"
113
- resp_dict = super()._create(url=url)
114
- async_result = ApiAsyncResult.model_validate(resp_dict)
115
-
116
- if async_result.type != AsyncResultType.ANALYSIS_RUN:
117
- raise ItemError(f"Async Result Type was {async_result.type}.")
118
-
119
- if async_result.entity_id != analysis_id:
120
- raise UnexpectedServerError(
121
- details="async_result.entity_id was not the same as the item id"
122
- )
101
+ _ = super()._create(url=url)
123
102
 
124
103
  return self.get_by_id(analysis_id)
125
104
 
@@ -279,23 +258,22 @@ class Analyses(BaseSet):
279
258
 
280
259
  del check_interval_seconds
281
260
 
282
- analysis_id = getattr(analysis, "id", None)
283
- if analysis_id is None:
261
+ if analysis.id is None:
284
262
  raise ItemNotFoundError
285
263
 
286
264
  async_results = self.async_result_set.get(
287
265
  json={
288
266
  "$and": [
289
- {"entityId": {"$eq": analysis_id}},
267
+ {"entityId": {"$eq": analysis.id}},
290
268
  {"type": {"$eq": AsyncResultType.ANALYSIS_RUN}},
291
269
  {"entityType": {"$eq": EntityType.ANALYSIS}},
292
270
  ]
293
271
  }
294
272
  )
295
273
  async_results_list = list(async_results)
296
- if len(async_results_list) == 0:
274
+ if not async_results_list:
297
275
  raise ValidationError(
298
- f"Unable to find {EntityType.ANALYSIS} run status for: {analysis_id}."
276
+ f"Unable to find {EntityType.ANALYSIS} run status for: {analysis.id}."
299
277
  " Possibly the analysis has not been started yet?"
300
278
  )
301
279
 
@@ -309,7 +287,7 @@ class Analyses(BaseSet):
309
287
  init_interval_sec=76,
310
288
  )
311
289
 
312
- return self.get_by_id(analysis_id)
290
+ return self.get_by_id(analysis.id)
313
291
 
314
292
  def roll_forward_analysis_to_engagement(
315
293
  self,
@@ -353,24 +331,28 @@ class Analyses(BaseSet):
353
331
  url = f"{self.base_url}/{id}"
354
332
  resp_dict = super()._get_by_id(url=url)
355
333
  analysis = AnalysisItem.model_validate(resp_dict)
334
+ return self._restart_all_children(analysis)
335
+
336
+ def _restart_all_children(self, analysis: AnalysisItem) -> AnalysisItem:
356
337
  self.restart_analysis_sources(analysis)
357
338
  self.restart_data_tables(analysis)
339
+ self.restart_tasks(analysis)
358
340
 
359
341
  return analysis
360
342
 
361
- def restart_data_tables(self, analysis_item: AnalysisItem) -> None:
343
+ def restart_analysis_sources(self, analysis_item: AnalysisItem) -> None:
362
344
  if getattr(analysis_item, "id", None) is None:
363
345
  raise ItemNotFoundError
364
346
 
365
- analysis_item.data_tables = DataTables(server=self.server).get(
347
+ analysis_item.analysis_sources = AnalysisSources(server=self.server).get(
366
348
  json={"analysisId": {"$eq": analysis_item.id}}
367
349
  )
368
350
 
369
- def restart_analysis_sources(self, analysis_item: AnalysisItem) -> None:
351
+ def restart_data_tables(self, analysis_item: AnalysisItem) -> None:
370
352
  if getattr(analysis_item, "id", None) is None:
371
353
  raise ItemNotFoundError
372
354
 
373
- analysis_item.analysis_sources = AnalysisSources(server=self.server).get(
355
+ analysis_item.data_tables = DataTables(server=self.server).get(
374
356
  json={"analysisId": {"$eq": analysis_item.id}}
375
357
  )
376
358
 
@@ -163,5 +163,5 @@ class AnalysisItem(ApiAnalysisRead):
163
163
  days=1
164
164
  )
165
165
 
166
- earliest_period = AnalysisPeriod(start_date=start_date, end_date=end_date) # type: ignore[call-arg]
166
+ earliest_period = AnalysisPeriod(start_date=start_date, end_date=end_date)
167
167
  self.analysis_periods.append(earliest_period)
@@ -39,34 +39,35 @@ class BaseSet:
39
39
  ) -> Generator[Dict[str, Any], None, None]:
40
40
  item_holder: List[Dict[str, Any]] = []
41
41
  page_number = 0
42
- page_is_not_last = True
42
+ more_pages_to_check = True
43
43
 
44
- while True:
45
- if len(item_holder) != 0:
46
- yield item_holder.pop(0)
47
- elif page_is_not_last:
48
- params = {"page": page_number}
49
- request_url = f"{url}?{urlencode(params)}"
44
+ while item_holder or more_pages_to_check:
45
+ if not item_holder:
46
+ content = self._get_page(url=url, json=json, page_number=page_number)
50
47
 
51
- resp = self.server.http.request("POST", request_url, json=json)
52
- self._check_response(resp)
53
- resp_dict = self._response_as_dict(resp)
48
+ if not content:
49
+ more_pages_to_check = False
50
+ else:
51
+ item_holder.extend(content)
52
+ page_number = page_number + 1
54
53
 
55
- if "last" not in resp_dict or not isinstance(resp_dict["last"], bool):
56
- raise UnexpectedServerError(f"{resp_dict}")
54
+ if item_holder:
55
+ yield item_holder.pop(0)
57
56
 
58
- page_is_not_last = not resp_dict["last"]
57
+ def _get_page(
58
+ self, url: str, json: Dict[str, Any], page_number: int
59
+ ) -> List[Dict[str, Any]]:
60
+ params = {"page": page_number}
61
+ request_url = f"{url}?{urlencode(params)}"
59
62
 
60
- if "content" not in resp_dict or not isinstance(
61
- resp_dict["content"], list
62
- ):
63
- raise UnexpectedServerError(f"{resp_dict}")
63
+ resp = self.server.http.request("POST", request_url, json=json)
64
+ self._check_response(resp)
65
+ resp_dict = self._response_as_dict(resp)
64
66
 
65
- item_holder.extend(resp_dict["content"])
67
+ if "content" not in resp_dict or not isinstance(resp_dict["content"], list):
68
+ raise UnexpectedServerError(f"{resp_dict}")
66
69
 
67
- page_number = page_number + 1
68
- else:
69
- return # No more items
70
+ return resp_dict["content"]
70
71
 
71
72
  def _create(
72
73
  self,
@@ -62,10 +62,10 @@ def _convert_userinfo_to_useritem(v: Any) -> Any:
62
62
 
63
63
  prefix = "(API) "
64
64
  if v.user_name is None or not v.user_name.startswith(prefix):
65
- return UserItem(id=v.user_id, first_name=v.user_name) # type: ignore[call-arg]
65
+ return UserItem(id=v.user_id, first_name=v.user_name)
66
66
 
67
67
  prefix_len = len(prefix)
68
68
  first_name = v.user_name[prefix_len:]
69
- return UserItem( # type: ignore[call-arg]
69
+ return UserItem(
70
70
  id=v.user_id, first_name=first_name, last_name="", role=Role.ROLE_ADMIN
71
71
  )
@@ -133,7 +133,7 @@ class DataTables(BaseSet):
133
133
  sort_direction = None
134
134
 
135
135
  url = f"{self.base_url}/{input_item.id}/export"
136
- data_table_export_request = ApiDataTableExportRequest( # type: ignore[call-arg]
136
+ data_table_export_request = ApiDataTableExportRequest(
137
137
  fields=fields,
138
138
  query=MindBridgeQueryTerm.model_construct(root=query),
139
139
  limit=limit,
@@ -148,7 +148,7 @@ class FileManager(BaseSet):
148
148
 
149
149
  logger.info('Using the "Chunked Files" method')
150
150
  chunked_files = ChunkedFiles(server=self.server)
151
- chunked_file = ChunkedFileItem(size=file_size, name=file_name) # type: ignore[call-arg]
151
+ chunked_file = ChunkedFileItem(size=file_size, name=file_name)
152
152
  chunked_file = chunked_files.create(chunked_file)
153
153
 
154
154
  with open(input_file_path, "rb") as file: