bookivox 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.
@@ -0,0 +1,15 @@
1
+ # Python build/runtime artifacts
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ build/
6
+ dist/
7
+ .venv/
8
+
9
+ # Node build artifacts
10
+ node_modules/
11
+ typescript/dist/
12
+
13
+ # Local SDK build outputs
14
+ *.whl
15
+ *.tgz
bookivox-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Bookivox
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,164 @@
1
+ Metadata-Version: 2.5
2
+ Name: bookivox
3
+ Version: 0.1.0
4
+ Summary: Official Python SDK and CLI for the Bookivox API
5
+ Project-URL: Homepage, https://bookivox.com
6
+ Project-URL: Documentation, https://docs.bookivox.com
7
+ Project-URL: Repository, https://github.com/limitless-influence-ai/bookivox-sdk
8
+ Project-URL: Issues, https://github.com/limitless-influence-ai/bookivox-sdk/issues
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: ai,bookivox,sdk,telephony,voice,workflows
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Typing :: Typed
15
+ Requires-Python: >=3.11
16
+ Requires-Dist: httpx<1,>=0.27
17
+ Provides-Extra: dev
18
+ Requires-Dist: mypy>=1.10; extra == 'dev'
19
+ Requires-Dist: pytest>=8; extra == 'dev'
20
+ Requires-Dist: ruff>=0.5; extra == 'dev'
21
+ Description-Content-Type: text/markdown
22
+
23
+ # Bookivox Python SDK
24
+
25
+ Official Python client **and CLI** for the [Bookivox](https://bookivox.com) API:
26
+ typed access to agents, node types, tools, knowledge-base documents, recordings,
27
+ credentials and test calls.
28
+
29
+ - **Typed** — generated `TypedDict` models and typed method signatures (`py.typed`).
30
+ - **Safe by default** — timeouts, retries on idempotent verbs only, typed errors, no secret logging.
31
+ - **One install** — `pip install bookivox` gives you both the SDK and the `bookivox` CLI.
32
+ - **Single runtime dependency** — `httpx`.
33
+
34
+ ## Requirements
35
+
36
+ - Python **3.11 or newer**.
37
+ - A Bookivox API key (`bookeys_sk-...`), created in
38
+ [API keys](https://docs.bookivox.com/workspace/api-keys).
39
+
40
+ ## Install
41
+
42
+ ```bash
43
+ python3 -m venv .venv
44
+ source .venv/bin/activate # Windows: .venv\Scripts\Activate.ps1
45
+ pip install bookivox
46
+ ```
47
+
48
+ ```bash
49
+ uv add bookivox # or: poetry add bookivox
50
+ ```
51
+
52
+ Verify the installation:
53
+
54
+ ```bash
55
+ python -c "import bookivox_sdk; print(bookivox_sdk.__version__)"
56
+ bookivox --version
57
+ ```
58
+
59
+ ## Authenticate
60
+
61
+ The API key is read from the `api_key` argument, then from `BOOKIVOX_API_KEY`:
62
+
63
+ ```bash
64
+ export BOOKIVOX_API_KEY="bookeys_sk-..."
65
+ ```
66
+
67
+ ```python
68
+ import os
69
+ from bookivox_sdk import Bookivox
70
+
71
+ client = Bookivox(
72
+ api_key=os.environ["BOOKIVOX_API_KEY"], # or omit to use the env var
73
+ timeout=30.0,
74
+ max_retries=2, # idempotent requests only
75
+ )
76
+ ```
77
+
78
+ | Parameter | Env var | Default |
79
+ | --- | --- | --- |
80
+ | `api_key` | `BOOKIVOX_API_KEY` | — (required) |
81
+ | `timeout` | — | `30.0` |
82
+ | `max_retries` | — | `2` |
83
+
84
+ The API origin is `https://api.bookivox.com` and is not configurable.
85
+
86
+ ## Quick start
87
+
88
+ ```python
89
+ import os
90
+ from bookivox_sdk import Bookivox
91
+
92
+ with Bookivox(api_key=os.environ["BOOKIVOX_API_KEY"]) as client:
93
+ for workflow in client.list_workflows():
94
+ print(workflow["id"], workflow.get("name"))
95
+ ```
96
+
97
+ `Bookivox` is a context manager: `with` closes the underlying connection pool.
98
+
99
+ ## Methods
100
+
101
+ | Method | HTTP | Description |
102
+ | --- | --- | --- |
103
+ | `list_workflows(*, status=None)` | `GET /workflow/fetch` | List the organization's agents |
104
+ | `get_workflow(workflow_id)` | `GET /workflow/fetch/{id}` | Fetch one agent |
105
+ | `create_workflow(body)` | `POST /workflow/create/definition` | Create an agent |
106
+ | `update_workflow(workflow_id, body)` | `PUT /workflow/{id}` | Update an agent |
107
+ | `list_node_types()` | `GET /node-types` | List node types and their specs |
108
+ | `get_node_type(name)` | `GET /node-types/{name}` | Fetch one node type spec |
109
+ | `list_tools(*, status=None, category=None)` | `GET /tools/` | List tools |
110
+ | `create_tool(body)` | `POST /tools/` | Create a tool |
111
+ | `list_documents(*, status=None, limit=None, offset=None)` | `GET /knowledge-base/documents` | List knowledge-base documents |
112
+ | `list_recordings(*, workflow_id=None, ...)` | `GET /workflow-recordings/` | List recordings |
113
+ | `list_credentials()` | `GET /credentials/` | List credentials |
114
+ | `test_phone_call(body)` | `POST /telephony/initiate-call` | Start a test call (**billable**) |
115
+
116
+ ## Errors
117
+
118
+ ```python
119
+ from bookivox_sdk import (
120
+ Bookivox,
121
+ AuthenticationError,
122
+ NotFoundError,
123
+ RateLimitError,
124
+ ValidationError,
125
+ )
126
+
127
+ try:
128
+ with Bookivox() as client:
129
+ client.get_workflow("wf_123")
130
+ except AuthenticationError:
131
+ ... # 401 — invalid or revoked key
132
+ except NotFoundError:
133
+ ... # 404 — unknown agent, or outside your organization
134
+ except ValidationError as exc:
135
+ print(exc.status_code, exc.body)
136
+ except RateLimitError as exc:
137
+ print("retry in", exc.retry_after, "s")
138
+ ```
139
+
140
+ Every `APIStatusError` exposes `status_code`, `request_id` and `body`.
141
+
142
+ ## CLI
143
+
144
+ ```bash
145
+ bookivox login --api-key "$BOOKIVOX_API_KEY"
146
+ bookivox config
147
+ bookivox workflows list --json
148
+ ```
149
+
150
+ Exit codes: `0` ok, `1` error, `2` usage, `3` auth, `4` not found,
151
+ `5` rate limit, `6` connection.
152
+
153
+ ## Security
154
+
155
+ - Never commit `.env` files; load the key from your platform's secret manager.
156
+ - `test_phone_call` triggers a **real, billable phone call**.
157
+
158
+ ## Generated code
159
+
160
+ `src/bookivox_sdk/models.py` and `src/bookivox_sdk/_generated.py` are generated
161
+ from the API OpenAPI schema and must never be edited by hand. Regenerate them
162
+ with `./generate_sdk.sh` from the repository root.
163
+
164
+ Full documentation: <https://docs.bookivox.com/sdk/overview>.
@@ -0,0 +1,142 @@
1
+ # Bookivox Python SDK
2
+
3
+ Official Python client **and CLI** for the [Bookivox](https://bookivox.com) API:
4
+ typed access to agents, node types, tools, knowledge-base documents, recordings,
5
+ credentials and test calls.
6
+
7
+ - **Typed** — generated `TypedDict` models and typed method signatures (`py.typed`).
8
+ - **Safe by default** — timeouts, retries on idempotent verbs only, typed errors, no secret logging.
9
+ - **One install** — `pip install bookivox` gives you both the SDK and the `bookivox` CLI.
10
+ - **Single runtime dependency** — `httpx`.
11
+
12
+ ## Requirements
13
+
14
+ - Python **3.11 or newer**.
15
+ - A Bookivox API key (`bookeys_sk-...`), created in
16
+ [API keys](https://docs.bookivox.com/workspace/api-keys).
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ python3 -m venv .venv
22
+ source .venv/bin/activate # Windows: .venv\Scripts\Activate.ps1
23
+ pip install bookivox
24
+ ```
25
+
26
+ ```bash
27
+ uv add bookivox # or: poetry add bookivox
28
+ ```
29
+
30
+ Verify the installation:
31
+
32
+ ```bash
33
+ python -c "import bookivox_sdk; print(bookivox_sdk.__version__)"
34
+ bookivox --version
35
+ ```
36
+
37
+ ## Authenticate
38
+
39
+ The API key is read from the `api_key` argument, then from `BOOKIVOX_API_KEY`:
40
+
41
+ ```bash
42
+ export BOOKIVOX_API_KEY="bookeys_sk-..."
43
+ ```
44
+
45
+ ```python
46
+ import os
47
+ from bookivox_sdk import Bookivox
48
+
49
+ client = Bookivox(
50
+ api_key=os.environ["BOOKIVOX_API_KEY"], # or omit to use the env var
51
+ timeout=30.0,
52
+ max_retries=2, # idempotent requests only
53
+ )
54
+ ```
55
+
56
+ | Parameter | Env var | Default |
57
+ | --- | --- | --- |
58
+ | `api_key` | `BOOKIVOX_API_KEY` | — (required) |
59
+ | `timeout` | — | `30.0` |
60
+ | `max_retries` | — | `2` |
61
+
62
+ The API origin is `https://api.bookivox.com` and is not configurable.
63
+
64
+ ## Quick start
65
+
66
+ ```python
67
+ import os
68
+ from bookivox_sdk import Bookivox
69
+
70
+ with Bookivox(api_key=os.environ["BOOKIVOX_API_KEY"]) as client:
71
+ for workflow in client.list_workflows():
72
+ print(workflow["id"], workflow.get("name"))
73
+ ```
74
+
75
+ `Bookivox` is a context manager: `with` closes the underlying connection pool.
76
+
77
+ ## Methods
78
+
79
+ | Method | HTTP | Description |
80
+ | --- | --- | --- |
81
+ | `list_workflows(*, status=None)` | `GET /workflow/fetch` | List the organization's agents |
82
+ | `get_workflow(workflow_id)` | `GET /workflow/fetch/{id}` | Fetch one agent |
83
+ | `create_workflow(body)` | `POST /workflow/create/definition` | Create an agent |
84
+ | `update_workflow(workflow_id, body)` | `PUT /workflow/{id}` | Update an agent |
85
+ | `list_node_types()` | `GET /node-types` | List node types and their specs |
86
+ | `get_node_type(name)` | `GET /node-types/{name}` | Fetch one node type spec |
87
+ | `list_tools(*, status=None, category=None)` | `GET /tools/` | List tools |
88
+ | `create_tool(body)` | `POST /tools/` | Create a tool |
89
+ | `list_documents(*, status=None, limit=None, offset=None)` | `GET /knowledge-base/documents` | List knowledge-base documents |
90
+ | `list_recordings(*, workflow_id=None, ...)` | `GET /workflow-recordings/` | List recordings |
91
+ | `list_credentials()` | `GET /credentials/` | List credentials |
92
+ | `test_phone_call(body)` | `POST /telephony/initiate-call` | Start a test call (**billable**) |
93
+
94
+ ## Errors
95
+
96
+ ```python
97
+ from bookivox_sdk import (
98
+ Bookivox,
99
+ AuthenticationError,
100
+ NotFoundError,
101
+ RateLimitError,
102
+ ValidationError,
103
+ )
104
+
105
+ try:
106
+ with Bookivox() as client:
107
+ client.get_workflow("wf_123")
108
+ except AuthenticationError:
109
+ ... # 401 — invalid or revoked key
110
+ except NotFoundError:
111
+ ... # 404 — unknown agent, or outside your organization
112
+ except ValidationError as exc:
113
+ print(exc.status_code, exc.body)
114
+ except RateLimitError as exc:
115
+ print("retry in", exc.retry_after, "s")
116
+ ```
117
+
118
+ Every `APIStatusError` exposes `status_code`, `request_id` and `body`.
119
+
120
+ ## CLI
121
+
122
+ ```bash
123
+ bookivox login --api-key "$BOOKIVOX_API_KEY"
124
+ bookivox config
125
+ bookivox workflows list --json
126
+ ```
127
+
128
+ Exit codes: `0` ok, `1` error, `2` usage, `3` auth, `4` not found,
129
+ `5` rate limit, `6` connection.
130
+
131
+ ## Security
132
+
133
+ - Never commit `.env` files; load the key from your platform's secret manager.
134
+ - `test_phone_call` triggers a **real, billable phone call**.
135
+
136
+ ## Generated code
137
+
138
+ `src/bookivox_sdk/models.py` and `src/bookivox_sdk/_generated.py` are generated
139
+ from the API OpenAPI schema and must never be edited by hand. Regenerate them
140
+ with `./generate_sdk.sh` from the repository root.
141
+
142
+ Full documentation: <https://docs.bookivox.com/sdk/overview>.
@@ -0,0 +1,49 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.24"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "bookivox"
7
+ version = "0.1.0"
8
+ description = "Official Python SDK and CLI for the Bookivox API"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = { text = "MIT" }
12
+ keywords = ["bookivox", "voice", "ai", "sdk", "workflows", "telephony"]
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3",
15
+ "Programming Language :: Python :: 3 :: Only",
16
+ "Typing :: Typed",
17
+ ]
18
+ dependencies = ["httpx>=0.27,<1"]
19
+
20
+ [project.optional-dependencies]
21
+ dev = ["pytest>=8", "mypy>=1.10", "ruff>=0.5"]
22
+
23
+ [project.urls]
24
+ Homepage = "https://bookivox.com"
25
+ Documentation = "https://docs.bookivox.com"
26
+ Repository = "https://github.com/limitless-influence-ai/bookivox-sdk"
27
+ Issues = "https://github.com/limitless-influence-ai/bookivox-sdk/issues"
28
+
29
+ [project.scripts]
30
+ bookivox = "bookivox_sdk.cli:main"
31
+
32
+ [tool.hatch.build.targets.wheel]
33
+ packages = ["src/bookivox_sdk"]
34
+
35
+ [tool.hatch.build.targets.wheel.force-include]
36
+ "src/bookivox_sdk/py.typed" = "bookivox_sdk/py.typed"
37
+
38
+ [tool.mypy]
39
+ python_version = "3.11"
40
+ strict = true
41
+ files = ["src"]
42
+
43
+ [tool.ruff]
44
+ line-length = 100
45
+ target-version = "py311"
46
+
47
+ [tool.ruff.lint]
48
+ select = ["E", "F", "I", "UP", "B", "S", "SIM"]
49
+ ignore = ["S101"]
@@ -0,0 +1,43 @@
1
+ """Bookivox Python SDK."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ._generated import GeneratedMethods
6
+ from .client import DEFAULT_BASE_URL, Bookivox
7
+ from .errors import (
8
+ APIConnectionError,
9
+ APIStatusError,
10
+ APITimeoutError,
11
+ AuthenticationError,
12
+ BadRequestError,
13
+ BookivoxError,
14
+ ConflictError,
15
+ NotFoundError,
16
+ PermissionDeniedError,
17
+ RateLimitError,
18
+ ServerError,
19
+ ValidationError,
20
+ )
21
+ from .models import * # noqa: F401,F403
22
+ from .models import __all__ as _model_exports
23
+
24
+ __version__ = "0.1.0"
25
+
26
+ __all__ = [
27
+ "Bookivox",
28
+ "GeneratedMethods",
29
+ "DEFAULT_BASE_URL",
30
+ "BookivoxError",
31
+ "APIConnectionError",
32
+ "APITimeoutError",
33
+ "APIStatusError",
34
+ "BadRequestError",
35
+ "AuthenticationError",
36
+ "PermissionDeniedError",
37
+ "NotFoundError",
38
+ "ConflictError",
39
+ "ValidationError",
40
+ "RateLimitError",
41
+ "ServerError",
42
+ *_model_exports,
43
+ ]
@@ -0,0 +1,121 @@
1
+ # AUTO-GENERATED by sdk/generate_sdk.py — DO NOT EDIT.
2
+ # Run `sdk/generate_sdk.sh` to refresh from the live OpenAPI schema.
3
+
4
+ """Typed client methods for the Bookivox API (generated)."""
5
+
6
+ from __future__ import annotations
7
+
8
+ from typing import Any
9
+ from urllib.parse import quote
10
+
11
+ from .models import * # noqa: F401,F403
12
+
13
+
14
+ class GeneratedMethods:
15
+ """HTTP methods generated from the OpenAPI `x-sdk-method` tags."""
16
+
17
+ def create_tool(self, body: CreateToolRequest) -> ToolResponse:
18
+ """Create a reusable tool for the authenticated organization."""
19
+ return self._request(
20
+ "POST",
21
+ "/api/v1/tools/",
22
+ json_body=body,
23
+ )
24
+
25
+ def create_workflow(self, body: CreateWorkflowRequest) -> WorkflowResponse:
26
+ """Create a new workflow from a workflow definition."""
27
+ return self._request(
28
+ "POST",
29
+ "/api/v1/workflow/create/definition",
30
+ json_body=body,
31
+ )
32
+
33
+ def get_node_type(self, name: str) -> NodeSpec:
34
+ """Fetch a single node spec by name."""
35
+ return self._request(
36
+ "GET",
37
+ f"/api/v1/node-types/{quote(str(name), safe='')}",
38
+ )
39
+
40
+ def get_workflow(self, workflow_id: str) -> WorkflowResponse:
41
+ """Get a single workflow by ID (returns draft if one exists, else published)."""
42
+ return self._request(
43
+ "GET",
44
+ f"/api/v1/workflow/fetch/{quote(str(workflow_id), safe='')}",
45
+ )
46
+
47
+ def list_credentials(self) -> list[CredentialResponse]:
48
+ """List webhook credentials available to the authenticated organization."""
49
+ return self._request(
50
+ "GET",
51
+ "/api/v1/credentials/",
52
+ )
53
+
54
+ def list_documents(self, *, status: str | None = None, limit: int | None = None, offset: int | None = None) -> DocumentListResponseSchema:
55
+ """List knowledge base documents available to the authenticated organization."""
56
+ return self._request(
57
+ "GET",
58
+ "/api/v1/knowledge-base/documents",
59
+ params={
60
+ "status": status,
61
+ "limit": limit,
62
+ "offset": offset,
63
+ },
64
+ )
65
+
66
+ def list_node_types(self) -> NodeTypesResponse:
67
+ """List every registered node type with its spec. Pinned to spec_version."""
68
+ return self._request(
69
+ "GET",
70
+ "/api/v1/node-types",
71
+ )
72
+
73
+ def list_recordings(self, *, workflow_id: int | None = None, tts_provider: str | None = None, tts_model: str | None = None, tts_voice_id: str | None = None) -> RecordingListResponseSchema:
74
+ """List workflow recordings available to the authenticated organization."""
75
+ return self._request(
76
+ "GET",
77
+ "/api/v1/workflow-recordings/",
78
+ params={
79
+ "workflow_id": workflow_id,
80
+ "tts_provider": tts_provider,
81
+ "tts_model": tts_model,
82
+ "tts_voice_id": tts_voice_id,
83
+ },
84
+ )
85
+
86
+ def list_tools(self, *, status: str | None = None, category: str | None = None) -> list[ToolResponse]:
87
+ """List tools available to the authenticated organization."""
88
+ return self._request(
89
+ "GET",
90
+ "/api/v1/tools/",
91
+ params={
92
+ "status": status,
93
+ "category": category,
94
+ },
95
+ )
96
+
97
+ def list_workflows(self, *, status: str | None = None) -> list[WorkflowListResponse]:
98
+ """List all workflows in the authenticated organization."""
99
+ return self._request(
100
+ "GET",
101
+ "/api/v1/workflow/fetch",
102
+ params={
103
+ "status": status,
104
+ },
105
+ )
106
+
107
+ def test_phone_call(self, body: InitiateCallRequest) -> InitiateCallResponse:
108
+ """Place a test call from a workflow to a phone number."""
109
+ return self._request(
110
+ "POST",
111
+ "/api/v1/telephony/initiate-call",
112
+ json_body=body,
113
+ )
114
+
115
+ def update_workflow(self, workflow_id: str, body: UpdateWorkflowRequest) -> WorkflowResponse:
116
+ """Update a workflow's name and/or definition. Saves as a new draft."""
117
+ return self._request(
118
+ "PUT",
119
+ f"/api/v1/workflow/{quote(str(workflow_id), safe='')}",
120
+ json_body=body,
121
+ )