codemie-sdk-python 0.1.4__py3-none-any.whl → 0.1.6__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.

Potentially problematic release.


This version of codemie-sdk-python might be problematic. Click here for more details.

@@ -51,6 +51,11 @@ class CodeMieClient:
51
51
  self._token: Optional[str] = None
52
52
  self._api_domain = codemie_api_domain.rstrip("/")
53
53
  self._verify_ssl = verify_ssl
54
+ if not verify_ssl:
55
+ import requests
56
+ from urllib3.exceptions import InsecureRequestWarning
57
+
58
+ requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
54
59
 
55
60
  # Initialize token first
56
61
  self._token = self.auth.get_token()
@@ -11,6 +11,28 @@ from .common import User
11
11
  from .integration import Integration
12
12
 
13
13
 
14
+ class GitToolName(str, Enum):
15
+ """Enum for Git tool names."""
16
+
17
+ LIST_BRANCHES_IN_REPO = "list_branches_in_repo"
18
+ CREATE_BRANCH = "create_branch"
19
+ SET_ACTIVE_BRANCH = "set_active_branch"
20
+ CREATE_FILE = "create_file"
21
+ UPDATE_FILE = "update_file"
22
+ UPDATE_FILE_DIFF = "update_file_diff"
23
+ DELETE_FILE = "delete_file"
24
+ CREATE_PULL_REQUEST = "create_pull_request"
25
+ GET_PR_CHANGES = "get_pr_changes"
26
+ CREATE_PR_CHANGES_COMMENT = "create_pr_changes_comment"
27
+
28
+
29
+ class VcsToolName(str, Enum):
30
+ """Enum for VCS tool names."""
31
+
32
+ GITLAB = "gitlab"
33
+ GITHUB = "github"
34
+
35
+
14
36
  class ToolDetails(BaseModel):
15
37
  """Model for tool details."""
16
38
 
@@ -23,6 +45,13 @@ class ToolDetails(BaseModel):
23
45
  settings: Optional[Integration] = None
24
46
 
25
47
 
48
+ class Toolkit(str, Enum):
49
+ """Enum for toolkits."""
50
+
51
+ GIT = "Git"
52
+ VCS = "VCS"
53
+
54
+
26
55
  class ToolKitDetails(BaseModel):
27
56
  """Model for toolkit details."""
28
57
 
@@ -149,7 +178,7 @@ class AssistantChatRequest(BaseModel):
149
178
  conversation_id: Optional[str] = Field(
150
179
  default=str(uuid.uuid4()), description="Conversation identifier"
151
180
  )
152
- text: Optional[str] = Field(default=None, description="User's input error_message")
181
+ text: str = Field(description="User's input")
153
182
  content_raw: Optional[str] = Field(default="", description="Raw content input")
154
183
  file_name: Optional[str] = Field(default=None, description="Associated file name")
155
184
  llm_model: Optional[str] = Field(
@@ -166,6 +195,9 @@ class AssistantChatRequest(BaseModel):
166
195
  top_k: int = Field(default=10, description="Top K results to consider")
167
196
  system_prompt: str = Field(default="", description="Override system prompt")
168
197
  background_task: bool = Field(default=False, description="Run as background task")
198
+ metadata: Optional[dict[str, Any]] = Field(
199
+ default=None, description="Provide additional metadata"
200
+ )
169
201
 
170
202
 
171
203
  class BaseModelResponse(BaseModel):
@@ -1,7 +1,7 @@
1
1
  import re
2
2
  from datetime import datetime
3
3
  from enum import Enum
4
- from typing import Optional, List
4
+ from typing import Optional, List, Union
5
5
 
6
6
  from pydantic import BaseModel, Field, model_validator, ConfigDict, field_validator
7
7
 
@@ -20,6 +20,10 @@ class DataSourceType(str, Enum):
20
20
  JIRA = "knowledge_base_jira"
21
21
  FILE = "knowledge_base_file"
22
22
  GOOGLE = "llm_routing_google"
23
+ PROVIDER = "provider"
24
+ SUMMARY = "summary"
25
+ CHUNK_SUMMARY = "chunk-summary"
26
+ JSON = "knowledge_base_json"
23
27
 
24
28
 
25
29
  class DataSourceStatus(str, Enum):
@@ -37,7 +41,7 @@ class DataSourceProcessingInfo(BaseModel):
37
41
  total_size_kb: Optional[float] = None
38
42
  average_file_size_bytes: Optional[float] = None
39
43
  unique_extensions: Optional[List[str]] = None
40
- filtered_documents: Optional[int] = None
44
+ filtered_documents: Optional[Union[int, list]] = None
41
45
  processed_documents_count: Optional[int] = Field(None, alias="documents_count_key")
42
46
 
43
47
 
@@ -1,10 +1,10 @@
1
1
  """Models for assistant-related data structures."""
2
2
 
3
- from datetime import datetime
4
3
  from enum import Enum
5
4
  from typing import List, Optional, Any
5
+ from datetime import datetime
6
6
 
7
- from pydantic import BaseModel, Field, ConfigDict
7
+ from pydantic import BaseModel, Field, ConfigDict, field_serializer
8
8
 
9
9
 
10
10
  class CredentialTypes(str, Enum):
@@ -33,6 +33,8 @@ class CredentialTypes(str, Enum):
33
33
  ZEPHYR_SQUAD = "ZephyrSquad"
34
34
  SERVICE_NOW = "ServiceNow"
35
35
  DIAL = "DIAL"
36
+ A2A = "A2A"
37
+ MCP = "MCP"
36
38
 
37
39
 
38
40
  class IntegrationType(str, Enum):
@@ -66,3 +68,7 @@ class Integration(BaseModel):
66
68
  credential_type: CredentialTypes
67
69
  credential_values: List[CredentialValues]
68
70
  setting_type: IntegrationType = Field(default=IntegrationType.USER)
71
+
72
+ @field_serializer("date", "update_date")
73
+ def serialize_dt(self, dt: datetime, _info):
74
+ return dt.isoformat()
@@ -0,0 +1,51 @@
1
+ """Workflow execution state models."""
2
+
3
+ from datetime import datetime
4
+ from enum import Enum
5
+ from typing import Optional
6
+
7
+ from pydantic import BaseModel, ConfigDict
8
+
9
+
10
+ class WorkflowExecutionStatusEnum(str, Enum):
11
+ """Workflow execution state status."""
12
+
13
+ IN_PROGRESS = "In Progress"
14
+ NOT_STARTED = "Not Started"
15
+ INTERRUPTED = "Interrupted"
16
+ FAILED = "Failed"
17
+ SUCCEEDED = "Succeeded"
18
+ ABORTED = "Aborted"
19
+
20
+
21
+ class WorkflowExecutionStateThought(BaseModel):
22
+ """Model for workflow execution state thought."""
23
+
24
+ model_config = ConfigDict(populate_by_name=True)
25
+
26
+ id: str
27
+ text: str
28
+ created_at: datetime
29
+ parent_id: Optional[str] = None
30
+
31
+
32
+ class WorkflowExecutionState(BaseModel):
33
+ """Model for workflow execution state."""
34
+
35
+ model_config = ConfigDict(populate_by_name=True)
36
+
37
+ id: str
38
+ execution_id: str
39
+ name: str
40
+ task: Optional[str] = ""
41
+ status: WorkflowExecutionStatusEnum = WorkflowExecutionStatusEnum.NOT_STARTED
42
+ started_at: Optional[datetime] = None
43
+ completed_at: Optional[datetime] = None
44
+
45
+
46
+ class WorkflowExecutionStateOutput(BaseModel):
47
+ """Model for workflow execution state output."""
48
+
49
+ model_config = ConfigDict(populate_by_name=True)
50
+
51
+ output: Optional[str] = None
@@ -4,6 +4,7 @@ from typing import List, Optional
4
4
 
5
5
  from ..models.common import PaginationParams
6
6
  from ..models.workflow import WorkflowExecution
7
+ from .workflow_execution_state import WorkflowExecutionStateService
7
8
  from ..utils import ApiRequestHandler
8
9
 
9
10
 
@@ -71,6 +72,17 @@ class WorkflowExecutionService:
71
72
  WorkflowExecution,
72
73
  )
73
74
 
75
+ def states(self, execution_id: str) -> WorkflowExecutionStateService:
76
+ """Get states service for a specific workflow execution.
77
+
78
+ Args:
79
+ execution_id: ID of the execution to get states for
80
+
81
+ Returns:
82
+ WorkflowExecutionStateService: Service for managing states of this execution
83
+ """
84
+ return WorkflowExecutionStateService(self._api, self._workflow_id, execution_id)
85
+
74
86
  def delete_all(self) -> dict:
75
87
  """Delete all workflow executions."""
76
88
  return self._api.delete(f"/v1/workflows/{self._workflow_id}/executions", dict)
@@ -0,0 +1,61 @@
1
+ """Workflow execution state service implementation."""
2
+
3
+ from typing import List
4
+
5
+ from ..models.common import PaginationParams
6
+ from ..models.workflow_state import (
7
+ WorkflowExecutionState,
8
+ WorkflowExecutionStateOutput,
9
+ )
10
+ from ..utils import ApiRequestHandler
11
+
12
+
13
+ class WorkflowExecutionStateService:
14
+ """Service for managing workflow execution states."""
15
+
16
+ def __init__(self, api: ApiRequestHandler, workflow_id: str, execution_id: str):
17
+ """Initialize the workflow execution state service.
18
+
19
+ Args:
20
+ api: Request handler for API
21
+ workflow_id: ID of the workflow this service manages states for
22
+ execution_id: ID of the execution this service manages states for
23
+ """
24
+ self._api = api
25
+ self._workflow_id = workflow_id
26
+ self._execution_id = execution_id
27
+
28
+ def list(
29
+ self,
30
+ page: int = 0,
31
+ per_page: int = 10,
32
+ ) -> List[WorkflowExecutionState]:
33
+ """List states for the workflow execution with filtering and pagination support.
34
+
35
+ Args:
36
+ page: Page number (0-based). Must be >= 0. Defaults to 0.
37
+ per_page: Number of items per page. Must be > 0. Defaults to 10.
38
+
39
+ Returns:
40
+ List of WorkflowExecutionState containing state information.
41
+ """
42
+ params = PaginationParams(page=page, per_page=per_page).to_dict()
43
+ return self._api.get(
44
+ f"/v1/workflows/{self._workflow_id}/executions/{self._execution_id}/states",
45
+ List[WorkflowExecutionState],
46
+ params=params,
47
+ )
48
+
49
+ def get_output(self, state_id: str) -> WorkflowExecutionStateOutput:
50
+ """Get output for a specific execution state.
51
+
52
+ Args:
53
+ state_id: ID of the state to get output for
54
+
55
+ Returns:
56
+ WorkflowExecutionStateOutput containing the state output.
57
+ """
58
+ return self._api.get(
59
+ f"/v1/workflows/{self._workflow_id}/executions/{self._execution_id}/states/{state_id}/output",
60
+ WorkflowExecutionStateOutput,
61
+ )
codemie_sdk/utils/http.py CHANGED
@@ -48,10 +48,16 @@ class ApiRequestHandler:
48
48
 
49
49
  def _get_headers(self) -> dict:
50
50
  """Gets request headers with auth token."""
51
- return {
52
- "Authorization": f"Bearer {self._token}",
53
- "Content-Type": "application/json",
54
- }
51
+ headers = {"Content-Type": "application/json"}
52
+ if (
53
+ "0.0.0.0" in self._base_url
54
+ or "127.0.0.1" in self._base_url
55
+ or "localhost" in self._base_url
56
+ ):
57
+ headers["User-Id"] = "dev-codemie-user"
58
+ else:
59
+ headers["Authorization"] = f"Bearer {self._token}"
60
+ return headers
55
61
 
56
62
  def _parse_response(
57
63
  self,
@@ -0,0 +1,802 @@
1
+ Metadata-Version: 2.1
2
+ Name: codemie-sdk-python
3
+ Version: 0.1.6
4
+ Summary: CodeMie SDK for Python
5
+ Author: Vadym Vlasenko
6
+ Author-email: vadym_vlasenko@epam.com
7
+ Requires-Python: >=3.12,<4.0
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Requires-Dist: pydantic (>=2.11.1,<3.0.0)
11
+ Requires-Dist: requests (>=2.31.0,<3.0.0)
12
+ Description-Content-Type: text/markdown
13
+
14
+ # CodeMie Python SDK
15
+
16
+ Python SDK for CodeMie services. This SDK provides a comprehensive interface to interact with CodeMie services, including LLM (Large Language Models), assistants, workflows, and tools.
17
+
18
+ ## Table of Contents
19
+
20
+ - [Installation](#installation)
21
+ - [Usage](#usage)
22
+ - [Basic Usage](#basic-usage)
23
+ - [Service Details](#service-details)
24
+ - [LLM Service](#llm-service)
25
+ - [Assistant Service](#assistant-service)
26
+ - [Core Methods](#core-methods)
27
+ - [Advanced Features](#advanced-features)
28
+ - [Datasource Service](#datasource-service)
29
+ - [Supported Datasource Types](#supported-datasource-types)
30
+ - [Core Methods](#core-methods-1)
31
+ - [Datasource Status](#datasource-status)
32
+ - [Best Practices for Datasources](#best-practices-for-datasources)
33
+ - [Integration Service](#integration-service)
34
+ - [Integration Types](#integration-types)
35
+ - [Core Methods](#core-methods-2)
36
+ - [Best Practices for Integrations](#best-practices-for-integrations)
37
+ - [Workflow Service](#workflow-service)
38
+ - [Core Methods](#core-methods-3)
39
+ - [Workflow Execution](#workflow-execution)
40
+ - [Workflow Configuration](#workflow-configuration)
41
+ - [Best Practices](#best-practices)
42
+ - [Error Handling](#error-handling)
43
+ - [Workflow Status Monitoring](#workflow-status-monitoring)
44
+ - [Development](#development)
45
+ - [Setup](#setup)
46
+ - [Running Tests](#running-tests)
47
+ - [Building Package](#building-package)
48
+ - [Error Handling](#error-handling-1)
49
+ - [Authentication](#authentication)
50
+ - [Required Parameters](#required-parameters)
51
+ - [Usage Examples](#usage-examples)
52
+ - [Best Practices](#best-practices-1)
53
+ - [Support](#support)
54
+
55
+ ## Installation
56
+
57
+ ```sh
58
+ pip install codemie-sdk
59
+ ```
60
+
61
+ ## Usage
62
+
63
+ ### Basic usage
64
+
65
+ ```python
66
+ from codemie_sdk import CodeMieClient
67
+
68
+ # Initialize client with authentication parameters
69
+ client = CodeMieClient(
70
+ auth_server_url="https://keycloak.eks-core.aws.main.edp.projects.epam.com/auth",
71
+ auth_client_id="your-client-id",
72
+ auth_client_secret="your-client-secret",
73
+ auth_realm_name="your-realm",
74
+ codemie_api_domain="https://codemie.lab.epam.com/code-assistant-api"
75
+ )
76
+ ```
77
+
78
+ ## Service Details
79
+
80
+ ### LLM Service
81
+
82
+ The LLM service provides access to language models and embedding models:
83
+
84
+ - **list()**: Retrieves a list of available LLM models
85
+ ```python
86
+ llm_models = client.llm.list(token=client.token)
87
+ ```
88
+
89
+ - **list_embeddings()**: Retrieves a list of available embedding models
90
+ ```python
91
+ embedding_models = client.llm.list_embeddings(token=client.token)
92
+ ```
93
+
94
+ Each LLM model contains the following information:
95
+ - Model identifier
96
+ - Model capabilities
97
+ - Configuration parameters
98
+
99
+ Example usage:
100
+ ```python
101
+ # List available LLM models
102
+ llm_models = client.llm.list(token=client.token)
103
+
104
+ # List available embedding models
105
+ embedding_models = client.llm.list_embeddings(token=client.token)
106
+ ```
107
+
108
+ ### Assistant Service
109
+
110
+ The Assistant service allows you to manage and interact with CodeMie assistants:
111
+
112
+ #### Core Methods
113
+
114
+ 1. **List Assistants**
115
+ ```python
116
+ assistants = client.assistant.list(
117
+ minimal_response=True, # Return minimal assistant info
118
+ scope="visible_to_user", # or "created_by_user"
119
+ page=0,
120
+ per_page=12,
121
+ filters={"key": "value"} # Optional filters
122
+ )
123
+ ```
124
+
125
+ 2. **Get Assistant Details**
126
+ ```python
127
+ # By ID
128
+ assistant = client.assistant.get("assistant-id")
129
+
130
+ # By Slug
131
+ assistant = client.assistant.get_by_slug("assistant-slug")
132
+ ```
133
+
134
+ 3. **Create Assistant**
135
+ ```python
136
+ from codemie_sdk.models.assistant import AssistantCreateRequest
137
+
138
+ request = AssistantCreateRequest(
139
+ name="My Assistant",
140
+ description="Assistant description",
141
+ instructions="Assistant instructions",
142
+ tools=["tool1", "tool2"],
143
+ # Additional parameters as needed
144
+ )
145
+ new_assistant = client.assistant.create(request)
146
+ ```
147
+
148
+ 4. **Update Assistant**
149
+ ```python
150
+ from codemie_sdk.models.assistant import AssistantUpdateRequest
151
+
152
+ request = AssistantUpdateRequest(
153
+ name="Updated Name",
154
+ description="Updated description",
155
+ # Other fields to update
156
+ )
157
+ updated_assistant = client.assistant.update("assistant-id", request)
158
+ ```
159
+
160
+ 5. **Delete Assistant**
161
+ ```python
162
+ result = client.assistant.delete("assistant-id")
163
+ ```
164
+
165
+ #### Advanced Features
166
+
167
+ 6. **Chat with Assistant**
168
+ ```python
169
+ from codemie_sdk.models.assistant import AssistantChatRequest
170
+
171
+ chat_request = AssistantChatRequest(
172
+ text="Your message here",
173
+ stream=False, # Set to True for streaming response
174
+ # Additional parameters
175
+ )
176
+ response = client.assistant.chat("assistant-id", chat_request)
177
+ ```
178
+
179
+ 7. **Work with Prebuilt Assistants**
180
+ ```python
181
+ # List prebuilt assistants
182
+ prebuilt = client.assistant.get_prebuilt()
183
+
184
+ # Get specific prebuilt assistant
185
+ prebuilt_assistant = client.assistant.get_prebuilt_by_slug("assistant-slug")
186
+ ```
187
+
188
+ 8. **Get Available Tools**
189
+ ```python
190
+ tools = client.assistant.get_tools()
191
+ ```
192
+
193
+ ### Datasource Service
194
+
195
+ The Datasource service enables managing various types of data sources in CodeMie, including code repositories, Confluence spaces, Jira projects, files, and Google documents.
196
+
197
+ #### Supported Datasource Types
198
+
199
+ - `CODE`: Code repository datasources
200
+ - `CONFLUENCE`: Confluence knowledge base
201
+ - `JIRA`: Jira knowledge base
202
+ - `FILE`: File-based knowledge base
203
+ - `GOOGLE`: Google documents
204
+
205
+ #### Core Methods
206
+
207
+ 1. **Create Datasource**
208
+ ```python
209
+ from codemie_sdk.models.datasource import (
210
+ CodeDataSourceRequest,
211
+ ConfluenceDataSourceRequest,
212
+ JiraDataSourceRequest,
213
+ GoogleDataSourceRequest
214
+ )
215
+
216
+ # Create Code Datasource
217
+ code_request = CodeDataSourceRequest(
218
+ name="my_repo", # lowercase letters and underscores only
219
+ project_name="my_project",
220
+ description="My code repository",
221
+ link="https://github.com/user/repo",
222
+ branch="main",
223
+ index_type="code", # or "summary" or "chunk-summary"
224
+ files_filter="*.py", # optional
225
+ embeddings_model="model_name",
226
+ summarization_model="gpt-4", # optional
227
+ docs_generation=False # optional
228
+ )
229
+ result = client.datasource.create(code_request)
230
+
231
+ # Create Confluence Datasource
232
+ confluence_request = ConfluenceDataSourceRequest(
233
+ name="confluence_kb",
234
+ project_name="my_project",
235
+ description="Confluence space",
236
+ cql="space = 'MYSPACE'",
237
+ include_restricted_content=False,
238
+ include_archived_content=False,
239
+ include_attachments=True,
240
+ include_comments=True
241
+ )
242
+ result = client.datasource.create(confluence_request)
243
+
244
+ # Create Jira Datasource
245
+ jira_request = JiraDataSourceRequest(
246
+ name="jira_kb",
247
+ project_name="my_project",
248
+ description="Jira project",
249
+ jql="project = 'MYPROJECT'"
250
+ )
251
+ result = client.datasource.create(jira_request)
252
+
253
+ # Create Google Doc Datasource
254
+ google_request = GoogleDataSourceRequest(
255
+ name="google_doc",
256
+ project_name="my_project",
257
+ description="Google document",
258
+ google_doc="document_url"
259
+ )
260
+ result = client.datasource.create(google_request)
261
+ ```
262
+
263
+ 2. **Update Datasource**
264
+ ```python
265
+ from codemie_sdk.models.datasource import UpdateCodeDataSourceRequest
266
+
267
+ # Update Code Datasource
268
+ update_request = UpdateCodeDataSourceRequest(
269
+ name="my_repo",
270
+ project_name="my_project",
271
+ description="Updated description",
272
+ branch="develop",
273
+ full_reindex=True, # optional reindex parameters
274
+ skip_reindex=False,
275
+ resume_indexing=False
276
+ )
277
+ result = client.datasource.update("datasource_id", update_request)
278
+ ```
279
+
280
+ 3. **List Datasources**
281
+ ```python
282
+ # List all datasources with filtering and pagination
283
+ datasources = client.datasource.list(
284
+ page=0,
285
+ per_page=10,
286
+ sort_key="update_date", # or "date"
287
+ sort_order="desc", # or "asc"
288
+ datasource_types=["CODE", "CONFLUENCE"], # optional filter by type
289
+ projects=["project1", "project2"], # optional filter by projects
290
+ owner="John Doe", # optional filter by owner
291
+ status="COMPLETED" # optional filter by status
292
+ )
293
+ ```
294
+
295
+ 4. **Get Datasource Details**
296
+ ```python
297
+ # Get single datasource by ID
298
+ datasource = client.datasource.get("datasource_id")
299
+ ```
300
+
301
+ 5. **Delete Datasource**
302
+ ```python
303
+ # Delete datasource by ID
304
+ result = client.datasource.delete("datasource_id")
305
+ ```
306
+
307
+ #### Datasource Status
308
+
309
+ Datasources can have the following statuses:
310
+ - `COMPLETED`: Indexing completed successfully
311
+ - `FAILED`: Indexing failed
312
+ - `FETCHING`: Fetching data from source
313
+ - `IN_PROGRESS`: Processing/indexing in progress
314
+
315
+ #### Best Practices for Datasources
316
+
317
+ 1. **Naming Convention**:
318
+ - Use lowercase letters and underscores for datasource names
319
+ - Keep names descriptive but concise
320
+
321
+ 2. **Performance Optimization**:
322
+ - Use appropriate filters when listing datasources
323
+ - Consider pagination for large result sets
324
+ - Choose appropriate reindex options based on your needs
325
+
326
+ 3. **Error Handling**:
327
+ - Always check datasource status after creation/update
328
+ - Handle potential failures gracefully
329
+ - Monitor processing information for issues
330
+
331
+ 4. **Security**:
332
+ - Be careful with sensitive data in filters and queries
333
+ - Use proper access controls when sharing datasources
334
+ - Regularly review and clean up unused datasources
335
+
336
+ ### Integration Service
337
+
338
+ The Integration service manages both user and project-level integrations in CodeMie, allowing you to configure and manage various integration settings.
339
+
340
+ #### Integration Types
341
+
342
+ - `USER`: User-level integrations
343
+ - `PROJECT`: Project-level integrations
344
+
345
+ #### Core Methods
346
+
347
+ 1. **List Integrations**
348
+ ```python
349
+ from codemie_sdk.models.integration import IntegrationType
350
+
351
+ # List user integrations with pagination
352
+ user_integrations = client.integration.list(
353
+ setting_type=IntegrationType.USER,
354
+ page=0,
355
+ per_page=10,
356
+ filters={"some_filter": "value"} # optional
357
+ )
358
+
359
+ # List project integrations
360
+ project_integrations = client.integration.list(
361
+ setting_type=IntegrationType.PROJECT,
362
+ per_page=100
363
+ )
364
+ ```
365
+
366
+ 2. **Get Integration**
367
+ ```python
368
+ # Get integration by ID
369
+ integration = client.integration.get(
370
+ integration_id="integration_id",
371
+ setting_type=IntegrationType.USER
372
+ )
373
+
374
+ # Get integration by alias
375
+ integration = client.integration.get_by_alias(
376
+ alias="integration_alias",
377
+ setting_type=IntegrationType.PROJECT
378
+ )
379
+ ```
380
+
381
+ 3. **Create Integration**
382
+ ```python
383
+ from codemie_sdk.models.integration import Integration
384
+
385
+ # Create new integration
386
+ new_integration = Integration(
387
+ setting_type=IntegrationType.USER,
388
+ alias="my_integration",
389
+ # Add other required fields based on integration type
390
+ )
391
+ result = client.integration.create(new_integration)
392
+ ```
393
+
394
+ 4. **Update Integration**
395
+ ```python
396
+ # Update existing integration
397
+ updated_integration = Integration(
398
+ setting_type=IntegrationType.USER,
399
+ alias="updated_alias",
400
+ # Add other fields to update
401
+ )
402
+ result = client.integration.update("integration_id", updated_integration)
403
+ ```
404
+
405
+ 5. **Delete Integration**
406
+ ```python
407
+ # Delete integration
408
+ result = client.integration.delete(
409
+ setting_id="integration_id",
410
+ setting_type=IntegrationType.USER
411
+ )
412
+ ```
413
+
414
+ #### Best Practices for Integrations
415
+
416
+ 1. **Error Handling**:
417
+ - Handle `NotFoundError` when getting integrations by ID or alias
418
+ - Validate integration settings before creation/update
419
+ - Use appropriate setting type (USER/PROJECT) based on context
420
+
421
+ 2. **Performance**:
422
+ - Use pagination for listing integrations
423
+ - Cache frequently accessed integrations when appropriate
424
+ - Use filters to reduce result set size
425
+
426
+ 3. **Security**:
427
+ - Keep integration credentials secure
428
+ - Regularly review and update integration settings
429
+ - Use project-level integrations for team-wide settings
430
+ - Use user-level integrations for personal settings
431
+
432
+ ### Workflow Service
433
+
434
+ The Workflow service enables you to create, manage, and execute workflows in CodeMie. Workflows allow you to automate complex processes and integrate various CodeMie services.
435
+
436
+ #### Core Methods
437
+
438
+ 1. **Create Workflow**
439
+ ```python
440
+ from codemie_sdk.models.workflow import WorkflowCreateRequest
441
+
442
+ # Create new workflow
443
+ workflow_request = WorkflowCreateRequest(
444
+ name="My Workflow",
445
+ description="Workflow description",
446
+ project="project-id",
447
+ yaml_config="your-yaml-configuration",
448
+ mode="SEQUENTIAL", # Optional, defaults to SEQUENTIAL
449
+ shared=False, # Optional, defaults to False
450
+ icon_url="https://example.com/icon.png" # Optional
451
+ )
452
+ result = client.workflow.create_workflow(workflow_request)
453
+ ```
454
+
455
+ 2. **Update Workflow**
456
+ ```python
457
+ from codemie_sdk.models.workflow import WorkflowUpdateRequest
458
+
459
+ # Update existing workflow
460
+ update_request = WorkflowUpdateRequest(
461
+ name="Updated Workflow",
462
+ description="Updated description",
463
+ yaml_config="updated-yaml-config",
464
+ mode="PARALLEL",
465
+ shared=True
466
+ )
467
+ result = client.workflow.update("workflow-id", update_request)
468
+ ```
469
+
470
+ 3. **List Workflows**
471
+ ```python
472
+ # List workflows with pagination and filtering
473
+ workflows = client.workflow.list(
474
+ page=0,
475
+ per_page=10,
476
+ projects=["project1", "project2"] # Optional project filter
477
+ )
478
+ ```
479
+
480
+ 4. **Get Workflow Details**
481
+ ```python
482
+ # Get workflow by ID
483
+ workflow = client.workflow.get("workflow-id")
484
+
485
+ # Get prebuilt workflows
486
+ prebuilt_workflows = client.workflow.get_prebuilt()
487
+ ```
488
+
489
+ 5. **Delete Workflow**
490
+ ```python
491
+ result = client.workflow.delete("workflow-id")
492
+ ```
493
+
494
+ #### Workflow Execution
495
+
496
+ The SDK provides comprehensive workflow execution management through the WorkflowExecutionService:
497
+
498
+ 1. **Run Workflow**
499
+ ```python
500
+ # Simple workflow execution
501
+ execution = client.workflow.run("workflow-id", user_input="optional input")
502
+
503
+ # Get execution service for advanced operations
504
+ execution_service = client.workflow.executions("workflow-id")
505
+ ```
506
+
507
+ 2. **Manage Executions**
508
+ ```python
509
+ # List workflow executions
510
+ executions = execution_service.list(
511
+ page=0,
512
+ per_page=10
513
+ )
514
+
515
+ # Get execution details
516
+ execution = execution_service.get("execution-id")
517
+
518
+ # Abort running execution
519
+ result = execution_service.abort("execution-id")
520
+
521
+ # Resume interrupted execution
522
+ result = execution_service.resume("execution-id")
523
+
524
+ # Delete all executions
525
+ result = execution_service.delete_all()
526
+ ```
527
+
528
+ 3. **Work with Execution States**
529
+ ```python
530
+ # Get execution states
531
+ states = execution_service.states(execution_id).list()
532
+
533
+ # Get state output
534
+ state_output = execution_service.states(execution_id).get_output(state_id)
535
+
536
+ # Example of monitoring workflow with state verification
537
+ def verify_workflow_execution(execution_service, execution_id):
538
+ execution = execution_service.get(execution_id)
539
+
540
+ if execution.status == ExecutionStatus.SUCCEEDED:
541
+ # Get and verify states
542
+ states = execution_service.states(execution_id).list()
543
+
544
+ # States are ordered by completion date
545
+ if len(states) >= 2:
546
+ first_state = states[0]
547
+ second_state = states[1]
548
+ assert first_state.completed_at < second_state.completed_at
549
+
550
+ # Get state outputs
551
+ for state in states:
552
+ output = execution_service.states(execution_id).get_output(state.id)
553
+ print(f"State {state.id} output: {output.output}")
554
+
555
+ elif execution.status == ExecutionStatus.FAILED:
556
+ print(f"Workflow failed: {execution.error_message}")
557
+ ```
558
+
559
+ #### Workflow Configuration
560
+
561
+ Workflows support various configuration options:
562
+
563
+ 1. **Modes**:
564
+ - `SEQUENTIAL`: Tasks execute in sequence
565
+ - `PARALLEL`: Tasks can execute simultaneously
566
+
567
+ 2. **YAML Configuration**:
568
+ ```yaml
569
+ name: Example Workflow
570
+ description: Workflow description
571
+ tasks:
572
+ - name: task1
573
+ type: llm
574
+ config:
575
+ prompt: "Your prompt here"
576
+ model: "gpt-4"
577
+
578
+ - name: task2
579
+ type: tool
580
+ config:
581
+ tool_name: "your-tool"
582
+ parameters:
583
+ param1: "value1"
584
+ ```
585
+
586
+ #### Best Practices
587
+
588
+ 1. **Workflow Design**:
589
+ - Keep workflows modular and focused
590
+ - Use clear, descriptive names for workflows and tasks
591
+ - Document workflow purpose and requirements
592
+ - Test workflows thoroughly before deployment
593
+
594
+ 2. **Execution Management**:
595
+ - Monitor long-running workflows
596
+ - Implement proper error handling
597
+ - Use pagination for listing executions
598
+ - Clean up completed executions regularly
599
+
600
+ 3. **Performance Optimization**:
601
+ - Choose appropriate workflow mode (SEQUENTIAL/PARALLEL)
602
+ - Manage resource usage in parallel workflows
603
+ - Consider task dependencies and ordering
604
+ - Use efficient task configurations
605
+
606
+ 4. **Security**:
607
+ - Control workflow sharing carefully
608
+ - Validate user inputs
609
+ - Manage sensitive data appropriately
610
+ - Regular audit of workflow access
611
+
612
+ 5. **Maintenance**:
613
+ - Regular review of workflow configurations
614
+ - Update workflows when dependencies change
615
+ - Monitor workflow performance
616
+ - Archive or remove unused workflows
617
+
618
+ #### Error Handling
619
+
620
+ Implement proper error handling for workflow operations:
621
+
622
+ ```python
623
+ try:
624
+ workflow = client.workflow.get("workflow-id")
625
+ except ApiError as e:
626
+ if e.status_code == 404:
627
+ print("Workflow not found")
628
+ else:
629
+ print(f"API error: {e}")
630
+ except Exception as e:
631
+ print(f"Unexpected error: {e}")
632
+ ```
633
+
634
+ #### Workflow Status Monitoring
635
+
636
+ Monitor workflow execution status:
637
+
638
+ ```python
639
+ def monitor_execution(execution_service, execution_id):
640
+ while True:
641
+ execution = execution_service.get(execution_id)
642
+ status = execution.status
643
+
644
+ if status == "COMPLETED":
645
+ print("Workflow completed successfully")
646
+ break
647
+ elif status == "FAILED":
648
+ print(f"Workflow failed: {execution.error}")
649
+ break
650
+ elif status == "ABORTED":
651
+ print("Workflow was aborted")
652
+ break
653
+
654
+ time.sleep(5) # Poll every 5 seconds
655
+ ```
656
+
657
+ ## Error Handling
658
+
659
+ The SDK implements comprehensive error handling. All API calls may raise exceptions for:
660
+ - Authentication failures
661
+ - Network errors
662
+ - Invalid parameters
663
+ - Server-side errors
664
+
665
+ It's recommended to implement try-catch blocks around SDK operations to handle potential exceptions gracefully.
666
+
667
+ ## Authentication
668
+
669
+ The SDK supports two authentication methods through Keycloak:
670
+
671
+ 1. Username/Password Authentication
672
+ 2. Client Credentials Authentication
673
+
674
+ ### Required Parameters
675
+
676
+ You must provide either:
677
+
678
+ - Username/Password credentials:
679
+ ```python
680
+ {
681
+ "username": "your-username",
682
+ "password": "your-password",
683
+ "auth_client_id": "client-id", # Optional, defaults to "codemie-sdk"
684
+ "auth_realm_name": "realm-name",
685
+ "auth_server_url": "keycloak-url",
686
+ "verify_ssl": True # Optional, defaults to True
687
+ }
688
+ ```
689
+
690
+ OR
691
+
692
+ - Client Credentials:
693
+ ```python
694
+ {
695
+ "auth_client_id": "your-client-id",
696
+ "auth_client_secret": "your-client-secret",
697
+ "auth_realm_name": "realm-name",
698
+ "auth_server_url": "keycloak-url",
699
+ "verify_ssl": True # Optional, defaults to True
700
+ }
701
+ ```
702
+
703
+ ### Usage Examples
704
+
705
+ 1. Username/Password Authentication:
706
+ ```python
707
+ from codemie_sdk import CodeMieClient
708
+
709
+ client = CodeMieClient(
710
+ codemie_api_domain="https://api.domain.com",
711
+ username="your-username",
712
+ password="your-password",
713
+ auth_client_id="your-client-id", # Optional
714
+ auth_realm_name="your-realm",
715
+ auth_server_url="https://keycloak.domain.com/auth",
716
+ verify_ssl=True # Optional
717
+ )
718
+ ```
719
+
720
+ 2. Client Credentials Authentication:
721
+ ```python
722
+ from codemie_sdk.auth import KeycloakCredentials
723
+
724
+ credentials = KeycloakCredentials(
725
+ server_url="https://keycloak.domain.com/auth",
726
+ realm_name="your-realm",
727
+ client_id="your-client-id",
728
+ client_secret="your-client-secret",
729
+ verify_ssl=True # Optional
730
+ )
731
+
732
+ client = CodeMieClient(
733
+ codemie_api_domain="https://api.domain.com",
734
+ credentials=credentials
735
+ )
736
+ ```
737
+
738
+ ## Support
739
+ For providing credentials please contact AI/Run CodeMie Team: Vadym_Vlasenko@epam.com or Nikita_Levyankov@epam.com
740
+
741
+ ## Running tests
742
+
743
+ For running tests on custom environment you should create .env file in the root directory
744
+
745
+ ``` properties
746
+
747
+ AUTH_SERVER_URL=https://keycloak.eks-core.aws.main.edp.projects.epam.com/auth
748
+ AUTH_CLIENT_ID=codemie-preview
749
+ AUTH_CLIENT_SECRET=<your_secret>
750
+ AUTH_REALM_NAME=codemie-prod
751
+ CODEMIE_API_DOMAIN=https://codemie-preview.lab.epam.com/code-assistant-api
752
+ VERIFY_SSL=False
753
+
754
+ USERNAME=<username>
755
+ PASSWORD=<password>
756
+
757
+ PROJECT_NAME=automation-tests-project
758
+
759
+ DEFAULT_TIMEOUT=60
760
+
761
+ GITLAB_URL=https://gitbud.epam.com
762
+ GITLAB_TOKEN=<gitlab_token>
763
+ GITLAB_PROJECT=https://gitbud.epam.com/epm-cdme/autotests/codemie-test-project
764
+ GITLAB_PROJECT_ID=<project_id>
765
+
766
+ GITHUB_URL=https://github.com
767
+ GITHUB_TOKEN=<github_token>
768
+ GITHUB_PROJECT=https://github.com/wild47/final_task
769
+
770
+ JIRA_URL=https://jiraeu.epam.com
771
+ JIRA_TOKEN=<jira_token>
772
+ JQL="project = 'EPMCDME' and issuetype = 'Epic' and status = 'Closed'"
773
+
774
+ CONFLUENCE_URL=https://kb.epam.com
775
+ CONFLUENCE_TOKEN=<konfluence_token>
776
+ CQL="space = EPMCDME and type = page and title = 'AQA Backlog Estimation'"
777
+ ```
778
+
779
+ Run all tests
780
+
781
+ ```shell
782
+ pytest -n auto --reruns 1
783
+ ```
784
+
785
+ Run e2e tests
786
+
787
+ ```shell
788
+ pytest -n auto -m e2e --reruns 1
789
+ ```
790
+
791
+ Run tests for e2e tests for specific integration/tool.
792
+ Available marks:
793
+ - jira_kb
794
+ - confluence_kb
795
+ - code_kb
796
+ - gitlab
797
+ - github
798
+ - git
799
+
800
+ ```shell
801
+ pytest -n auto -m "jira_kb or github" --reruns 1
802
+ ```
@@ -2,16 +2,17 @@ codemie_sdk/__init__.py,sha256=xfhrTFdvRmLSsrdQksX5GhnoQEj6tvkeytkrbB20Jj8,567
2
2
  codemie_sdk/auth/__init__.py,sha256=IksEj223xEZtJ-cQ0AT9L0Bs9psIJ8QNzDXrPTUQ3xQ,126
3
3
  codemie_sdk/auth/credentials.py,sha256=u2eLNsD8fELTgreQghVb0g0kk82zchUkux0M5lzq-u8,4320
4
4
  codemie_sdk/client/__init__.py,sha256=yf6C39MmrJ6gK9ZHMhBeynKwUUYVSUTQbKxU8-4qpKg,101
5
- codemie_sdk/client/client.py,sha256=aU4yr_Un4gX7SLXZ7rQiO_ObxE2__RyR8OdlxeKLRvc,4172
5
+ codemie_sdk/client/client.py,sha256=dVcWqd-ruWd8GOZ3_33C3LnHgUyyxIoCKxKYPYbBPq8,4373
6
6
  codemie_sdk/exceptions.py,sha256=XoVPyognx-JmyVxLHkZPAcX1CMi1OoT1diBFJLU54so,1183
7
- codemie_sdk/models/assistant.py,sha256=hx3R1H7UPqRvmBFKL7PDwHdVcX_CbjUsju55tjVRVEo,5538
7
+ codemie_sdk/models/assistant.py,sha256=5VT5DOUPsEjVTLEPQoxFw5yna0BDoJBq0D8daVIp7l4,6304
8
8
  codemie_sdk/models/common.py,sha256=V4sJCzwFTF8BPlrd2OKI44Em5HmPmn2Nm8fQNsnBZ_Q,1128
9
- codemie_sdk/models/datasource.py,sha256=Kjde8pXi4pm6x37g-c838C3yDg4tnTJHNvITA3rvmUk,9898
10
- codemie_sdk/models/integration.py,sha256=lhY_5Dxm0MDxp9vxL0H0HaM-ytNNoyBSOoEYTw4a-rU,1589
9
+ codemie_sdk/models/datasource.py,sha256=Iun6O76o4m-_jbyyumMndpyr4OiN0lwqKb8u5AOTHdM,10037
10
+ codemie_sdk/models/integration.py,sha256=F1YBdCK1w5W_jKK8prEsg7A00NghkEBvJgkkr8KpC6w,1764
11
11
  codemie_sdk/models/llm.py,sha256=ppb9-1dx1UFhRuJpSR3ij7H6Pfhe9nO4C4BEOIbToy4,1192
12
12
  codemie_sdk/models/task.py,sha256=J4ZFRY3s8qBGrqB5NLQF0rMbInLh4s7OEZ0ZfmnW0Ho,1476
13
13
  codemie_sdk/models/user.py,sha256=Q0rjimZh-IbeaPfq6b6fk6ZaCtwLqWHEIlU863suCS4,1777
14
14
  codemie_sdk/models/workflow.py,sha256=CyK-kBnOck2KiRX3gmWF_mcGtqxsGXH3FS3jwYbpz_A,2327
15
+ codemie_sdk/models/workflow_state.py,sha256=CMYFQZ7sy4QxmnWmc83TFfqP7TG_3rW5MdH5fxsS9kY,1251
15
16
  codemie_sdk/services/assistant.py,sha256=-U5YpqOyKlVplSRPrnDItG8TUpg9qqhO6-F7c7Rz2xU,5110
16
17
  codemie_sdk/services/datasource.py,sha256=hYH__M5LD33dfh7CCS7HYmEn8izsGkO0nfVa-dpoj6w,5118
17
18
  codemie_sdk/services/integration.py,sha256=vJnSkXk2C2l0ahX2SUsuA7fKhY2hTuAByynx5Lgh7Ls,4864
@@ -19,10 +20,10 @@ codemie_sdk/services/llm.py,sha256=0-e4_7RvLHs2giCyoQ5U4KDTh6p5VXgPKNxnDP9ZDFU,1
19
20
  codemie_sdk/services/task.py,sha256=3e9t8_LMkR4xfeMBwMCo7ZF87PxPS-ZbzDg85ilda2M,1031
20
21
  codemie_sdk/services/user.py,sha256=7B-Qw451qKPD5Io6qLda-kbFDaPRQ3TamJamiGwCQu4,1013
21
22
  codemie_sdk/services/workflow.py,sha256=aOV13WrFAqMXOPd2jVHbEhg3fpezk4XWo382D5aWtro,4833
22
- codemie_sdk/services/workflow_execution.py,sha256=Ud-cYC_a2yb3FErfwWjM7hBIHzs2QoYQ-kX-o7K1cms,3152
23
+ codemie_sdk/services/workflow_execution.py,sha256=aGoT3rdTmh5-doAsrmBBjLEuOfvL5aqeo3g9th1_aAw,3647
24
+ codemie_sdk/services/workflow_execution_state.py,sha256=tXoaa8yT09xgYEUNiHhVULe76TwGwVgZupMIUyyLxdo,2070
23
25
  codemie_sdk/utils/__init__.py,sha256=BXAJJfAzO89-kMYvWWo9wSNhSbGgF3vB1In9sePFhMM,109
24
- codemie_sdk/utils/http.py,sha256=d2GRkd-OBrrrURfVLeD7SUGFsyB4k1anYz5LXX3o4H8,7525
25
- codemie_sdk_python-0.1.4.dist-info/LICENSE,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
26
- codemie_sdk_python-0.1.4.dist-info/METADATA,sha256=6r74NCBL8fKOBHzSeC6xARrOwqWd-VvfkzjvYaUJung,2633
27
- codemie_sdk_python-0.1.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
28
- codemie_sdk_python-0.1.4.dist-info/RECORD,,
26
+ codemie_sdk/utils/http.py,sha256=JfyX4gP-grQUI795QL0DJ72aBkiqNd1fs31fUqtSnYE,7757
27
+ codemie_sdk_python-0.1.6.dist-info/METADATA,sha256=bFS58qIKO7ZXcvu_L3QilTaE9tEV8hh8gQt4x-sqT6I,21439
28
+ codemie_sdk_python-0.1.6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
29
+ codemie_sdk_python-0.1.6.dist-info/RECORD,,
@@ -1,19 +0,0 @@
1
- Copyright (c) 2018 The Python Packaging Authority
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy
4
- of this software and associated documentation files (the "Software"), to deal
5
- in the Software without restriction, including without limitation the rights
6
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- copies of the Software, and to permit persons to whom the Software is
8
- furnished to do so, subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in all
11
- copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
- SOFTWARE.
@@ -1,120 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: codemie-sdk-python
3
- Version: 0.1.4
4
- Summary: CodeMie SDK for Python
5
- Author: Vadym Vlasenko
6
- Author-email: vadym_vlasenko@epam.com
7
- Requires-Python: >=3.12,<4.0
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.12
10
- Requires-Dist: pydantic (>=2.6.1,<3.0.0)
11
- Requires-Dist: pytest-cov (>=6.0.0,<7.0.0)
12
- Requires-Dist: requests (>=2.31.0,<3.0.0)
13
- Requires-Dist: ruff (>=0.11.0,<0.12.0)
14
- Description-Content-Type: text/markdown
15
-
16
- # CodeMie Python SDK
17
-
18
- Python SDK for CodeMie services
19
-
20
-
21
- ## Installation
22
-
23
- ```sh
24
- pip install codemie-sdk
25
- ```
26
-
27
- ## Usage
28
-
29
- ### Basic usage
30
-
31
- ```python
32
- from codemie_sdk import CodeMieClient
33
-
34
- # Initialize client with authentication parameters
35
- client = CodeMieClient(
36
- auth_server_url="https://keycloak.example.com",
37
- auth_client_id="your-client-id",
38
- auth_client_secret="your-client-secret",
39
- auth_realm_name="your-realm",
40
- codemie_api_domain="https://codemie-preview.lab.epam.com/code-assistant-api"
41
- )
42
-
43
- # Create a new workflow
44
- workflow = client.workflow.create('project-id', 'workflow-name', {'param': 'value'}, token=client.token)
45
-
46
- # Execute tool
47
- tool_result = client.tool.execute(
48
- tool_name='my-tool',
49
- project='project-id',
50
- tool_args={'param': 'value'},
51
- token=client.token
52
- )
53
- ```
54
-
55
- ### Tool Operations
56
-
57
- ```python
58
- # List available tools
59
- tools = client.tool.list(token=client.token)
60
-
61
- # Get tool schema
62
- schema = client.tool.schema('tool-name', token=client.token)
63
-
64
- # Execute tool with optional parameters
65
- result = client.tool.execute(
66
- tool_name='my-tool',
67
- project='project-id',
68
- tool_args={'param': 'value'},
69
- token=client.token,
70
- llm_model='gpt-4', # optional
71
- tool_attributes={'attr': 'value'}, # optional
72
- tool_creds={'cred': 'secret'}, # optional
73
- datasource_id='ds-123', # optional
74
- params={'retry_count': 3} # optional
75
- )
76
- ```
77
-
78
- ### Workflow Operations
79
-
80
- ```python
81
- # Create workflow
82
- workflow = client.workflow.create('project-id', 'workflow-name', {'param': 'value'}, token=client.token)
83
-
84
- # Get workflow status
85
- status = client.workflow.status('workflow-id', token=client.token)
86
-
87
- # List workflows
88
- workflows = client.workflow.list('project-id', token=client.token)
89
-
90
- # Get workflow result
91
- result = client.workflow.result('workflow-id', token=client.token)
92
- ```
93
-
94
- ## Development
95
-
96
- ### Setup
97
-
98
- 1. Create and activate virtual environment:
99
- ```sh
100
- python -m venv venv
101
- source venv/bin/activate # Linux/MacOS
102
- venv\Scripts\activate # Windows
103
- ```
104
-
105
- 2. Install dependencies:
106
- ```sh
107
- pip install -r requirements.txt
108
- ```
109
-
110
- ### Running Tests
111
-
112
- ```sh
113
- make test
114
- ```
115
-
116
- ### Building Package
117
-
118
- ```sh
119
- make build
120
- ```