Skip to content

Commit 1d8a32b

Browse files
release: 0.3.0 (#42)
Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
1 parent 128dcbd commit 1d8a32b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+3948
-225
lines changed

.devcontainer/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ USER vscode
66
RUN curl -sSf https://rye.astral.sh/get | RYE_VERSION="0.35.0" RYE_INSTALL_OPTION="--yes" bash
77
ENV PATH=/home/vscode/.rye/shims:$PATH
88

9-
RUN echo "[[ -d .venv ]] && source .venv/bin/activate" >> /home/vscode/.bashrc
9+
RUN echo "[[ -d .venv ]] && source .venv/bin/activate || export PATH=\$PATH" >> /home/vscode/.bashrc

.devcontainer/devcontainer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
}
2525
}
2626
}
27+
},
28+
"features": {
29+
"ghcr.io/devcontainers/features/node:1": {}
2730
}
2831

2932
// Features to add to the dev container. More info: https://containers.dev/features.

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.2.0"
2+
".": "0.3.0"
33
}

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
configured_endpoints: 35
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/contextual-ai%2Fsunrise-d79ccb778953ad5c2ae4b99115429c8b3f68b3b23d9b6d90b1b40393f11a4383.yml
1+
configured_endpoints: 46
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/contextual-ai%2Fsunrise-5298551c424bb999f258bdd6c311e96c80c70701ad59bbce19b46c788ee13bd4.yml

CHANGELOG.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,30 @@
11
# Changelog
22

3+
## 0.3.0 (2025-02-26)
4+
5+
Full Changelog: [v0.2.0...v0.3.0](https://github.com/ContextualAI/contextual-client-python/compare/v0.2.0...v0.3.0)
6+
7+
### Features
8+
9+
* **api:** update via SDK Studio ([#41](https://github.com/ContextualAI/contextual-client-python/issues/41)) ([4b3ea42](https://github.com/ContextualAI/contextual-client-python/commit/4b3ea42dd9effb3cec4fb078800ca96dc3609617))
10+
* **api:** update via SDK Studio ([#49](https://github.com/ContextualAI/contextual-client-python/issues/49)) ([d54defd](https://github.com/ContextualAI/contextual-client-python/commit/d54defd3a23a488c24cae38bedd86d5721d8a71b))
11+
* **api:** update via SDK Studio ([#50](https://github.com/ContextualAI/contextual-client-python/issues/50)) ([6060be1](https://github.com/ContextualAI/contextual-client-python/commit/6060be19c881d87e5ab7b63bc60f536a6b9e70cc))
12+
* **client:** allow passing `NotGiven` for body ([#46](https://github.com/ContextualAI/contextual-client-python/issues/46)) ([4e2264d](https://github.com/ContextualAI/contextual-client-python/commit/4e2264da0b35d4dcfbf33a77950f0f7d57f1db14))
13+
14+
15+
### Bug Fixes
16+
17+
* asyncify on non-asyncio runtimes ([#44](https://github.com/ContextualAI/contextual-client-python/issues/44)) ([3a16763](https://github.com/ContextualAI/contextual-client-python/commit/3a16763381747ee6ccf829fb535927446634d54c))
18+
* **client:** mark some request bodies as optional ([4e2264d](https://github.com/ContextualAI/contextual-client-python/commit/4e2264da0b35d4dcfbf33a77950f0f7d57f1db14))
19+
20+
21+
### Chores
22+
23+
* **internal:** codegen related update ([#45](https://github.com/ContextualAI/contextual-client-python/issues/45)) ([2651383](https://github.com/ContextualAI/contextual-client-python/commit/26513832dc75629f229493f4718e97a34588fd97))
24+
* **internal:** fix devcontainers setup ([#47](https://github.com/ContextualAI/contextual-client-python/issues/47)) ([f5ea511](https://github.com/ContextualAI/contextual-client-python/commit/f5ea51125d954e2ef39e817c0a7bae763661c571))
25+
* **internal:** properly set __pydantic_private__ ([#48](https://github.com/ContextualAI/contextual-client-python/issues/48)) ([b49c8a0](https://github.com/ContextualAI/contextual-client-python/commit/b49c8a0b97a15495912999b97b6b754d2dcfbb4e))
26+
* **internal:** update client tests ([#43](https://github.com/ContextualAI/contextual-client-python/issues/43)) ([ee164e9](https://github.com/ContextualAI/contextual-client-python/commit/ee164e9e3a7f15570560922d383565ea4a50d446))
27+
328
## 0.2.0 (2025-02-08)
429

530
Full Changelog: [v0.1.0...v0.2.0](https://github.com/ContextualAI/contextual-client-python/compare/v0.1.0...v0.2.0)

README.md

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ client = ContextualAI(
3030
)
3131

3232
create_agent_output = client.agents.create(
33-
name="xxx",
33+
name="Example",
3434
)
3535
print(create_agent_output.id)
3636
```
@@ -56,7 +56,7 @@ client = AsyncContextualAI(
5656

5757
async def main() -> None:
5858
create_agent_output = await client.agents.create(
59-
name="xxx",
59+
name="Example",
6060
)
6161
print(create_agent_output.id)
6262

@@ -138,6 +138,24 @@ for agent in first_page.agents:
138138
# Remove `await` for non-async usage.
139139
```
140140

141+
## File uploads
142+
143+
Request parameters that correspond to file uploads can be passed as `bytes`, a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance or a tuple of `(filename, contents, media type)`.
144+
145+
```python
146+
from pathlib import Path
147+
from contextual import ContextualAI
148+
149+
client = ContextualAI()
150+
151+
client.datastores.documents.ingest(
152+
datastore_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
153+
file=Path("/path/to/file"),
154+
)
155+
```
156+
157+
The async client uses the exact same interface. If you pass a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance, the file contents will be read asynchronously automatically.
158+
141159
## Handling errors
142160

143161
When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `contextual.APIConnectionError` is raised.
@@ -155,7 +173,7 @@ client = ContextualAI()
155173

156174
try:
157175
client.agents.create(
158-
name="xxx",
176+
name="Example",
159177
)
160178
except contextual.APIConnectionError as e:
161179
print("The server could not be reached")
@@ -200,7 +218,7 @@ client = ContextualAI(
200218

201219
# Or, configure per-request:
202220
client.with_options(max_retries=5).agents.create(
203-
name="xxx",
221+
name="Example",
204222
)
205223
```
206224

@@ -225,7 +243,7 @@ client = ContextualAI(
225243

226244
# Override per-request:
227245
client.with_options(timeout=5.0).agents.create(
228-
name="xxx",
246+
name="Example",
229247
)
230248
```
231249

@@ -268,7 +286,7 @@ from contextual import ContextualAI
268286

269287
client = ContextualAI()
270288
response = client.agents.with_raw_response.create(
271-
name="xxx",
289+
name="Example",
272290
)
273291
print(response.headers.get('X-My-Header'))
274292

@@ -288,7 +306,7 @@ To stream the response body, use `.with_streaming_response` instead, which requi
288306

289307
```python
290308
with client.agents.with_streaming_response.create(
291-
name="xxx",
309+
name="Example",
292310
) as response:
293311
print(response.headers.get("X-My-Header"))
294312

api.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Methods:
3838
- <code title="delete /datastores/{datastore_id}/documents/{document_id}">client.datastores.documents.<a href="./src/contextual/resources/datastores/documents.py">delete</a>(document_id, \*, datastore_id) -> <a href="./src/contextual/types/datastores/document_delete_response.py">object</a></code>
3939
- <code title="post /datastores/{datastore_id}/documents">client.datastores.documents.<a href="./src/contextual/resources/datastores/documents.py">ingest</a>(datastore_id, \*\*<a href="src/contextual/types/datastores/document_ingest_params.py">params</a>) -> <a href="./src/contextual/types/datastores/ingestion_response.py">IngestionResponse</a></code>
4040
- <code title="get /datastores/{datastore_id}/documents/{document_id}/metadata">client.datastores.documents.<a href="./src/contextual/resources/datastores/documents.py">metadata</a>(document_id, \*, datastore_id) -> <a href="./src/contextual/types/datastores/document_metadata.py">DocumentMetadata</a></code>
41+
- <code title="post /datastores/{datastore_id}/documents/{document_id}/metadata">client.datastores.documents.<a href="./src/contextual/resources/datastores/documents.py">set_metadata</a>(document_id, \*, datastore_id, \*\*<a href="src/contextual/types/datastores/document_set_metadata_params.py">params</a>) -> <a href="./src/contextual/types/datastores/document_metadata.py">DocumentMetadata</a></code>
4142

4243
# Agents
4344

@@ -120,6 +121,23 @@ Types:
120121
from contextual.types.agents import CreateDatasetResponse, DatasetMetadata, ListDatasetsResponse
121122
```
122123

124+
### Tune
125+
126+
Types:
127+
128+
```python
129+
from contextual.types.agents.datasets import TuneDeleteResponse
130+
```
131+
132+
Methods:
133+
134+
- <code title="post /agents/{agent_id}/datasets/tune">client.agents.datasets.tune.<a href="./src/contextual/resources/agents/datasets/tune.py">create</a>(agent_id, \*\*<a href="src/contextual/types/agents/datasets/tune_create_params.py">params</a>) -> <a href="./src/contextual/types/agents/create_dataset_response.py">CreateDatasetResponse</a></code>
135+
- <code title="get /agents/{agent_id}/datasets/tune/{dataset_name}">client.agents.datasets.tune.<a href="./src/contextual/resources/agents/datasets/tune.py">retrieve</a>(dataset_name, \*, agent_id, \*\*<a href="src/contextual/types/agents/datasets/tune_retrieve_params.py">params</a>) -> BinaryAPIResponse</code>
136+
- <code title="put /agents/{agent_id}/datasets/tune/{dataset_name}">client.agents.datasets.tune.<a href="./src/contextual/resources/agents/datasets/tune.py">update</a>(dataset_name, \*, agent_id, \*\*<a href="src/contextual/types/agents/datasets/tune_update_params.py">params</a>) -> <a href="./src/contextual/types/agents/create_dataset_response.py">CreateDatasetResponse</a></code>
137+
- <code title="get /agents/{agent_id}/datasets/tune">client.agents.datasets.tune.<a href="./src/contextual/resources/agents/datasets/tune.py">list</a>(agent_id, \*\*<a href="src/contextual/types/agents/datasets/tune_list_params.py">params</a>) -> <a href="./src/contextual/types/agents/list_datasets_response.py">ListDatasetsResponse</a></code>
138+
- <code title="delete /agents/{agent_id}/datasets/tune/{dataset_name}">client.agents.datasets.tune.<a href="./src/contextual/resources/agents/datasets/tune.py">delete</a>(dataset_name, \*, agent_id) -> <a href="./src/contextual/types/agents/datasets/tune_delete_response.py">object</a></code>
139+
- <code title="get /agents/{agent_id}/datasets/tune/{dataset_name}/metadata">client.agents.datasets.tune.<a href="./src/contextual/resources/agents/datasets/tune.py">metadata</a>(dataset_name, \*, agent_id, \*\*<a href="src/contextual/types/agents/datasets/tune_metadata_params.py">params</a>) -> <a href="./src/contextual/types/agents/dataset_metadata.py">DatasetMetadata</a></code>
140+
123141
### Evaluate
124142

125143
Types:
@@ -175,6 +193,27 @@ Methods:
175193

176194
- <code title="get /agents/{agent_id}/tune/models">client.agents.tune.models.<a href="./src/contextual/resources/agents/tune/models.py">list</a>(agent_id) -> <a href="./src/contextual/types/agents/tune/list_tune_models_response.py">ListTuneModelsResponse</a></code>
177195

196+
# Users
197+
198+
Types:
199+
200+
```python
201+
from contextual.types import (
202+
InviteUsersResponse,
203+
ListUsersResponse,
204+
NewUser,
205+
UserUpdateResponse,
206+
UserDeactivateResponse,
207+
)
208+
```
209+
210+
Methods:
211+
212+
- <code title="put /users">client.users.<a href="./src/contextual/resources/users.py">update</a>(\*\*<a href="src/contextual/types/user_update_params.py">params</a>) -> <a href="./src/contextual/types/user_update_response.py">object</a></code>
213+
- <code title="get /users">client.users.<a href="./src/contextual/resources/users.py">list</a>(\*\*<a href="src/contextual/types/user_list_params.py">params</a>) -> SyncUsersPage[User]</code>
214+
- <code title="delete /users">client.users.<a href="./src/contextual/resources/users.py">deactivate</a>(\*\*<a href="src/contextual/types/user_deactivate_params.py">params</a>) -> <a href="./src/contextual/types/user_deactivate_response.py">object</a></code>
215+
- <code title="post /users">client.users.<a href="./src/contextual/resources/users.py">invite</a>(\*\*<a href="src/contextual/types/user_invite_params.py">params</a>) -> <a href="./src/contextual/types/invite_users_response.py">InviteUsersResponse</a></code>
216+
178217
# LMUnit
179218

180219
Types:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "contextual-client"
3-
version = "0.2.0"
3+
version = "0.3.0"
44
description = "The official Python library for the Contextual AI API"
55
dynamic = ["readme"]
66
license = "Apache-2.0"

src/contextual/_base_client.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
ModelBuilderProtocol,
6464
)
6565
from ._utils import is_dict, is_list, asyncify, is_given, lru_cache, is_mapping
66-
from ._compat import model_copy, model_dump
66+
from ._compat import PYDANTIC_V2, model_copy, model_dump
6767
from ._models import GenericModel, FinalRequestOptions, validate_type, construct_type
6868
from ._response import (
6969
APIResponse,
@@ -207,6 +207,9 @@ def _set_private_attributes(
207207
model: Type[_T],
208208
options: FinalRequestOptions,
209209
) -> None:
210+
if PYDANTIC_V2 and getattr(self, "__pydantic_private__", None) is None:
211+
self.__pydantic_private__ = {}
212+
210213
self._model = model
211214
self._client = client
212215
self._options = options
@@ -292,6 +295,9 @@ def _set_private_attributes(
292295
client: AsyncAPIClient,
293296
options: FinalRequestOptions,
294297
) -> None:
298+
if PYDANTIC_V2 and getattr(self, "__pydantic_private__", None) is None:
299+
self.__pydantic_private__ = {}
300+
295301
self._model = model
296302
self._client = client
297303
self._options = options
@@ -518,7 +524,7 @@ def _build_request(
518524
# so that passing a `TypedDict` doesn't cause an error.
519525
# https://github.com/microsoft/pyright/issues/3526#event-6715453066
520526
params=self.qs.stringify(cast(Mapping[str, Any], params)) if params else None,
521-
json=json_data,
527+
json=json_data if is_given(json_data) else None,
522528
files=files,
523529
**kwargs,
524530
)

src/contextual/_client.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
get_async_library,
2525
)
2626
from ._version import __version__
27-
from .resources import lmunit, rerank, generate
27+
from .resources import users, lmunit, rerank, generate
2828
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
2929
from ._exceptions import APIStatusError, ContextualAIError
3030
from ._base_client import (
@@ -50,6 +50,7 @@
5050
class ContextualAI(SyncAPIClient):
5151
datastores: datastores.DatastoresResource
5252
agents: agents.AgentsResource
53+
users: users.UsersResource
5354
lmunit: lmunit.LMUnitResource
5455
rerank: rerank.RerankResource
5556
generate: generate.GenerateResource
@@ -118,6 +119,7 @@ def __init__(
118119

119120
self.datastores = datastores.DatastoresResource(self)
120121
self.agents = agents.AgentsResource(self)
122+
self.users = users.UsersResource(self)
121123
self.lmunit = lmunit.LMUnitResource(self)
122124
self.rerank = rerank.RerankResource(self)
123125
self.generate = generate.GenerateResource(self)
@@ -235,6 +237,7 @@ def _make_status_error(
235237
class AsyncContextualAI(AsyncAPIClient):
236238
datastores: datastores.AsyncDatastoresResource
237239
agents: agents.AsyncAgentsResource
240+
users: users.AsyncUsersResource
238241
lmunit: lmunit.AsyncLMUnitResource
239242
rerank: rerank.AsyncRerankResource
240243
generate: generate.AsyncGenerateResource
@@ -303,6 +306,7 @@ def __init__(
303306

304307
self.datastores = datastores.AsyncDatastoresResource(self)
305308
self.agents = agents.AsyncAgentsResource(self)
309+
self.users = users.AsyncUsersResource(self)
306310
self.lmunit = lmunit.AsyncLMUnitResource(self)
307311
self.rerank = rerank.AsyncRerankResource(self)
308312
self.generate = generate.AsyncGenerateResource(self)
@@ -421,6 +425,7 @@ class ContextualAIWithRawResponse:
421425
def __init__(self, client: ContextualAI) -> None:
422426
self.datastores = datastores.DatastoresResourceWithRawResponse(client.datastores)
423427
self.agents = agents.AgentsResourceWithRawResponse(client.agents)
428+
self.users = users.UsersResourceWithRawResponse(client.users)
424429
self.lmunit = lmunit.LMUnitResourceWithRawResponse(client.lmunit)
425430
self.rerank = rerank.RerankResourceWithRawResponse(client.rerank)
426431
self.generate = generate.GenerateResourceWithRawResponse(client.generate)
@@ -430,6 +435,7 @@ class AsyncContextualAIWithRawResponse:
430435
def __init__(self, client: AsyncContextualAI) -> None:
431436
self.datastores = datastores.AsyncDatastoresResourceWithRawResponse(client.datastores)
432437
self.agents = agents.AsyncAgentsResourceWithRawResponse(client.agents)
438+
self.users = users.AsyncUsersResourceWithRawResponse(client.users)
433439
self.lmunit = lmunit.AsyncLMUnitResourceWithRawResponse(client.lmunit)
434440
self.rerank = rerank.AsyncRerankResourceWithRawResponse(client.rerank)
435441
self.generate = generate.AsyncGenerateResourceWithRawResponse(client.generate)
@@ -439,6 +445,7 @@ class ContextualAIWithStreamedResponse:
439445
def __init__(self, client: ContextualAI) -> None:
440446
self.datastores = datastores.DatastoresResourceWithStreamingResponse(client.datastores)
441447
self.agents = agents.AgentsResourceWithStreamingResponse(client.agents)
448+
self.users = users.UsersResourceWithStreamingResponse(client.users)
442449
self.lmunit = lmunit.LMUnitResourceWithStreamingResponse(client.lmunit)
443450
self.rerank = rerank.RerankResourceWithStreamingResponse(client.rerank)
444451
self.generate = generate.GenerateResourceWithStreamingResponse(client.generate)
@@ -448,6 +455,7 @@ class AsyncContextualAIWithStreamedResponse:
448455
def __init__(self, client: AsyncContextualAI) -> None:
449456
self.datastores = datastores.AsyncDatastoresResourceWithStreamingResponse(client.datastores)
450457
self.agents = agents.AsyncAgentsResourceWithStreamingResponse(client.agents)
458+
self.users = users.AsyncUsersResourceWithStreamingResponse(client.users)
451459
self.lmunit = lmunit.AsyncLMUnitResourceWithStreamingResponse(client.lmunit)
452460
self.rerank = rerank.AsyncRerankResourceWithStreamingResponse(client.rerank)
453461
self.generate = generate.AsyncGenerateResourceWithStreamingResponse(client.generate)

0 commit comments

Comments
 (0)