lucius-mcp 0.3.0__py3-none-any.whl → 0.4.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.
Files changed (39) hide show
  1. lucius_mcp-0.4.0.dist-info/METADATA +124 -0
  2. {lucius_mcp-0.3.0.dist-info → lucius_mcp-0.4.0.dist-info}/RECORD +38 -29
  3. src/client/__init__.py +6 -0
  4. src/client/client.py +271 -7
  5. src/client/exceptions.py +23 -0
  6. src/client/generated/README.md +18 -0
  7. src/client/generated/__init__.py +2 -0
  8. src/client/generated/api/__init__.py +1 -0
  9. src/client/generated/api/integration_controller_api.py +5285 -0
  10. src/client/generated/docs/IntegrationControllerApi.md +1224 -0
  11. src/services/__init__.py +9 -1
  12. src/services/custom_field_value_service.py +301 -0
  13. src/services/integration_service.py +205 -0
  14. src/services/launch_service.py +29 -1
  15. src/services/shared_step_service.py +34 -17
  16. src/services/test_case_service.py +269 -37
  17. src/services/test_layer_service.py +11 -0
  18. src/tools/__init__.py +19 -1
  19. src/tools/create_custom_field_value.py +38 -0
  20. src/tools/create_test_case.py +32 -2
  21. src/tools/delete_custom_field_value.py +57 -0
  22. src/tools/delete_test_case.py +5 -4
  23. src/tools/delete_test_layer.py +17 -4
  24. src/tools/delete_test_layer_schema.py +17 -4
  25. src/tools/launches.py +86 -0
  26. src/tools/link_shared_step.py +18 -12
  27. src/tools/list_custom_field_values.py +72 -0
  28. src/tools/list_integrations.py +77 -0
  29. src/tools/search.py +3 -3
  30. src/tools/shared_steps.py +23 -8
  31. src/tools/unlink_shared_step.py +19 -5
  32. src/tools/update_custom_field_value.py +55 -0
  33. src/tools/update_test_case.py +67 -2
  34. src/tools/update_test_layer.py +15 -4
  35. src/tools/update_test_layer_schema.py +16 -5
  36. lucius_mcp-0.3.0.dist-info/METADATA +0 -297
  37. {lucius_mcp-0.3.0.dist-info → lucius_mcp-0.4.0.dist-info}/WHEEL +0 -0
  38. {lucius_mcp-0.3.0.dist-info → lucius_mcp-0.4.0.dist-info}/entry_points.txt +0 -0
  39. {lucius_mcp-0.3.0.dist-info → lucius_mcp-0.4.0.dist-info}/licenses/LICENSE +0 -0
src/client/client.py CHANGED
@@ -10,7 +10,7 @@ from collections.abc import Awaitable
10
10
  from typing import Literal, TypeVar, cast, overload
11
11
 
12
12
  import httpx
13
- from pydantic import SecretStr, ValidationError
13
+ from pydantic import Field, SecretStr, ValidationError
14
14
 
15
15
  from src.client.exceptions import TestCaseNotFoundError
16
16
  from src.utils.config import settings
@@ -26,7 +26,9 @@ from .exceptions import (
26
26
  from .generated.api.custom_field_controller_api import CustomFieldControllerApi
27
27
  from .generated.api.custom_field_project_controller_api import CustomFieldProjectControllerApi
28
28
  from .generated.api.custom_field_project_controller_v2_api import CustomFieldProjectControllerV2Api
29
+ from .generated.api.custom_field_value_controller_api import CustomFieldValueControllerApi
29
30
  from .generated.api.custom_field_value_project_controller_api import CustomFieldValueProjectControllerApi
31
+ from .generated.api.integration_controller_api import IntegrationControllerApi
30
32
  from .generated.api.launch_controller_api import LaunchControllerApi
31
33
  from .generated.api.launch_search_controller_api import LaunchSearchControllerApi
32
34
  from .generated.api.shared_step_attachment_controller_api import SharedStepAttachmentControllerApi
@@ -46,17 +48,23 @@ from .generated.models.aql_validate_response_dto import AqlValidateResponseDto
46
48
  from .generated.models.attachment_step_dto import AttachmentStepDto
47
49
  from .generated.models.body_step_dto import BodyStepDto
48
50
  from .generated.models.custom_field_project_with_values_dto import CustomFieldProjectWithValuesDto
51
+ from .generated.models.custom_field_value_project_create_dto import CustomFieldValueProjectCreateDto
52
+ from .generated.models.custom_field_value_project_patch_dto import CustomFieldValueProjectPatchDto
49
53
  from .generated.models.custom_field_value_with_cf_dto import CustomFieldValueWithCfDto
50
54
  from .generated.models.custom_field_with_values_dto import CustomFieldWithValuesDto
51
55
  from .generated.models.find_all29200_response import FindAll29200Response
56
+ from .generated.models.integration_dto import IntegrationDto
57
+ from .generated.models.issue_dto import IssueDto
52
58
  from .generated.models.launch_create_dto import LaunchCreateDto
53
59
  from .generated.models.launch_dto import LaunchDto
60
+ from .generated.models.page_custom_field_value_with_tc_count_dto import PageCustomFieldValueWithTcCountDto
54
61
  from .generated.models.page_launch_dto import PageLaunchDto
55
62
  from .generated.models.page_launch_preview_dto import PageLaunchPreviewDto
56
63
  from .generated.models.page_shared_step_dto import PageSharedStepDto
57
64
  from .generated.models.page_test_case_dto import PageTestCaseDto
58
65
  from .generated.models.scenario_step_create_dto import ScenarioStepCreateDto
59
66
  from .generated.models.scenario_step_created_response_dto import ScenarioStepCreatedResponseDto
67
+ from .generated.models.scenario_step_patch_dto import ScenarioStepPatchDto
60
68
  from .generated.models.shared_step_attachment_row_dto import SharedStepAttachmentRowDto
61
69
  from .generated.models.shared_step_create_dto import SharedStepCreateDto
62
70
  from .generated.models.shared_step_dto import SharedStepDto
@@ -77,9 +85,13 @@ from .overridden.test_case_custom_fields_v2 import TestCaseCustomFieldV2Controll
77
85
 
78
86
  # Subclasses to add missing fields to generated models
79
87
  class TestCaseDtoWithCF(TestCaseDto):
80
- """Subclass to support custom_fields access."""
88
+ """Subclass to support custom_fields and issues access."""
81
89
 
82
90
  custom_fields: list[CustomFieldValueWithCfDto] | None = None
91
+ issues: list[IssueDto] | None = None
92
+
93
+
94
+ TestCaseDtoWithCF.model_rebuild()
83
95
 
84
96
 
85
97
  class BodyStepDtoWithSteps(BodyStepDto):
@@ -89,6 +101,14 @@ class BodyStepDtoWithSteps(BodyStepDto):
89
101
  id: int | None = None
90
102
 
91
103
 
104
+ class StepWithExpected(BodyStepDto):
105
+ """Subclass to support expected results and nested steps."""
106
+
107
+ expected_result: str | None = Field(default=None, alias="expectedResult")
108
+ steps: list[SharedStepScenarioDtoStepsInner] | None = None
109
+ id: int | None = None
110
+
111
+
92
112
  class AttachmentStepDtoWithName(AttachmentStepDto):
93
113
  """Subclass to support name attribute and id."""
94
114
 
@@ -119,11 +139,13 @@ type ApiType = (
119
139
  | CustomFieldControllerApi
120
140
  | CustomFieldProjectControllerApi
121
141
  | CustomFieldProjectControllerV2Api
142
+ | CustomFieldValueControllerApi
122
143
  | CustomFieldValueProjectControllerApi
123
144
  | TestLayerControllerApi
124
145
  | TestLayerSchemaControllerApi
125
146
  | LaunchControllerApi
126
147
  | LaunchSearchControllerApi
148
+ | IntegrationControllerApi
127
149
  )
128
150
 
129
151
  type NormalizedScenarioDict = dict[str, object]
@@ -148,12 +170,14 @@ __all__ = [
148
170
  "PageTestCaseDto",
149
171
  "ScenarioStepCreateDto",
150
172
  "ScenarioStepCreatedResponseDto",
173
+ "ScenarioStepPatchDto",
151
174
  "SharedStepAttachmentRowDto",
152
175
  "SharedStepCreateDto",
153
176
  "SharedStepDto",
154
177
  "SharedStepPatchDto",
155
178
  "SharedStepScenarioDtoStepsInner",
156
179
  "SharedStepStepDtoWithId",
180
+ "StepWithExpected",
157
181
  "TestCaseAttachmentRowDto",
158
182
  "TestCaseCreateV2Dto",
159
183
  "TestCaseDto",
@@ -229,11 +253,13 @@ class AllureClient:
229
253
  self._custom_field_api: CustomFieldControllerApi | None = None
230
254
  self._custom_field_project_api: CustomFieldProjectControllerApi | None = None
231
255
  self._custom_field_project_v2_api: CustomFieldProjectControllerV2Api | None = None
256
+ self._custom_field_value_api: CustomFieldValueControllerApi | None = None
232
257
  self._custom_field_value_project_api: CustomFieldValueProjectControllerApi | None = None
233
258
  self._test_layer_api: TestLayerControllerApi | None = None
234
259
  self._test_layer_schema_api: TestLayerSchemaControllerApi | None = None
235
260
  self._launch_api: LaunchControllerApi | None = None
236
261
  self._launch_search_api: LaunchSearchControllerApi | None = None
262
+ self._integration_api: IntegrationControllerApi | None = None
237
263
  self._is_entered = False
238
264
 
239
265
  @classmethod
@@ -374,11 +400,13 @@ class AllureClient:
374
400
  self._custom_field_api = CustomFieldControllerApi(self._api_client)
375
401
  self._custom_field_project_api = CustomFieldProjectControllerApi(self._api_client)
376
402
  self._custom_field_project_v2_api = CustomFieldProjectControllerV2Api(self._api_client)
403
+ self._custom_field_value_api = CustomFieldValueControllerApi(self._api_client)
377
404
  self._custom_field_value_project_api = CustomFieldValueProjectControllerApi(self._api_client)
378
405
  self._test_layer_api = TestLayerControllerApi(self._api_client)
379
406
  self._test_layer_schema_api = TestLayerSchemaControllerApi(self._api_client)
380
407
  self._launch_api = LaunchControllerApi(self._api_client)
381
408
  self._launch_search_api = LaunchSearchControllerApi(self._api_client)
409
+ self._integration_api = IntegrationControllerApi(self._api_client)
382
410
 
383
411
  @property
384
412
  def api_client(self) -> ApiClient:
@@ -391,6 +419,21 @@ class AllureClient:
391
419
  raise RuntimeError("AllureClient must be used as an async context manager")
392
420
  return self._api_client
393
421
 
422
+ async def get_integrations(self) -> list[IntegrationDto]:
423
+ """Fetch all integrations."""
424
+ # Ensure we have a valid client
425
+ if self._integration_api is None:
426
+ raise RuntimeError("AllureClient must be used as an async context manager")
427
+
428
+ try:
429
+ # Fetch first page with reasonable size
430
+ page = await self._integration_api.get_integrations(page=0, size=100)
431
+ return page.content or []
432
+ except Exception:
433
+ # Log warning or re-raise depending on strictness.
434
+ # For now return empty list to act as fallback.
435
+ return []
436
+
394
437
  async def __aenter__(self) -> AllureClient:
395
438
  """Initialize the client session within an async context.
396
439
 
@@ -512,6 +555,11 @@ class AllureClient:
512
555
  self, attr_name: Literal["_custom_field_project_v2_api"], *, error_name: str | None = None
513
556
  ) -> CustomFieldProjectControllerV2Api: ...
514
557
 
558
+ @overload
559
+ async def _get_api(
560
+ self, attr_name: Literal["_custom_field_value_api"], *, error_name: str | None = None
561
+ ) -> CustomFieldValueControllerApi: ...
562
+
515
563
  @overload
516
564
  async def _get_api(
517
565
  self, attr_name: Literal["_custom_field_value_project_api"], *, error_name: str | None = None
@@ -831,6 +879,28 @@ class AllureClient:
831
879
  raise AllureValidationError("Unexpected launch list response from API") from e
832
880
  return FindAll29200Response(preview_data)
833
881
 
882
+ async def get_launch(self, launch_id: int) -> LaunchDto:
883
+ """Retrieve a specific launch by its ID.
884
+
885
+ Args:
886
+ launch_id: The unique ID of the launch.
887
+
888
+ Returns:
889
+ The launch data.
890
+
891
+ Raises:
892
+ AllureNotFoundError: If launch doesn't exist.
893
+ AllureValidationError: If input is invalid.
894
+ AllureAuthError: If unauthorized.
895
+ AllureAPIError: If the server returns an error.
896
+ """
897
+ api = await self._get_api("_launch_api", error_name="launch APIs")
898
+
899
+ if not isinstance(launch_id, int) or launch_id <= 0:
900
+ raise AllureValidationError("Launch ID must be a positive integer")
901
+
902
+ return await self._call_api(api.find_one23(id=launch_id, _request_timeout=self._timeout))
903
+
834
904
  async def search_launches_aql(
835
905
  self,
836
906
  project_id: int,
@@ -1088,6 +1158,165 @@ class AllureClient:
1088
1158
  with_expected_result=with_expected_result,
1089
1159
  )
1090
1160
 
1161
+ async def list_custom_field_values(
1162
+ self,
1163
+ project_id: int,
1164
+ custom_field_id: int,
1165
+ *,
1166
+ query: str | None = None,
1167
+ var_global: bool | None = None,
1168
+ test_case_search: str | None = None,
1169
+ page: int | None = None,
1170
+ size: int | None = None,
1171
+ sort: list[str] | None = None,
1172
+ ) -> PageCustomFieldValueWithTcCountDto:
1173
+ """List custom field values for a project field.
1174
+
1175
+ Args:
1176
+ project_id: Target project ID.
1177
+ custom_field_id: Target custom field ID (project-scoped).
1178
+ query: Optional search query.
1179
+ var_global: Optional global flag filter.
1180
+ test_case_search: Optional test case search filter.
1181
+ page: Zero-based page index.
1182
+ size: Page size.
1183
+ sort: Optional sort criteria.
1184
+
1185
+ Returns:
1186
+ Paginated custom field values with test case counts.
1187
+
1188
+ Raises:
1189
+ AllureNotFoundError: If project or custom field doesn't exist.
1190
+ AllureValidationError: If input data fails validation.
1191
+ AllureAuthError: If unauthorized.
1192
+ AllureAPIError: If the server returns an error.
1193
+ """
1194
+ api = await self._get_api("_custom_field_value_project_api")
1195
+
1196
+ if not isinstance(project_id, int) or project_id <= 0:
1197
+ raise AllureValidationError("Project ID must be a positive integer")
1198
+ if not isinstance(custom_field_id, int) or custom_field_id == 0:
1199
+ raise AllureValidationError("Custom Field ID must be a non-zero integer")
1200
+ if page is not None and (not isinstance(page, int) or page < 0):
1201
+ raise AllureValidationError("Page must be a non-negative integer")
1202
+ if size is not None and (not isinstance(size, int) or size <= 0 or size > 1000):
1203
+ raise AllureValidationError("Size must be between 1 and 1000")
1204
+
1205
+ return await self._call_api(
1206
+ api.find_all22(
1207
+ project_id=project_id,
1208
+ custom_field_id=custom_field_id,
1209
+ query=query,
1210
+ var_global=var_global,
1211
+ test_case_search=test_case_search,
1212
+ page=page,
1213
+ size=size,
1214
+ sort=sort,
1215
+ _request_timeout=self._timeout,
1216
+ )
1217
+ )
1218
+
1219
+ async def create_custom_field_value(
1220
+ self, project_id: int, data: CustomFieldValueProjectCreateDto
1221
+ ) -> CustomFieldValueWithCfDto:
1222
+ """Create a custom field value in a project.
1223
+
1224
+ Args:
1225
+ project_id: Target project ID.
1226
+ data: Custom field value payload.
1227
+
1228
+ Returns:
1229
+ The created custom field value DTO.
1230
+
1231
+ Raises:
1232
+ AllureNotFoundError: If project doesn't exist.
1233
+ AllureValidationError: If input data fails validation.
1234
+ AllureAuthError: If unauthorized.
1235
+ AllureAPIError: If the server returns an error.
1236
+ """
1237
+ api = await self._get_api("_custom_field_value_project_api")
1238
+
1239
+ if not isinstance(project_id, int) or project_id <= 0:
1240
+ raise AllureValidationError("Project ID must be a positive integer")
1241
+
1242
+ try:
1243
+ return await self._call_api(
1244
+ api.create26(
1245
+ project_id=project_id,
1246
+ custom_field_value_project_create_dto=data,
1247
+ _request_timeout=self._timeout,
1248
+ )
1249
+ )
1250
+ except AllureAPIError as exc:
1251
+ if exc.status_code == 409:
1252
+ raise AllureValidationError(
1253
+ "Duplicate custom field value name.",
1254
+ status_code=exc.status_code,
1255
+ response_body=exc.response_body,
1256
+ suggestions=["Use a unique custom field value name"],
1257
+ ) from exc
1258
+ raise
1259
+
1260
+ async def update_custom_field_value(
1261
+ self, project_id: int, cfv_id: int, data: CustomFieldValueProjectPatchDto
1262
+ ) -> None:
1263
+ """Update a custom field value in a project.
1264
+
1265
+ Args:
1266
+ project_id: Target project ID.
1267
+ cfv_id: Target custom field value ID.
1268
+ data: Patch payload for the custom field value.
1269
+
1270
+ Raises:
1271
+ AllureNotFoundError: If project or value doesn't exist.
1272
+ AllureValidationError: If input data fails validation.
1273
+ AllureAuthError: If unauthorized.
1274
+ AllureAPIError: If the server returns an error.
1275
+ """
1276
+ api = await self._get_api("_custom_field_value_project_api")
1277
+
1278
+ if not isinstance(project_id, int) or project_id <= 0:
1279
+ raise AllureValidationError("Project ID must be a positive integer")
1280
+ if not isinstance(cfv_id, int) or cfv_id <= 0:
1281
+ raise AllureValidationError("Custom Field Value ID must be a positive integer")
1282
+
1283
+ await self._call_api(
1284
+ api.patch23(
1285
+ project_id=project_id,
1286
+ cfv_id=cfv_id,
1287
+ custom_field_value_project_patch_dto=data,
1288
+ _request_timeout=self._timeout,
1289
+ )
1290
+ )
1291
+
1292
+ async def delete_custom_field_value(self, project_id: int, cfv_id: int) -> None:
1293
+ """Delete a custom field value in a project.
1294
+
1295
+ Args:
1296
+ project_id: Target project ID.
1297
+ cfv_id: Target custom field value ID.
1298
+
1299
+ Raises:
1300
+ AllureNotFoundError: If project or value doesn't exist.
1301
+ AllureValidationError: If input data fails validation.
1302
+ AllureAuthError: If unauthorized.
1303
+ AllureAPIError: If the server returns an error.
1304
+ """
1305
+ api = await self._get_api("_custom_field_value_project_api")
1306
+
1307
+ if not isinstance(project_id, int) or project_id <= 0:
1308
+ raise AllureValidationError("Project ID must be a positive integer")
1309
+ if not isinstance(cfv_id, int) or cfv_id <= 0:
1310
+ raise AllureValidationError("Custom Field Value ID must be a positive integer")
1311
+
1312
+ await self._call_api(
1313
+ api.delete47(
1314
+ project_id=project_id,
1315
+ id=cfv_id,
1316
+ _request_timeout=self._timeout,
1317
+ )
1318
+ )
1319
+
1091
1320
  async def get_custom_fields_with_values(self, project_id: int) -> list[CustomFieldProjectWithValuesDto]:
1092
1321
  """Fetch all custom fields and their allowed values for a project.
1093
1322
 
@@ -1197,14 +1426,14 @@ class AllureClient:
1197
1426
  AllureAPIError: If the API request fails.
1198
1427
  """
1199
1428
  scenario_api = await self._get_api("_scenario_api")
1200
- await self._call_api(
1201
- scenario_api.delete_by_id1(
1429
+ await self._call_api_raw(
1430
+ scenario_api.delete_by_id1_without_preload_content(
1202
1431
  id=step_id,
1203
1432
  _request_timeout=self._timeout,
1204
1433
  )
1205
1434
  )
1206
1435
 
1207
- async def get_test_case(self, test_case_id: int) -> TestCaseDto:
1436
+ async def get_test_case(self, test_case_id: int) -> TestCaseDtoWithCF:
1208
1437
  """Retrieve a specific test case by its ID.
1209
1438
 
1210
1439
  Args:
@@ -1237,6 +1466,8 @@ class AllureClient:
1237
1466
  )
1238
1467
  if overview.custom_fields:
1239
1468
  case.custom_fields = overview.custom_fields
1469
+ if overview.issues:
1470
+ case.issues = overview.issues
1240
1471
  except Exception as e:
1241
1472
  logger.warning(f"Failed to fetch overview for test case {test_case_id}: {e}")
1242
1473
 
@@ -1377,13 +1608,14 @@ class AllureClient:
1377
1608
  child_ids = step_def.get("children") or []
1378
1609
  child_steps = build_steps(child_ids) if child_ids else None
1379
1610
 
1380
- # Build BodyStepDtoWithSteps
1611
+ # Build StepWithExpected
1381
1612
  steps_list.append(
1382
1613
  SharedStepScenarioDtoStepsInner(
1383
- actual_instance=BodyStepDtoWithSteps.model_construct(
1614
+ actual_instance=StepWithExpected.model_construct(
1384
1615
  type="BodyStepDto",
1385
1616
  body=body,
1386
1617
  body_json=None, # Skip complex rich-text
1618
+ expected_result=step_def.get("expectedResult"),
1387
1619
  steps=child_steps,
1388
1620
  id=sid,
1389
1621
  )
@@ -1482,6 +1714,38 @@ class AllureClient:
1482
1714
 
1483
1715
  return await self._create_scenario_step_via_api(shared_step_scenario_api, step)
1484
1716
 
1717
+ async def patch_test_case_scenario_step(
1718
+ self,
1719
+ step_id: int,
1720
+ patch: ScenarioStepPatchDto,
1721
+ ) -> None:
1722
+ """Patch a specific scenario step within a test case."""
1723
+ scenario_api = await self._get_api("_scenario_api")
1724
+ await self._call_api_raw(
1725
+ scenario_api.patch_by_id_without_preload_content(
1726
+ id=step_id,
1727
+ scenario_step_patch_dto=patch,
1728
+ with_expected_result=False,
1729
+ _request_timeout=self._timeout,
1730
+ )
1731
+ )
1732
+
1733
+ async def patch_shared_step_scenario_step(
1734
+ self,
1735
+ step_id: int,
1736
+ patch: ScenarioStepPatchDto,
1737
+ ) -> None:
1738
+ """Patch a specific scenario step within a shared step."""
1739
+ shared_step_scenario_api = await self._get_api("_shared_step_scenario_api")
1740
+ await self._call_api_raw(
1741
+ shared_step_scenario_api.patch_by_id1_without_preload_content(
1742
+ id=step_id,
1743
+ scenario_step_patch_dto=patch,
1744
+ with_expected_result=False,
1745
+ _request_timeout=self._timeout,
1746
+ )
1747
+ )
1748
+
1485
1749
  async def upload_shared_step_attachment(
1486
1750
  self,
1487
1751
  shared_step_id: int,
src/client/exceptions.py CHANGED
@@ -42,6 +42,28 @@ class TestCaseNotFoundError(ResourceNotFoundError):
42
42
  )
43
43
 
44
44
 
45
+ class LaunchNotFoundError(ResourceNotFoundError):
46
+ """Resource not found for a specific launch."""
47
+
48
+ def __init__(
49
+ self,
50
+ launch_id: int,
51
+ status_code: int | None = None,
52
+ response_body: str | None = None,
53
+ ) -> None:
54
+ suggestions = [
55
+ "Verify the launch ID",
56
+ "Use list_launches to find valid IDs",
57
+ "Check access to the project containing this launch",
58
+ ]
59
+ super().__init__(
60
+ message=f"Launch ID {launch_id} not found",
61
+ status_code=status_code,
62
+ response_body=response_body,
63
+ suggestions=suggestions,
64
+ )
65
+
66
+
45
67
  class AllureAuthError(AuthenticationError):
46
68
  """Authentication failed (401/403)."""
47
69
 
@@ -57,5 +79,6 @@ __all__ = [
57
79
  "AllureNotFoundError",
58
80
  "AllureRateLimitError",
59
81
  "AllureValidationError",
82
+ "LaunchNotFoundError",
60
83
  "TestCaseNotFoundError",
61
84
  ]
@@ -107,6 +107,24 @@ Class | Method | HTTP request | Description
107
107
  *CustomFieldValueProjectControllerApi* | [**merge_custom_fields_to_existing_record**](src/client/generated/docs/CustomFieldValueProjectControllerApi.md#merge_custom_fields_to_existing_record) | **POST** /api/project/{projectId}/cfv/merge-to/{toCfvId} | Merge custom field values to existing record by id
108
108
  *CustomFieldValueProjectControllerApi* | [**merge_custom_fields_to_new_record**](src/client/generated/docs/CustomFieldValueProjectControllerApi.md#merge_custom_fields_to_new_record) | **POST** /api/project/{projectId}/cfv/merge | Merge custom field values to new record
109
109
  *CustomFieldValueProjectControllerApi* | [**patch23**](src/client/generated/docs/CustomFieldValueProjectControllerApi.md#patch23) | **PATCH** /api/project/{projectId}/cfv/{cfvId} | Patch specified custom field value, test results won&#39;t be affected
110
+ *IntegrationControllerApi* | [**create37**](src/client/generated/docs/IntegrationControllerApi.md#create37) | **POST** /api/integration |
111
+ *IntegrationControllerApi* | [**create_project_integration**](src/client/generated/docs/IntegrationControllerApi.md#create_project_integration) | **POST** /api/integration/project |
112
+ *IntegrationControllerApi* | [**delete_by_id3**](src/client/generated/docs/IntegrationControllerApi.md#delete_by_id3) | **DELETE** /api/integration/{id} |
113
+ *IntegrationControllerApi* | [**delete_project_integration**](src/client/generated/docs/IntegrationControllerApi.md#delete_project_integration) | **DELETE** /api/integration/{integrationId}/project/{projectId} |
114
+ *IntegrationControllerApi* | [**find_one_by_id**](src/client/generated/docs/IntegrationControllerApi.md#find_one_by_id) | **GET** /api/integration/{id} |
115
+ *IntegrationControllerApi* | [**find_project_integration_by_id**](src/client/generated/docs/IntegrationControllerApi.md#find_project_integration_by_id) | **GET** /api/integration/{integrationId}/project/{projectId} |
116
+ *IntegrationControllerApi* | [**get_available_integrations**](src/client/generated/docs/IntegrationControllerApi.md#get_available_integrations) | **GET** /api/integration/available |
117
+ *IntegrationControllerApi* | [**get_global_fields**](src/client/generated/docs/IntegrationControllerApi.md#get_global_fields) | **GET** /api/integration/globalfields |
118
+ *IntegrationControllerApi* | [**get_integration_projects**](src/client/generated/docs/IntegrationControllerApi.md#get_integration_projects) | **GET** /api/integration/{id}/project |
119
+ *IntegrationControllerApi* | [**get_integrations**](src/client/generated/docs/IntegrationControllerApi.md#get_integrations) | **GET** /api/integration |
120
+ *IntegrationControllerApi* | [**get_project_available_integrations**](src/client/generated/docs/IntegrationControllerApi.md#get_project_available_integrations) | **GET** /api/integration/project/{projectId}/available |
121
+ *IntegrationControllerApi* | [**get_project_integration_fields**](src/client/generated/docs/IntegrationControllerApi.md#get_project_integration_fields) | **GET** /api/integration/projectfields |
122
+ *IntegrationControllerApi* | [**get_project_integrations**](src/client/generated/docs/IntegrationControllerApi.md#get_project_integrations) | **GET** /api/integration/project/{projectId} |
123
+ *IntegrationControllerApi* | [**patch34**](src/client/generated/docs/IntegrationControllerApi.md#patch34) | **PATCH** /api/integration/{id} |
124
+ *IntegrationControllerApi* | [**patch_project_integration**](src/client/generated/docs/IntegrationControllerApi.md#patch_project_integration) | **PATCH** /api/integration/{integrationId}/project/{projectId} |
125
+ *IntegrationControllerApi* | [**suggest15**](src/client/generated/docs/IntegrationControllerApi.md#suggest15) | **GET** /api/integration/suggest | Suggest integrations
126
+ *IntegrationControllerApi* | [**validate1**](src/client/generated/docs/IntegrationControllerApi.md#validate1) | **POST** /api/integration/validate |
127
+ *IntegrationControllerApi* | [**validate2**](src/client/generated/docs/IntegrationControllerApi.md#validate2) | **POST** /api/integration/project/validate |
110
128
  *LaunchControllerApi* | [**add_test_cases**](src/client/generated/docs/LaunchControllerApi.md#add_test_cases) | **POST** /api/launch/{id}/testcase/add | Add test cases to launch
111
129
  *LaunchControllerApi* | [**add_test_plan**](src/client/generated/docs/LaunchControllerApi.md#add_test_plan) | **POST** /api/launch/{id}/testplan/add | Add test plan to launch
112
130
  *LaunchControllerApi* | [**apply_defect_matchers**](src/client/generated/docs/LaunchControllerApi.md#apply_defect_matchers) | **POST** /api/launch/{id}/defect/apply | Apply defect matchers to launch
@@ -24,6 +24,7 @@ __all__ = [
24
24
  "CustomFieldSchemaControllerApi",
25
25
  "CustomFieldValueControllerApi",
26
26
  "CustomFieldValueProjectControllerApi",
27
+ "IntegrationControllerApi",
27
28
  "LaunchControllerApi",
28
29
  "LaunchSearchControllerApi",
29
30
  "ProjectControllerApi",
@@ -742,6 +743,7 @@ from src.client.generated.api.custom_field_project_controller_v2_api import Cust
742
743
  from src.client.generated.api.custom_field_schema_controller_api import CustomFieldSchemaControllerApi as CustomFieldSchemaControllerApi
743
744
  from src.client.generated.api.custom_field_value_controller_api import CustomFieldValueControllerApi as CustomFieldValueControllerApi
744
745
  from src.client.generated.api.custom_field_value_project_controller_api import CustomFieldValueProjectControllerApi as CustomFieldValueProjectControllerApi
746
+ from src.client.generated.api.integration_controller_api import IntegrationControllerApi as IntegrationControllerApi
745
747
  from src.client.generated.api.launch_controller_api import LaunchControllerApi as LaunchControllerApi
746
748
  from src.client.generated.api.launch_search_controller_api import LaunchSearchControllerApi as LaunchSearchControllerApi
747
749
  from src.client.generated.api.project_controller_api import ProjectControllerApi as ProjectControllerApi
@@ -7,6 +7,7 @@ from src.client.generated.api.custom_field_project_controller_v2_api import Cust
7
7
  from src.client.generated.api.custom_field_schema_controller_api import CustomFieldSchemaControllerApi
8
8
  from src.client.generated.api.custom_field_value_controller_api import CustomFieldValueControllerApi
9
9
  from src.client.generated.api.custom_field_value_project_controller_api import CustomFieldValueProjectControllerApi
10
+ from src.client.generated.api.integration_controller_api import IntegrationControllerApi
10
11
  from src.client.generated.api.launch_controller_api import LaunchControllerApi
11
12
  from src.client.generated.api.launch_search_controller_api import LaunchSearchControllerApi
12
13
  from src.client.generated.api.project_controller_api import ProjectControllerApi