wexa-sdk 0.1.0__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.
Potentially problematic release.
This version of wexa-sdk might be problematic. Click here for more details.
- wexa_sdk-0.1.0/PKG-INFO +23 -0
- wexa_sdk-0.1.0/README.md +7 -0
- wexa_sdk-0.1.0/pyproject.toml +29 -0
- wexa_sdk-0.1.0/setup.cfg +4 -0
- wexa_sdk-0.1.0/wexa_sdk/__init__.py +37 -0
- wexa_sdk-0.1.0/wexa_sdk/agentflows.py +37 -0
- wexa_sdk-0.1.0/wexa_sdk/analytics.py +12 -0
- wexa_sdk-0.1.0/wexa_sdk/connectors/__init__.py +1 -0
- wexa_sdk-0.1.0/wexa_sdk/connectors/core.py +24 -0
- wexa_sdk-0.1.0/wexa_sdk/connectors/google_drive.py +22 -0
- wexa_sdk-0.1.0/wexa_sdk/connectors_mgmt.py +47 -0
- wexa_sdk-0.1.0/wexa_sdk/executions.py +57 -0
- wexa_sdk-0.1.0/wexa_sdk/files.py +23 -0
- wexa_sdk-0.1.0/wexa_sdk/inbox.py +41 -0
- wexa_sdk-0.1.0/wexa_sdk/marketplace.py +31 -0
- wexa_sdk-0.1.0/wexa_sdk/models/__init__.py +1 -0
- wexa_sdk-0.1.0/wexa_sdk/project_members.py +16 -0
- wexa_sdk-0.1.0/wexa_sdk/projects.py +33 -0
- wexa_sdk-0.1.0/wexa_sdk/settings.py +11 -0
- wexa_sdk-0.1.0/wexa_sdk/skills.py +35 -0
- wexa_sdk-0.1.0/wexa_sdk/tables.py +59 -0
- wexa_sdk-0.1.0/wexa_sdk/tasks.py +36 -0
- wexa_sdk-0.1.0/wexa_sdk.egg-info/PKG-INFO +23 -0
- wexa_sdk-0.1.0/wexa_sdk.egg-info/SOURCES.txt +25 -0
- wexa_sdk-0.1.0/wexa_sdk.egg-info/dependency_links.txt +1 -0
- wexa_sdk-0.1.0/wexa_sdk.egg-info/requires.txt +2 -0
- wexa_sdk-0.1.0/wexa_sdk.egg-info/top_level.txt +1 -0
wexa_sdk-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wexa-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official Wexa Python SDK
|
|
5
|
+
Author: Wexa
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/wexa-ai/wexa-sdk
|
|
8
|
+
Keywords: wexa,sdk,api
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: httpx>=0.27
|
|
15
|
+
Requires-Dist: pydantic>=2.6
|
|
16
|
+
|
|
17
|
+
# wexa-sdk (Python)
|
|
18
|
+
|
|
19
|
+
Python SDK for Wexa API.
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from wexa_sdk import WexaClient
|
|
23
|
+
```
|
wexa_sdk-0.1.0/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "wexa-sdk"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Official Wexa Python SDK"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "Apache-2.0" }
|
|
12
|
+
keywords = ["wexa", "sdk", "api"]
|
|
13
|
+
authors = [{ name = "Wexa" }]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"License :: OSI Approved :: Apache Software License",
|
|
17
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
18
|
+
]
|
|
19
|
+
dependencies = [
|
|
20
|
+
"httpx>=0.27",
|
|
21
|
+
"pydantic>=2.6",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
Homepage = "https://github.com/wexa-ai/wexa-sdk"
|
|
26
|
+
|
|
27
|
+
[tool.setuptools]
|
|
28
|
+
packages = ["wexa_sdk", "wexa_sdk.connectors", "wexa_sdk.models"]
|
|
29
|
+
include-package-data = true
|
wexa_sdk-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from .core.http import HttpClient
|
|
2
|
+
from .agentflows import AgentFlows
|
|
3
|
+
from .executions import Executions
|
|
4
|
+
from .tables import Tables
|
|
5
|
+
from .connectors.core import Connectors
|
|
6
|
+
from .projects import Projects
|
|
7
|
+
from .skills import Skills
|
|
8
|
+
from .tasks import Tasks
|
|
9
|
+
from .inbox import Inbox
|
|
10
|
+
from .settings import Settings
|
|
11
|
+
from .marketplace import Marketplace
|
|
12
|
+
from .analytics import Analytics
|
|
13
|
+
from .project_members import ProjectMembers
|
|
14
|
+
from .connectors_mgmt import ConnectorsMgmt
|
|
15
|
+
from .files import Files
|
|
16
|
+
|
|
17
|
+
class WexaClient:
|
|
18
|
+
def __init__(self, base_url: str, api_key: str, user_agent: str | None = None, timeout: dict | None = None, retries: dict | None = None, polling: dict | None = None):
|
|
19
|
+
self.http = HttpClient(base_url=base_url, api_key=api_key, user_agent=user_agent, timeout=timeout, retries=retries)
|
|
20
|
+
self.agentflows = AgentFlows(self.http)
|
|
21
|
+
self.executions = Executions(self.http, polling or {})
|
|
22
|
+
self.tables = Tables(self.http)
|
|
23
|
+
self.connectors = Connectors(self.http)
|
|
24
|
+
self.projects = Projects(self.http)
|
|
25
|
+
self.skills = Skills(self.http)
|
|
26
|
+
self.tasks = Tasks(self.http)
|
|
27
|
+
self.inbox = Inbox(self.http)
|
|
28
|
+
self.settings = Settings(self.http)
|
|
29
|
+
self.marketplace = Marketplace(self.http)
|
|
30
|
+
self.analytics = Analytics(self.http)
|
|
31
|
+
self.project_members = ProjectMembers(self.http)
|
|
32
|
+
self.connectors_mgmt = ConnectorsMgmt(self.http)
|
|
33
|
+
self.files = Files(self.http)
|
|
34
|
+
|
|
35
|
+
def _action(self, *args, **kwargs):
|
|
36
|
+
# Kept for backward compatibility; delegate to connectors.action
|
|
37
|
+
return self.connectors.action(*args, **kwargs)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from .core.http import HttpClient
|
|
2
|
+
|
|
3
|
+
class AgentFlows:
|
|
4
|
+
def __init__(self, http: HttpClient):
|
|
5
|
+
self.http = http
|
|
6
|
+
|
|
7
|
+
def list(
|
|
8
|
+
self,
|
|
9
|
+
project_id: str | None = None,
|
|
10
|
+
projectID: str | None = None,
|
|
11
|
+
skip: int | None = None,
|
|
12
|
+
limit: int | None = None,
|
|
13
|
+
):
|
|
14
|
+
# API expects 'projectID' (capital D); accept both and normalize
|
|
15
|
+
pid = projectID or project_id
|
|
16
|
+
params: dict | None = None
|
|
17
|
+
if pid is not None or skip is not None or limit is not None:
|
|
18
|
+
params = {}
|
|
19
|
+
if pid is not None:
|
|
20
|
+
params["projectID"] = pid
|
|
21
|
+
if skip is not None:
|
|
22
|
+
params["skip"] = skip
|
|
23
|
+
if limit is not None:
|
|
24
|
+
params["limit"] = limit
|
|
25
|
+
return self.http.request("GET", "/agentflows", params=params)
|
|
26
|
+
|
|
27
|
+
def get(self, id: str):
|
|
28
|
+
return self.http.request("GET", f"/agentflow/{id}")
|
|
29
|
+
|
|
30
|
+
def create(self, body: dict):
|
|
31
|
+
return self.http.request("POST", "/agentflow/", json=body)
|
|
32
|
+
|
|
33
|
+
def update(self, id: str, body: dict):
|
|
34
|
+
return self.http.request("PUT", f"/agentflow/{id}", json=body)
|
|
35
|
+
|
|
36
|
+
def delete(self, project_id: str, id: str):
|
|
37
|
+
return self.http.request("DELETE", f"/agentflow/{project_id}/{id}")
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from .core.http import HttpClient
|
|
5
|
+
|
|
6
|
+
class Analytics:
|
|
7
|
+
def __init__(self, http: HttpClient):
|
|
8
|
+
self.http = http
|
|
9
|
+
|
|
10
|
+
# GET /analytics?projectID=...
|
|
11
|
+
def get(self, project_id: str) -> Any:
|
|
12
|
+
return self.http.request("GET", "/analytics", params={"projectID": project_id})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .google_drive import GoogleDrive # re-export
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any, Optional
|
|
3
|
+
|
|
4
|
+
from ..core.http import HttpClient
|
|
5
|
+
from .google_drive import GoogleDrive
|
|
6
|
+
|
|
7
|
+
class Connectors:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
self.google_drive = GoogleDrive(http)
|
|
11
|
+
|
|
12
|
+
# POST /actions/{CATEGORY}/{ACTION}/{connector_id?}
|
|
13
|
+
def action(self, category: str, action: str, connector_id: Optional[str] = None, *, body: Optional[dict] = None, projectID: Optional[str] = None) -> Any:
|
|
14
|
+
path = f"/actions/{category}/{action}/{connector_id}" if connector_id else f"/actions/{category}/{action}"
|
|
15
|
+
params = {"projectID": projectID} if projectID else None
|
|
16
|
+
return self.http.request("POST", path, params=params, json=body)
|
|
17
|
+
|
|
18
|
+
# POST /actions/{CATEGORY}/config?projectID=...
|
|
19
|
+
def set_config(self, category: str, project_id: str, body: dict) -> Any:
|
|
20
|
+
return self.http.request("POST", f"/actions/{category}/config", params={"projectID": project_id}, json=body)
|
|
21
|
+
|
|
22
|
+
# GET /actions/{CATEGORY}/config/{projectID}
|
|
23
|
+
def get_config(self, category: str, project_id: str) -> Any:
|
|
24
|
+
return self.http.request("GET", f"/actions/{category}/config/{project_id}")
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any, Dict, Optional
|
|
3
|
+
|
|
4
|
+
from ..core.http import HttpClient
|
|
5
|
+
|
|
6
|
+
class GoogleDrive:
|
|
7
|
+
def __init__(self, http: HttpClient):
|
|
8
|
+
self.http = http
|
|
9
|
+
|
|
10
|
+
def list_files(self, connector_id: str, *, folder_id: str, page_size: Optional[int] = None, page_token: Optional[str] = None, fetch_all: Optional[bool] = None):
|
|
11
|
+
body: Dict[str, Any] = {"folder_id": folder_id}
|
|
12
|
+
if page_size is not None:
|
|
13
|
+
body["page_size"] = page_size
|
|
14
|
+
if page_token is not None:
|
|
15
|
+
body["page_token"] = page_token
|
|
16
|
+
if fetch_all is not None:
|
|
17
|
+
body["fetch_all"] = fetch_all
|
|
18
|
+
return self.http.request("POST", f"/actions/google_drive/list_files/{connector_id}", json=body)
|
|
19
|
+
|
|
20
|
+
def read(self, connector_id: str, *, file_id: str):
|
|
21
|
+
body = {"file_id": file_id}
|
|
22
|
+
return self.http.request("POST", f"/actions/google_drive/read/{connector_id}", json=body)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any, Optional
|
|
3
|
+
|
|
4
|
+
from .core.http import HttpClient
|
|
5
|
+
|
|
6
|
+
class ConnectorsMgmt:
|
|
7
|
+
def __init__(self, http: HttpClient):
|
|
8
|
+
self.http = http
|
|
9
|
+
|
|
10
|
+
# GET /connectors/?projectID=...
|
|
11
|
+
def list(self, project_id: Optional[str] = None) -> Any:
|
|
12
|
+
params = {"projectID": project_id} if project_id else None
|
|
13
|
+
return self.http.request("GET", "/connectors/", params=params)
|
|
14
|
+
|
|
15
|
+
# GET /connectors/{projectID}
|
|
16
|
+
def list_by_project_id(self, project_id: str) -> Any:
|
|
17
|
+
return self.http.request("GET", f"/connectors/{project_id}")
|
|
18
|
+
|
|
19
|
+
# GET /v1/connector/{id}
|
|
20
|
+
def get_by_id(self, connector_id: str) -> Any:
|
|
21
|
+
return self.http.request("GET", f"/v1/connector/{connector_id}")
|
|
22
|
+
|
|
23
|
+
# GET /connector/{connector_id}
|
|
24
|
+
def get_by_id_path(self, connector_id: str) -> Any:
|
|
25
|
+
return self.http.request("GET", f"/connector/{connector_id}")
|
|
26
|
+
|
|
27
|
+
# DELETE /v1/connector/{id}?projectID=...
|
|
28
|
+
def delete(self, connector_id: str, *, project_id: Optional[str] = None) -> Any:
|
|
29
|
+
params = {"projectID": project_id} if project_id else None
|
|
30
|
+
return self.http.request("DELETE", f"/v1/connector/{connector_id}", params=params)
|
|
31
|
+
|
|
32
|
+
# DELETE /connector/{connector_id}?projectID=...
|
|
33
|
+
def delete_by_id_path(self, connector_id: str, *, project_id: str) -> Any:
|
|
34
|
+
return self.http.request("DELETE", f"/connector/{connector_id}", params={"projectID": project_id})
|
|
35
|
+
|
|
36
|
+
# POST /connectors/change_status
|
|
37
|
+
def update_status(self, *, new_status: str, connectorID: str, data_loader_config: dict) -> Any:
|
|
38
|
+
body = {"new_status": new_status, "connectorID": connectorID, "data_loader_config": data_loader_config}
|
|
39
|
+
return self.http.request("POST", "/connectors/change_status", json=body)
|
|
40
|
+
|
|
41
|
+
# GET /connectors/trigger_actions?projectID=...
|
|
42
|
+
def list_trigger_actions(self, project_id: str) -> Any:
|
|
43
|
+
return self.http.request("GET", "/connectors/trigger_actions", params={"projectID": project_id})
|
|
44
|
+
|
|
45
|
+
# GET /connectors/{projectID}/trigger_actions
|
|
46
|
+
def list_trigger_actions_by_project(self, project_id: str) -> Any:
|
|
47
|
+
return self.http.request("GET", f"/connectors/{project_id}/trigger_actions", params={"projectID": project_id})
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import time
|
|
3
|
+
from typing import Any, Callable, Optional
|
|
4
|
+
|
|
5
|
+
from .core.http import HttpClient
|
|
6
|
+
|
|
7
|
+
DEFAULT_TERMINAL = {"completed", "failed", "canceled"}
|
|
8
|
+
|
|
9
|
+
class Executions:
|
|
10
|
+
def __init__(self, http: HttpClient, polling: Optional[dict] = None):
|
|
11
|
+
self.http = http
|
|
12
|
+
self.polling = polling or {}
|
|
13
|
+
|
|
14
|
+
def start(self, payload: dict, *, projectID: Optional[str] = None):
|
|
15
|
+
params = {"projectID": projectID} if projectID else None
|
|
16
|
+
return self.http.request("POST", "/execute_flow", json=payload, params=params)
|
|
17
|
+
|
|
18
|
+
def get(self, execution_id: str):
|
|
19
|
+
return self.http.request("GET", f"/execute_flow/{execution_id}")
|
|
20
|
+
|
|
21
|
+
def monitor(self, agentflow_id: str):
|
|
22
|
+
return self.http.request("GET", f"/execute_flow/{agentflow_id}/monitor")
|
|
23
|
+
|
|
24
|
+
def pause(self, execution_id: str):
|
|
25
|
+
return self.http.request("POST", f"/execute_flow/{execution_id}/pause")
|
|
26
|
+
|
|
27
|
+
def resume(self, execution_id: str):
|
|
28
|
+
return self.http.request("POST", f"/execute_flow/{execution_id}/resume")
|
|
29
|
+
|
|
30
|
+
def cancel(self, execution_id: str):
|
|
31
|
+
return self.http.request("POST", f"/execute_flow/{execution_id}/cancel")
|
|
32
|
+
|
|
33
|
+
def approve_preview(self, execution_id: str):
|
|
34
|
+
return self.http.request("PUT", f"/execute_flow/{execution_id}/approve_preview")
|
|
35
|
+
|
|
36
|
+
def approve_anomaly(self, execution_id: str):
|
|
37
|
+
return self.http.request("PUT", f"/execute_flow/{execution_id}/approve_anomaly")
|
|
38
|
+
|
|
39
|
+
def update_runtime_input(self, execution_id: str, body: dict):
|
|
40
|
+
return self.http.request("PUT", f"/execute_flow/{execution_id}/runtime_input", json=body)
|
|
41
|
+
|
|
42
|
+
def wait(self, execution_id: str, *, interval_ms: Optional[int] = None, timeout_ms: Optional[int] = None, is_terminal: Optional[Callable[[str], bool]] = None):
|
|
43
|
+
interval = interval_ms or self.polling.get("intervalMs", 2000)
|
|
44
|
+
timeout = timeout_ms or self.polling.get("timeoutMs", 30 * 60 * 1000)
|
|
45
|
+
jitter = self.polling.get("jitter", 0.2)
|
|
46
|
+
term = is_terminal or (lambda s: (s or "").lower() in DEFAULT_TERMINAL)
|
|
47
|
+
|
|
48
|
+
start = time.time()
|
|
49
|
+
while True:
|
|
50
|
+
info = self.get(execution_id)
|
|
51
|
+
status = (info.get("status") or info.get("state") or "").lower()
|
|
52
|
+
if term(status):
|
|
53
|
+
return info
|
|
54
|
+
if (time.time() - start) * 1000 > timeout:
|
|
55
|
+
raise TimeoutError("Execution wait timeout")
|
|
56
|
+
j = 1 + ((2 * (time.time() % 1) - 1) * jitter)
|
|
57
|
+
time.sleep(max(0.2, (interval * j) / 1000))
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any, Dict, Optional
|
|
3
|
+
|
|
4
|
+
from .core.http import HttpClient
|
|
5
|
+
|
|
6
|
+
class Files:
|
|
7
|
+
def __init__(self, http: HttpClient):
|
|
8
|
+
self.http = http
|
|
9
|
+
|
|
10
|
+
# POST /files/upload?projectID=...&container_name=...
|
|
11
|
+
# body example: { "filenames": ["file.pdf"], "tags": ["resume"], "source_type": "STORAGE", "org_id": "..." }
|
|
12
|
+
def upload_request(self, project_id: str, container_name: str, body: Dict[str, Any]):
|
|
13
|
+
params: Dict[str, Any] = {"projectID": project_id, "container_name": container_name}
|
|
14
|
+
return self.http.request("POST", "/files/upload", params=params, json=body)
|
|
15
|
+
|
|
16
|
+
# GET /file/{fileId}/?projectID=...
|
|
17
|
+
def get_by_file_id(self, file_id: str, project_id: Optional[str] = None):
|
|
18
|
+
params = {"projectID": project_id} if project_id else None
|
|
19
|
+
return self.http.request("GET", f"/file/{file_id}/", params=params)
|
|
20
|
+
|
|
21
|
+
# GET /files/{connectorId}/connector/
|
|
22
|
+
def list_by_connector(self, connector_id: str):
|
|
23
|
+
return self.http.request("GET", f"/files/{connector_id}/connector/")
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any, Dict, Optional
|
|
3
|
+
|
|
4
|
+
from .core.http import HttpClient
|
|
5
|
+
|
|
6
|
+
class Inbox:
|
|
7
|
+
def __init__(self, http: HttpClient):
|
|
8
|
+
self.http = http
|
|
9
|
+
|
|
10
|
+
# POST /inbox/create
|
|
11
|
+
def create(self, body: Dict[str, Any]):
|
|
12
|
+
return self.http.request("POST", "/inbox/create", json=body)
|
|
13
|
+
|
|
14
|
+
# GET /inbox?projectID=...&limit=...
|
|
15
|
+
def list(self, project_id: str, *, limit: Optional[int] = None):
|
|
16
|
+
params: Dict[str, Any] = {"projectID": project_id}
|
|
17
|
+
if limit is not None:
|
|
18
|
+
params["limit"] = limit
|
|
19
|
+
return self.http.request("GET", "/inbox", params=params)
|
|
20
|
+
|
|
21
|
+
# POST /inbox/update/runtime_input/?projectID=...
|
|
22
|
+
def update_runtime(self, project_id: str, body: Dict[str, Any]):
|
|
23
|
+
return self.http.request("POST", "/inbox/update/runtime_input/", params={"projectID": project_id}, json=body)
|
|
24
|
+
|
|
25
|
+
# POST /inbox/update/anomaly_detection/?projectID=...
|
|
26
|
+
def update_anomaly(self, project_id: str, body: Dict[str, Any]):
|
|
27
|
+
return self.http.request("POST", "/inbox/update/anomaly_detection/", params={"projectID": project_id}, json=body)
|
|
28
|
+
|
|
29
|
+
# POST /inbox/update/preview/?projectID=...
|
|
30
|
+
def update_preview(self, project_id: str, body: Dict[str, Any]):
|
|
31
|
+
return self.http.request("POST", "/inbox/update/preview/", params={"projectID": project_id}, json=body)
|
|
32
|
+
|
|
33
|
+
# POST /inbox/update/preview/{execution_id}?projectID=...
|
|
34
|
+
def update_preview_by_execution(self, execution_id: str, body: Dict[str, Any], project_id: Optional[str] = None):
|
|
35
|
+
params = {"projectID": project_id} if project_id else None
|
|
36
|
+
return self.http.request("POST", f"/inbox/update/preview/{execution_id}", params=params, json=body)
|
|
37
|
+
|
|
38
|
+
# GET /inbox/{id}?projectID=...
|
|
39
|
+
def get(self, inbox_id: str, project_id: Optional[str] = None):
|
|
40
|
+
params = {"projectID": project_id} if project_id else None
|
|
41
|
+
return self.http.request("GET", f"/inbox/{inbox_id}", params=params)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any, Dict
|
|
3
|
+
|
|
4
|
+
from .core.http import HttpClient
|
|
5
|
+
|
|
6
|
+
class Marketplace:
|
|
7
|
+
def __init__(self, http: HttpClient):
|
|
8
|
+
self.http = http
|
|
9
|
+
|
|
10
|
+
# GET /public/connectors/all?search_key=...&projectID=...&filter_type=...
|
|
11
|
+
def list_connectors(self, *, search_key: str, projectID: str, filter_type: str):
|
|
12
|
+
params: Dict[str, Any] = {"search_key": search_key, "projectID": projectID, "filter_type": filter_type}
|
|
13
|
+
return self.http.request("GET", "/public/connectors/all", params=params)
|
|
14
|
+
|
|
15
|
+
# GET /public/marketplace/coworkers?search_key=...&limit=...
|
|
16
|
+
def list_coworkers(self, *, search_key: str, limit: int | str):
|
|
17
|
+
params: Dict[str, Any] = {"search_key": search_key, "limit": limit}
|
|
18
|
+
return self.http.request("GET", "/public/marketplace/coworkers", params=params)
|
|
19
|
+
|
|
20
|
+
# GET /public/marketplace/coworker/{coworker_id}
|
|
21
|
+
def get_coworker_by_id(self, coworker_id: str):
|
|
22
|
+
return self.http.request("GET", f"/public/marketplace/coworker/{coworker_id}")
|
|
23
|
+
|
|
24
|
+
# POST /marketplace/coworker/{coworker_id}/purchase?organization_id=...
|
|
25
|
+
def purchase_coworker(self, coworker_id: str, *, organization_id: str, body: Dict[str, Any] | None = None):
|
|
26
|
+
params = {"organization_id": organization_id}
|
|
27
|
+
return self.http.request("POST", f"/marketplace/coworker/{coworker_id}/purchase", params=params, json=(body or {}))
|
|
28
|
+
|
|
29
|
+
# GET /marketplace/coworker/update/{coworker_id}/check
|
|
30
|
+
def check_coworker_update(self, coworker_id: str):
|
|
31
|
+
return self.http.request("GET", f"/marketplace/coworker/update/{coworker_id}/check")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Placeholder for pydantic models (to be added as API payloads stabilize).
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from .core.http import HttpClient
|
|
5
|
+
|
|
6
|
+
class ProjectMembers:
|
|
7
|
+
def __init__(self, http: HttpClient):
|
|
8
|
+
self.http = http
|
|
9
|
+
|
|
10
|
+
# GET /project-member/{projectID}/summary
|
|
11
|
+
def summary(self, project_id: str) -> Any:
|
|
12
|
+
return self.http.request("GET", f"/project-member/{project_id}/summary")
|
|
13
|
+
|
|
14
|
+
# GET /project-member/{projectID}
|
|
15
|
+
def list(self, project_id: str) -> Any:
|
|
16
|
+
return self.http.request("GET", f"/project-member/{project_id}")
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Optional, Dict, Any
|
|
3
|
+
|
|
4
|
+
from .core.http import HttpClient
|
|
5
|
+
|
|
6
|
+
class Projects:
|
|
7
|
+
def __init__(self, http: HttpClient):
|
|
8
|
+
self.http = http
|
|
9
|
+
|
|
10
|
+
# Per developers.wexa.ai: POST https://api.wexa.ai/v1/project
|
|
11
|
+
def create(self, body: Dict[str, Any]):
|
|
12
|
+
"""
|
|
13
|
+
Expected body (example):
|
|
14
|
+
{
|
|
15
|
+
"orgId": "67fdea40aac77be632954f0f",
|
|
16
|
+
"projectName": "New",
|
|
17
|
+
"description": "yoooo",
|
|
18
|
+
"coworker_role": "testrole"
|
|
19
|
+
}
|
|
20
|
+
"""
|
|
21
|
+
return self.http.request("POST", "/v1/project", json=body)
|
|
22
|
+
|
|
23
|
+
def list(self):
|
|
24
|
+
return self.http.request("GET", "/v1/project")
|
|
25
|
+
|
|
26
|
+
def get(self, project_id: str):
|
|
27
|
+
return self.http.request("GET", f"/v1/project/{project_id}")
|
|
28
|
+
|
|
29
|
+
def update(self, project_id: str, body: Dict[str, Any]):
|
|
30
|
+
return self.http.request("PUT", f"/v1/project/{project_id}", json=body)
|
|
31
|
+
|
|
32
|
+
def delete(self, project_id: str):
|
|
33
|
+
return self.http.request("DELETE", f"/v1/project/{project_id}")
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from .core.http import HttpClient
|
|
4
|
+
|
|
5
|
+
class Settings:
|
|
6
|
+
def __init__(self, http: HttpClient):
|
|
7
|
+
self.http = http
|
|
8
|
+
|
|
9
|
+
# GET /settings/{projectID}
|
|
10
|
+
def get(self, project_id: str):
|
|
11
|
+
return self.http.request("GET", f"/settings/{project_id}")
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any, Dict, Optional
|
|
3
|
+
|
|
4
|
+
from .core.http import HttpClient
|
|
5
|
+
|
|
6
|
+
class Skills:
|
|
7
|
+
def __init__(self, http: HttpClient):
|
|
8
|
+
self.http = http
|
|
9
|
+
|
|
10
|
+
# POST /skills/
|
|
11
|
+
def create(self, body: Dict[str, Any]):
|
|
12
|
+
return self.http.request("POST", "/skills/", json=body)
|
|
13
|
+
|
|
14
|
+
# GET /skills/?projectID=...&limit=...
|
|
15
|
+
def list(self, project_id: str, *, limit: Optional[int] = None):
|
|
16
|
+
params: Dict[str, Any] = {"projectID": project_id}
|
|
17
|
+
if limit is not None:
|
|
18
|
+
params["limit"] = limit
|
|
19
|
+
return self.http.request("GET", "/skills/", params=params)
|
|
20
|
+
|
|
21
|
+
# GET /skills/category?projectId=...&category=...&limit=...
|
|
22
|
+
def list_by_category(self, project_id: str, category: str, *, limit: Optional[int] = None):
|
|
23
|
+
params: Dict[str, Any] = {"projectId": project_id, "category": category}
|
|
24
|
+
if limit is not None:
|
|
25
|
+
params["limit"] = limit
|
|
26
|
+
return self.http.request("GET", "/skills/category", params=params)
|
|
27
|
+
|
|
28
|
+
# GET /skills/{id}
|
|
29
|
+
def get_by_id(self, skill_id: str):
|
|
30
|
+
return self.http.request("GET", f"/skills/{skill_id}")
|
|
31
|
+
|
|
32
|
+
# GET /skills/?name=...&projectID=...
|
|
33
|
+
def get_by_name(self, name: str, project_id: str):
|
|
34
|
+
params = {"name": name, "projectID": project_id}
|
|
35
|
+
return self.http.request("GET", "/skills/", params=params)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any, Optional
|
|
3
|
+
|
|
4
|
+
from .core.http import HttpClient
|
|
5
|
+
|
|
6
|
+
class Tables:
|
|
7
|
+
def __init__(self, http: HttpClient):
|
|
8
|
+
self.http = http
|
|
9
|
+
|
|
10
|
+
# Tables
|
|
11
|
+
def create_table(self, project_id: str, spec: dict):
|
|
12
|
+
# API expects projectID as query param and in body with 'projectID' casing
|
|
13
|
+
params = {"projectID": project_id}
|
|
14
|
+
body = {"projectID": project_id, **spec}
|
|
15
|
+
return self.http.request("POST", "/create/table", params=params, json=body)
|
|
16
|
+
|
|
17
|
+
def list_tables(self, project_id: str):
|
|
18
|
+
return self.http.request("GET", f"/storage/{project_id}")
|
|
19
|
+
|
|
20
|
+
def get_table(self, project_id: str, table_id: str):
|
|
21
|
+
return self.http.request("GET", f"/storage/{project_id}/{table_id}")
|
|
22
|
+
|
|
23
|
+
def get_table_view(self, table_id: str):
|
|
24
|
+
return self.http.request("GET", f"/table/view/{table_id}")
|
|
25
|
+
|
|
26
|
+
def rename_table(self, project_id: str, table_id: str, new_name: str):
|
|
27
|
+
return self.http.request("POST", f"/table/rename/{project_id}", json={"tableId": table_id, "newName": new_name})
|
|
28
|
+
|
|
29
|
+
# Columns
|
|
30
|
+
def get_columns(self, project_id: str, table_id: str):
|
|
31
|
+
return self.http.request("GET", f"/column/storage/{project_id}/{table_id}")
|
|
32
|
+
|
|
33
|
+
def edit_columns(self, table_id: str, spec: dict):
|
|
34
|
+
return self.http.request("POST", f"/edit/columns/{table_id}", json=spec)
|
|
35
|
+
|
|
36
|
+
def delete_column(self, project_id: str, column_id: str):
|
|
37
|
+
return self.http.request("DELETE", f"/delete/column/{project_id}", json={"columnId": column_id})
|
|
38
|
+
|
|
39
|
+
# Records
|
|
40
|
+
def create_record(self, project_id: str, table_id: str, record: dict):
|
|
41
|
+
return self.http.request("POST", f"/storage/{project_id}/{table_id}", json=record)
|
|
42
|
+
|
|
43
|
+
def get_record(self, project_id: str, table_id: str, record_id: str):
|
|
44
|
+
return self.http.request("GET", f"/storage/{project_id}/{table_id}/{record_id}")
|
|
45
|
+
|
|
46
|
+
def update_record(self, project_id: str, table_id: str, record_id: str, record: dict):
|
|
47
|
+
return self.http.request("PUT", f"/storage/{project_id}/{table_id}/{record_id}", json=record)
|
|
48
|
+
|
|
49
|
+
def delete_record(self, project_id: str, table_id: str, record_id: str):
|
|
50
|
+
return self.http.request("DELETE", f"/storage/{project_id}/{table_id}/{record_id}")
|
|
51
|
+
|
|
52
|
+
def list_records(self, project_id: str, table_id: str, query: Optional[dict] = None):
|
|
53
|
+
return self.http.request("GET", f"/storage/{project_id}/{table_id}", params=query)
|
|
54
|
+
|
|
55
|
+
def bulk_upsert(self, project_id: str, table_id: str, records: list[dict]):
|
|
56
|
+
return self.http.request("POST", f"/bulk/storage/{project_id}/{table_id}", json={"records": records})
|
|
57
|
+
|
|
58
|
+
def export(self, project_id: str, table_id: str):
|
|
59
|
+
return self.http.request("GET", f"/table_data/storage/{table_id}/export")
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any, Dict, Optional
|
|
3
|
+
|
|
4
|
+
from .core.http import HttpClient
|
|
5
|
+
|
|
6
|
+
class Tasks:
|
|
7
|
+
def __init__(self, http: HttpClient):
|
|
8
|
+
self.http = http
|
|
9
|
+
|
|
10
|
+
# GET /tasks/?projectID=...&limit=...&skip=...&created_by=...
|
|
11
|
+
def list(self, project_id: str, *, limit: Optional[int] = None, skip: Optional[int] = None, created_by: Optional[str] = None):
|
|
12
|
+
params: Dict[str, Any] = {"projectID": project_id}
|
|
13
|
+
if limit is not None:
|
|
14
|
+
params["limit"] = limit
|
|
15
|
+
if skip is not None:
|
|
16
|
+
params["skip"] = skip
|
|
17
|
+
if created_by:
|
|
18
|
+
params["created_by"] = created_by
|
|
19
|
+
return self.http.request("GET", "/tasks/", params=params)
|
|
20
|
+
|
|
21
|
+
# GET /task/{id}?projectID=...
|
|
22
|
+
def get(self, task_id: str, project_id: Optional[str] = None):
|
|
23
|
+
params = {"projectID": project_id} if project_id else None
|
|
24
|
+
return self.http.request("GET", f"/task/{task_id}", params=params)
|
|
25
|
+
|
|
26
|
+
# POST /task/{id}/pause
|
|
27
|
+
def pause(self, task_id: str):
|
|
28
|
+
return self.http.request("POST", f"/task/{task_id}/pause")
|
|
29
|
+
|
|
30
|
+
# POST /task/{id}/resume
|
|
31
|
+
def resume(self, task_id: str):
|
|
32
|
+
return self.http.request("POST", f"/task/{task_id}/resume")
|
|
33
|
+
|
|
34
|
+
# POST /task/{id}/stop
|
|
35
|
+
def stop(self, task_id: str):
|
|
36
|
+
return self.http.request("POST", f"/task/{task_id}/stop")
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wexa-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official Wexa Python SDK
|
|
5
|
+
Author: Wexa
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/wexa-ai/wexa-sdk
|
|
8
|
+
Keywords: wexa,sdk,api
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: httpx>=0.27
|
|
15
|
+
Requires-Dist: pydantic>=2.6
|
|
16
|
+
|
|
17
|
+
# wexa-sdk (Python)
|
|
18
|
+
|
|
19
|
+
Python SDK for Wexa API.
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from wexa_sdk import WexaClient
|
|
23
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
wexa_sdk/__init__.py
|
|
4
|
+
wexa_sdk/agentflows.py
|
|
5
|
+
wexa_sdk/analytics.py
|
|
6
|
+
wexa_sdk/connectors_mgmt.py
|
|
7
|
+
wexa_sdk/executions.py
|
|
8
|
+
wexa_sdk/files.py
|
|
9
|
+
wexa_sdk/inbox.py
|
|
10
|
+
wexa_sdk/marketplace.py
|
|
11
|
+
wexa_sdk/project_members.py
|
|
12
|
+
wexa_sdk/projects.py
|
|
13
|
+
wexa_sdk/settings.py
|
|
14
|
+
wexa_sdk/skills.py
|
|
15
|
+
wexa_sdk/tables.py
|
|
16
|
+
wexa_sdk/tasks.py
|
|
17
|
+
wexa_sdk.egg-info/PKG-INFO
|
|
18
|
+
wexa_sdk.egg-info/SOURCES.txt
|
|
19
|
+
wexa_sdk.egg-info/dependency_links.txt
|
|
20
|
+
wexa_sdk.egg-info/requires.txt
|
|
21
|
+
wexa_sdk.egg-info/top_level.txt
|
|
22
|
+
wexa_sdk/connectors/__init__.py
|
|
23
|
+
wexa_sdk/connectors/core.py
|
|
24
|
+
wexa_sdk/connectors/google_drive.py
|
|
25
|
+
wexa_sdk/models/__init__.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
wexa_sdk
|