wexa-sdk 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. wexa_sdk-0.1.3/PKG-INFO +23 -0
  2. wexa_sdk-0.1.3/README.md +7 -0
  3. wexa_sdk-0.1.3/pyproject.toml +29 -0
  4. wexa_sdk-0.1.3/setup.cfg +4 -0
  5. wexa_sdk-0.1.3/tests/test_agentflows.py +22 -0
  6. wexa_sdk-0.1.3/tests/test_agentflows_crud.py +23 -0
  7. wexa_sdk-0.1.3/tests/test_analytics.py +21 -0
  8. wexa_sdk-0.1.3/tests/test_connectors_core.py +45 -0
  9. wexa_sdk-0.1.3/tests/test_connectors_mgmt.py +44 -0
  10. wexa_sdk-0.1.3/tests/test_demo_coworker_workflow.py +68 -0
  11. wexa_sdk-0.1.3/tests/test_executions.py +23 -0
  12. wexa_sdk-0.1.3/tests/test_files.py +20 -0
  13. wexa_sdk-0.1.3/tests/test_inbox.py +28 -0
  14. wexa_sdk-0.1.3/tests/test_integration_agentflows_create.py +40 -0
  15. wexa_sdk-0.1.3/tests/test_integration_marketplace.py +13 -0
  16. wexa_sdk-0.1.3/tests/test_marketplace.py +24 -0
  17. wexa_sdk-0.1.3/tests/test_project_members.py +18 -0
  18. wexa_sdk-0.1.3/tests/test_projects.py +22 -0
  19. wexa_sdk-0.1.3/tests/test_projects_crud.py +24 -0
  20. wexa_sdk-0.1.3/tests/test_projects_get_all.py +42 -0
  21. wexa_sdk-0.1.3/tests/test_settings.py +19 -0
  22. wexa_sdk-0.1.3/tests/test_skills.py +24 -0
  23. wexa_sdk-0.1.3/tests/test_tables.py +49 -0
  24. wexa_sdk-0.1.3/tests/test_tasks.py +24 -0
  25. wexa_sdk-0.1.3/wexa_sdk/__init__.py +37 -0
  26. wexa_sdk-0.1.3/wexa_sdk/agentflows.py +75 -0
  27. wexa_sdk-0.1.3/wexa_sdk/analytics.py +12 -0
  28. wexa_sdk-0.1.3/wexa_sdk/connectors/__init__.py +1 -0
  29. wexa_sdk-0.1.3/wexa_sdk/connectors/core.py +24 -0
  30. wexa_sdk-0.1.3/wexa_sdk/connectors/google_drive.py +22 -0
  31. wexa_sdk-0.1.3/wexa_sdk/connectors_mgmt.py +47 -0
  32. wexa_sdk-0.1.3/wexa_sdk/core/__init__.py +1 -0
  33. wexa_sdk-0.1.3/wexa_sdk/core/http.py +86 -0
  34. wexa_sdk-0.1.3/wexa_sdk/executions.py +57 -0
  35. wexa_sdk-0.1.3/wexa_sdk/files.py +30 -0
  36. wexa_sdk-0.1.3/wexa_sdk/inbox.py +41 -0
  37. wexa_sdk-0.1.3/wexa_sdk/marketplace.py +31 -0
  38. wexa_sdk-0.1.3/wexa_sdk/models/__init__.py +1 -0
  39. wexa_sdk-0.1.3/wexa_sdk/project_members.py +16 -0
  40. wexa_sdk-0.1.3/wexa_sdk/projects.py +134 -0
  41. wexa_sdk-0.1.3/wexa_sdk/settings.py +11 -0
  42. wexa_sdk-0.1.3/wexa_sdk/skills.py +57 -0
  43. wexa_sdk-0.1.3/wexa_sdk/tables.py +59 -0
  44. wexa_sdk-0.1.3/wexa_sdk/tasks.py +36 -0
  45. wexa_sdk-0.1.3/wexa_sdk.egg-info/PKG-INFO +23 -0
  46. wexa_sdk-0.1.3/wexa_sdk.egg-info/SOURCES.txt +47 -0
  47. wexa_sdk-0.1.3/wexa_sdk.egg-info/dependency_links.txt +1 -0
  48. wexa_sdk-0.1.3/wexa_sdk.egg-info/requires.txt +2 -0
  49. wexa_sdk-0.1.3/wexa_sdk.egg-info/top_level.txt +1 -0
@@ -0,0 +1,23 @@
1
+ Metadata-Version: 2.4
2
+ Name: wexa-sdk
3
+ Version: 0.1.3
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,7 @@
1
+ # wexa-sdk (Python)
2
+
3
+ Python SDK for Wexa API.
4
+
5
+ ```python
6
+ from wexa_sdk import WexaClient
7
+ ```
@@ -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.3"
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.core", "wexa_sdk.connectors", "wexa_sdk.models"]
29
+ include-package-data = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,22 @@
1
+ import pytest
2
+ from wexa_sdk import WexaClient
3
+
4
+
5
+ def test_agentflows_list_builds_params(monkeypatch):
6
+ c = WexaClient(base_url="https://api.wexa.ai", api_key="key")
7
+ calls = {}
8
+
9
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
10
+ calls["method"] = method
11
+ calls["path"] = path
12
+ calls["params"] = params
13
+ return {"ok": True}
14
+
15
+ c.http.request = fake_request # type: ignore
16
+
17
+ res = c.agentflows.list(projectID="p1", skip=1, limit=2)
18
+
19
+ assert calls["method"] == "GET"
20
+ assert calls["path"] == "/agentflows"
21
+ assert calls["params"] == {"projectID": "p1", "skip": 1, "limit": 2}
22
+ assert res == {"ok": True}
@@ -0,0 +1,23 @@
1
+ from wexa_sdk import WexaClient
2
+
3
+
4
+ def test_agentflows_crud(monkeypatch):
5
+ c = WexaClient(base_url="https://api.wexa.ai", api_key="key")
6
+ calls = []
7
+
8
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
9
+ calls.append((method, path, params, json))
10
+ return {"ok": True}
11
+
12
+ c.http.request = fake_request # type: ignore
13
+
14
+ # create with projectID in body -> should go to query as well
15
+ c.agentflows.create({"name": "N", "projectID": "p1"})
16
+ # update
17
+ c.agentflows.update("af1", {"name": "U"})
18
+ # delete
19
+ c.agentflows.delete("p1", "af1")
20
+
21
+ assert calls[0][0] == "POST" and calls[0][1] == "/agentflow/" and calls[0][2] == {"projectID": "p1"}
22
+ assert calls[1][0] == "PUT" and calls[1][1] == "/agentflow/af1"
23
+ assert calls[2][0] == "DELETE" and calls[2][1] == "/agentflow/p1/af1"
@@ -0,0 +1,21 @@
1
+ from wexa_sdk import WexaClient
2
+
3
+
4
+ def test_analytics_get_builds_query(monkeypatch):
5
+ c = WexaClient(base_url="https://api.wexa.ai", api_key="key")
6
+ calls = {}
7
+
8
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
9
+ calls["method"] = method
10
+ calls["path"] = path
11
+ calls["params"] = params
12
+ return {"ok": True}
13
+
14
+ c.http.request = fake_request # type: ignore
15
+
16
+ res = c.analytics.get("p1")
17
+
18
+ assert calls["method"] == "GET"
19
+ assert calls["path"] == "/analytics"
20
+ assert calls["params"] == {"projectID": "p1"}
21
+ assert res == {"ok": True}
@@ -0,0 +1,45 @@
1
+ from wexa_sdk import WexaClient
2
+
3
+
4
+ def test_connectors_core_actions_and_config(monkeypatch):
5
+ c = WexaClient(base_url="https://api.wexa.ai", api_key="key")
6
+ calls = []
7
+
8
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
9
+ calls.append((method, path, params, json))
10
+ return {"ok": True}
11
+
12
+ c.http.request = fake_request # type: ignore
13
+
14
+ # action without connector_id, then with connector_id
15
+ c.connectors.action("drive", "sync", body={"x": 1}, projectID="p1")
16
+ c.connectors.action("drive", "sync", "cid1", body={"y": 2}, projectID="p1")
17
+
18
+ # config
19
+ c.connectors.set_config("drive", "p1", {"cfg": True})
20
+ c.connectors.get_config("drive", "p1")
21
+
22
+ assert calls[0] == (
23
+ "POST",
24
+ "/actions/drive/sync",
25
+ {"projectID": "p1"},
26
+ {"x": 1},
27
+ )
28
+ assert calls[1] == (
29
+ "POST",
30
+ "/actions/drive/sync/cid1",
31
+ {"projectID": "p1"},
32
+ {"y": 2},
33
+ )
34
+ assert calls[2] == (
35
+ "POST",
36
+ "/actions/drive/config",
37
+ {"projectID": "p1"},
38
+ {"cfg": True},
39
+ )
40
+ assert calls[3] == (
41
+ "GET",
42
+ "/actions/drive/config/p1",
43
+ None,
44
+ None,
45
+ )
@@ -0,0 +1,44 @@
1
+ from wexa_sdk import WexaClient
2
+
3
+
4
+ def test_connectors_mgmt_endpoints(monkeypatch):
5
+ c = WexaClient(base_url="https://api.wexa.ai", api_key="key")
6
+ calls = []
7
+
8
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
9
+ calls.append((method, path, params, json))
10
+ return {"ok": True}
11
+
12
+ c.http.request = fake_request # type: ignore
13
+
14
+ # list variants
15
+ c.connectors_mgmt.list()
16
+ c.connectors_mgmt.list("p1")
17
+ c.connectors_mgmt.list_by_project_id("p1")
18
+
19
+ # get
20
+ c.connectors_mgmt.get_by_id("cid1")
21
+ c.connectors_mgmt.get_by_id_path("cid1")
22
+
23
+ # delete variants
24
+ c.connectors_mgmt.delete("cid1")
25
+ c.connectors_mgmt.delete("cid1", project_id="p1")
26
+ c.connectors_mgmt.delete_by_id_path("cid1", project_id="p1")
27
+
28
+ # status + triggers
29
+ c.connectors_mgmt.update_status(new_status="active", connectorID="cid1", data_loader_config={})
30
+ c.connectors_mgmt.list_trigger_actions("p1")
31
+ c.connectors_mgmt.list_trigger_actions_by_project("p1")
32
+
33
+ i = 0
34
+ assert calls[i] == ("GET", "/connectors/", None, None); i += 1
35
+ assert calls[i] == ("GET", "/connectors/", {"projectID": "p1"}, None); i += 1
36
+ assert calls[i] == ("GET", "/connectors/p1", None, None); i += 1
37
+ assert calls[i] == ("GET", "/v1/connector/cid1", None, None); i += 1
38
+ assert calls[i] == ("GET", "/connector/cid1", None, None); i += 1
39
+ assert calls[i] == ("DELETE", "/v1/connector/cid1", None, None); i += 1
40
+ assert calls[i] == ("DELETE", "/v1/connector/cid1", {"projectID": "p1"}, None); i += 1
41
+ assert calls[i] == ("DELETE", "/connector/cid1", {"projectID": "p1"}, None); i += 1
42
+ assert calls[i] == ("POST", "/connectors/change_status", None, {"new_status": "active", "connectorID": "cid1", "data_loader_config": {}}); i += 1
43
+ assert calls[i] == ("GET", "/connectors/trigger_actions", {"projectID": "p1"}, None); i += 1
44
+ assert calls[i] == ("GET", "/connectors/p1/trigger_actions", {"projectID": "p1"}, None); i += 1
@@ -0,0 +1,68 @@
1
+ import os
2
+ import time
3
+ import json
4
+ import pytest
5
+
6
+ from wexa_sdk import WexaClient
7
+
8
+ BASE = os.environ.get("WEXA_BASE_URL", "https://api.wexa.ai")
9
+ API_KEY = os.environ.get("WEXA_API_KEY")
10
+ PROJECT_ID = os.environ.get("WEXA_PROJECT_ID", "69088bf4121a635f1301ad8c")
11
+
12
+
13
+ @pytest.mark.skipif(not API_KEY, reason="Set WEXA_API_KEY to run this integration test")
14
+ def test_coworker_create_or_load_and_execute():
15
+ c = WexaClient(base_url=BASE, api_key=API_KEY)
16
+ # Use a mostly-unique name per run to avoid conflicts
17
+ name = f"InvoiceProcessor-{int(time.time()) % 100000}"
18
+
19
+ def get_by_name(name: str, project_id: str):
20
+ skip, limit = 0, 100
21
+ while True:
22
+ # Some environments reject skip=0; omit skip on first page
23
+ if skip > 0:
24
+ page = c.agentflows.list(projectID=project_id, skip=skip, limit=limit) or {}
25
+ else:
26
+ page = c.agentflows.list(projectID=project_id, limit=limit) or {}
27
+ arr = page.get("agentflows") or page.get("data") or []
28
+ for af in arr:
29
+ if af.get("name") == name:
30
+ return af
31
+ if len(arr) < limit:
32
+ return None
33
+ skip += limit
34
+
35
+ af = get_by_name(name, PROJECT_ID)
36
+ if not af:
37
+ body = {
38
+ "name": name,
39
+ "description": "created via SDK test",
40
+ "role": "SDK_ROLE",
41
+ "projectID": PROJECT_ID,
42
+ }
43
+ af = c.agentflows.create(body, projectID=PROJECT_ID)
44
+ assert af and af.get("_id"), "Agentflow creation failed"
45
+
46
+ # Execute the flow
47
+ payload = {
48
+ "agentflow_id": af["_id"],
49
+ "executed_by": "sdk@test",
50
+ "goal": "Demo run",
51
+ "input_variables": {"echo": "hello"},
52
+ "projectID": PROJECT_ID,
53
+ }
54
+ started = c.executions.start(payload, projectID=PROJECT_ID)
55
+ assert started and started.get("_id"), "Execution start failed"
56
+
57
+ # Try a brief wait; if it times out, fetch current state and finish
58
+ try:
59
+ res = c.executions.wait(started["_id"], timeout_ms=15_000)
60
+ except Exception:
61
+ res = c.executions.get(started["_id"])
62
+
63
+ assert isinstance(res, dict)
64
+ # Print (visible in CI logs) for manual inspection if needed
65
+ print(json.dumps({
66
+ "agentflow": {"_id": af.get("_id"), "name": af.get("name")},
67
+ "execution": {"_id": started.get("_id"), "status": res.get("status")}
68
+ })[:1000])
@@ -0,0 +1,23 @@
1
+ from wexa_sdk import WexaClient
2
+
3
+
4
+ def test_executions_start_posts_payload_and_query(monkeypatch):
5
+ c = WexaClient(base_url="https://api.wexa.ai", api_key="key")
6
+ calls = {}
7
+
8
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
9
+ calls["method"] = method
10
+ calls["path"] = path
11
+ calls["params"] = params
12
+ calls["json"] = json
13
+ return {"execution_id": "e1"}
14
+
15
+ c.http.request = fake_request # type: ignore
16
+
17
+ res = c.executions.start({"agentflow_id": "a1", "inputs": {}}, projectID="p1")
18
+
19
+ assert calls["method"] == "POST"
20
+ assert calls["path"] == "/execute_flow"
21
+ assert calls["params"] == {"projectID": "p1"}
22
+ assert calls["json"] == {"agentflow_id": "a1", "inputs": {}}
23
+ assert res == {"execution_id": "e1"}
@@ -0,0 +1,20 @@
1
+ from wexa_sdk import WexaClient
2
+
3
+
4
+ def test_files_endpoints(monkeypatch):
5
+ c = WexaClient(base_url="https://api.wexa.ai", api_key="key")
6
+ calls = []
7
+
8
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
9
+ calls.append((method, path, params, json))
10
+ return {"ok": True}
11
+
12
+ c.http.request = fake_request # type: ignore
13
+
14
+ c.files.upload_request("proj", "bucket", {"filenames": ["a.txt"]})
15
+ c.files.get_by_file_id("file1", "proj")
16
+ c.files.list_by_connector("conn1")
17
+
18
+ assert calls[0][0] == "POST" and calls[0][1] == "/files/upload" and calls[0][2] == {"projectID": "proj", "container_name": "bucket"}
19
+ assert calls[1][0] == "GET" and calls[1][1] == "/file/file1/" and calls[1][2] == {"projectID": "proj"}
20
+ assert calls[2][0] == "GET" and calls[2][1] == "/files/conn1/connector/"
@@ -0,0 +1,28 @@
1
+ from wexa_sdk import WexaClient
2
+
3
+
4
+ def test_inbox_endpoints(monkeypatch):
5
+ c = WexaClient(base_url="https://api.wexa.ai", api_key="key")
6
+ calls = []
7
+
8
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
9
+ calls.append((method, path, params, json))
10
+ return {"ok": True}
11
+
12
+ c.http.request = fake_request # type: ignore
13
+
14
+ c.inbox.create({"x": 1})
15
+ c.inbox.list("p1", limit=2)
16
+ c.inbox.update_runtime("p1", {"a": 1})
17
+ c.inbox.update_anomaly("p1", {"b": 2})
18
+ c.inbox.update_preview("p1", {"c": 3})
19
+ c.inbox.update_preview_by_execution("exec1", {"d": 4}, "p1")
20
+ c.inbox.get("inb1", "p1")
21
+
22
+ assert calls[0] == ("POST", "/inbox/create", None, {"x": 1})
23
+ assert calls[1] == ("GET", "/inbox", {"projectID": "p1", "limit": 2}, None)
24
+ assert calls[2] == ("POST", "/inbox/update/runtime_input/", {"projectID": "p1"}, {"a": 1})
25
+ assert calls[3] == ("POST", "/inbox/update/anomaly_detection/", {"projectID": "p1"}, {"b": 2})
26
+ assert calls[4] == ("POST", "/inbox/update/preview/", {"projectID": "p1"}, {"c": 3})
27
+ assert calls[5] == ("POST", "/inbox/update/preview/exec1", {"projectID": "p1"}, {"d": 4})
28
+ assert calls[6] == ("GET", "/inbox/inb1", {"projectID": "p1"}, None)
@@ -0,0 +1,40 @@
1
+ import os, time, json, pytest
2
+ from wexa_sdk import WexaClient
3
+ from wexa_sdk.core.http import ApiError
4
+
5
+ missing_env = not (os.getenv("WEXA_BASE_URL") and os.getenv("WEXA_API_KEY") and os.getenv("PROJECT_ID"))
6
+
7
+ @pytest.mark.integration
8
+ @pytest.mark.skipif(missing_env, reason="WEXA_BASE_URL/WEXA_API_KEY/PROJECT_ID not set")
9
+ def test_agentflows_create_get_delete():
10
+ base = os.environ["WEXA_BASE_URL"]
11
+ key = os.environ["WEXA_API_KEY"]
12
+ pid = os.environ["PROJECT_ID"]
13
+
14
+ c = WexaClient(base_url=base, api_key=key)
15
+
16
+ body = {
17
+ "name": f"sdk-integ-py-{int(time.time())}",
18
+ "description": "integration-create via sdk",
19
+ "role": "SDK_ROLE",
20
+ "projectID": pid,
21
+ }
22
+
23
+ afid = None
24
+ try:
25
+ created = c.agentflows.create(body, projectID=pid)
26
+ assert isinstance(created, dict)
27
+ afid = created.get("_id") or created.get("id")
28
+ assert afid and isinstance(afid, str)
29
+
30
+ got = c.agentflows.get(afid)
31
+ assert got.get("_id") == afid
32
+ assert got.get("name") == body["name"]
33
+ except ApiError as e:
34
+ pytest.fail(f"API error: {e.status} {e.detail}")
35
+ finally:
36
+ if afid:
37
+ try:
38
+ c.agentflows.delete(pid, afid)
39
+ except ApiError:
40
+ pass
@@ -0,0 +1,13 @@
1
+ import os
2
+ import pytest
3
+ from wexa_sdk import WexaClient
4
+
5
+ pytestmark = pytest.mark.integration
6
+
7
+ missing_env = not os.getenv("WEXA_BASE_URL") or not os.getenv("WEXA_API_KEY")
8
+
9
+ @pytest.mark.skipif(missing_env, reason="WEXA_BASE_URL/WEXA_API_KEY not set")
10
+ def test_marketplace_lists_coworkers():
11
+ c = WexaClient(base_url=os.environ["WEXA_BASE_URL"], api_key=os.environ["WEXA_API_KEY"])
12
+ res = c.marketplace.list_coworkers(search_key="", limit=1)
13
+ assert isinstance(res, dict)
@@ -0,0 +1,24 @@
1
+ from wexa_sdk import WexaClient
2
+
3
+
4
+ def test_marketplace_endpoints(monkeypatch):
5
+ c = WexaClient(base_url="https://api.wexa.ai", api_key="key")
6
+ calls = []
7
+
8
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
9
+ calls.append((method, path, params, json))
10
+ return {"ok": True}
11
+
12
+ c.http.request = fake_request # type: ignore
13
+
14
+ c.marketplace.list_connectors(search_key="", projectID="p1", filter_type="ALL")
15
+ c.marketplace.list_coworkers(search_key="", limit=2)
16
+ c.marketplace.get_coworker_by_id("cw1")
17
+ c.marketplace.purchase_coworker("cw1", organization_id="org1", body={"plan": "pro"})
18
+ c.marketplace.check_coworker_update("cw1")
19
+
20
+ assert calls[0] == ("GET", "/public/connectors/all", {"search_key": "", "projectID": "p1", "filter_type": "ALL"}, None)
21
+ assert calls[1] == ("GET", "/public/marketplace/coworkers", {"search_key": "", "limit": 2}, None)
22
+ assert calls[2] == ("GET", "/public/marketplace/coworker/cw1", None, None)
23
+ assert calls[3] == ("POST", "/marketplace/coworker/cw1/purchase", {"organization_id": "org1"}, {"plan": "pro"})
24
+ assert calls[4] == ("GET", "/marketplace/coworker/update/cw1/check", None, None)
@@ -0,0 +1,18 @@
1
+ from wexa_sdk import WexaClient
2
+
3
+
4
+ def test_project_members_endpoints(monkeypatch):
5
+ c = WexaClient(base_url="https://api.wexa.ai", api_key="key")
6
+ calls = []
7
+
8
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
9
+ calls.append((method, path, params, json))
10
+ return {"ok": True}
11
+
12
+ c.http.request = fake_request # type: ignore
13
+
14
+ c.project_members.summary("p1")
15
+ c.project_members.list("p1")
16
+
17
+ assert calls[0] == ("GET", "/project-member/p1/summary", None, None)
18
+ assert calls[1] == ("GET", "/project-member/p1", None, None)
@@ -0,0 +1,22 @@
1
+ from wexa_sdk import WexaClient
2
+
3
+
4
+ def test_projects_create_posts_body(monkeypatch):
5
+ c = WexaClient(base_url="https://api.wexa.ai", api_key="key")
6
+ calls = {}
7
+
8
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
9
+ calls["method"] = method
10
+ calls["path"] = path
11
+ calls["json"] = json
12
+ return {"_id": "p1"}
13
+
14
+ c.http.request = fake_request # type: ignore
15
+
16
+ body = {"orgId": "o1", "projectName": "Test", "description": "d", "coworker_role": "r"}
17
+ res = c.projects.create(body)
18
+
19
+ assert calls["method"] == "POST"
20
+ assert calls["path"] == "/v1/project"
21
+ assert calls["json"] == body
22
+ assert res == {"_id": "p1"}
@@ -0,0 +1,24 @@
1
+ from wexa_sdk import WexaClient
2
+
3
+
4
+ def test_projects_crud_paths(monkeypatch):
5
+ c = WexaClient(base_url="https://api.wexa.ai", api_key="key")
6
+ calls = []
7
+
8
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
9
+ calls.append((method, path, params, json))
10
+ return {"ok": True}
11
+
12
+ c.http.request = fake_request # type: ignore
13
+
14
+ c.projects.create({"orgId": "o1", "projectName": "P"})
15
+ c.projects.list()
16
+ c.projects.get("p1")
17
+ c.projects.update("p1", {"description": "d"})
18
+ c.projects.delete("p1")
19
+
20
+ assert calls[0][0] == "POST" and calls[0][1] == "/v1/project"
21
+ assert calls[1][0] == "GET" and calls[1][1] == "/v1/project"
22
+ assert calls[2][0] == "GET" and calls[2][1] == "/v1/project/p1"
23
+ assert calls[3][0] == "PUT" and calls[3][1] == "/v1/project/p1"
24
+ assert calls[4][0] == "DELETE" and calls[4][1] == "/v1/project/p1"
@@ -0,0 +1,42 @@
1
+ import os
2
+ from wexa_sdk import WexaClient
3
+
4
+
5
+ def test_projects_get_all_path_and_params(monkeypatch):
6
+ base_url = os.getenv("WEXA_BASE_URL", "https://api.wexa.ai")
7
+ api_key = os.getenv("WEXA_API_KEY", "key")
8
+
9
+ c = WexaClient(base_url=base_url, api_key=api_key)
10
+ calls = []
11
+
12
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
13
+ calls.append((method, path, params, json))
14
+ # Simulate API shape
15
+ return {"items": [], "count": 0}
16
+
17
+ # Patch HTTP layer to avoid real network
18
+ c.http.request = fake_request # type: ignore
19
+
20
+ res = c.projects.get_all(
21
+ status="published",
22
+ user_id="66f3cdde22bc63eb7490e23c",
23
+ org_id="66f3cdde22bc63eb7490e23e",
24
+ page=1,
25
+ limit=12,
26
+ )
27
+
28
+ # Assert method and path
29
+ assert calls[0][0] == "GET"
30
+ assert calls[0][1] == "/v1/project" # versioned path
31
+
32
+ # Assert query params
33
+ assert calls[0][2] == {
34
+ "status": "published",
35
+ "userId": "66f3cdde22bc63eb7490e23c",
36
+ "orgId": "66f3cdde22bc63eb7490e23e",
37
+ "page": 1,
38
+ "limit": 12,
39
+ }
40
+
41
+ # Assert returned structure from our fake
42
+ assert res == {"items": [], "count": 0}
@@ -0,0 +1,19 @@
1
+ from wexa_sdk import WexaClient
2
+
3
+
4
+ def test_settings_get(monkeypatch):
5
+ c = WexaClient(base_url="https://api.wexa.ai", api_key="key")
6
+ calls = {}
7
+
8
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
9
+ calls["method"] = method
10
+ calls["path"] = path
11
+ return {"ok": True}
12
+
13
+ c.http.request = fake_request # type: ignore
14
+
15
+ res = c.settings.get("p1")
16
+
17
+ assert calls["method"] == "GET"
18
+ assert calls["path"] == "/settings/p1"
19
+ assert res == {"ok": True}
@@ -0,0 +1,24 @@
1
+ from wexa_sdk import WexaClient
2
+
3
+
4
+ def test_skills_endpoints(monkeypatch):
5
+ c = WexaClient(base_url="https://api.wexa.ai", api_key="key")
6
+ calls = []
7
+
8
+ def fake_request(method, path, *, params=None, json=None, headers=None): # type: ignore
9
+ calls.append((method, path, params, json))
10
+ return {"ok": True}
11
+
12
+ c.http.request = fake_request # type: ignore
13
+
14
+ c.skills.create({"name": "s1"})
15
+ c.skills.list("p1", limit=2)
16
+ c.skills.list_by_category("p1", "LLM", limit=1)
17
+ c.skills.get_by_id("sid1")
18
+ c.skills.get_by_name("s1", "p1")
19
+
20
+ assert calls[0] == ("POST", "/skills/", None, {"name": "s1"})
21
+ assert calls[1] == ("GET", "/skills/", {"projectID": "p1", "limit": 2}, None)
22
+ assert calls[2] == ("GET", "/skills/category", {"projectId": "p1", "category": "LLM", "limit": 1}, None)
23
+ assert calls[3] == ("GET", "/skills/sid1", None, None)
24
+ assert calls[4] == ("GET", "/skills/", {"name": "s1", "projectID": "p1"}, None)