Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.32.0"
".": "0.32.1"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 61
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/mixedbread%2Fmixedbread-34b8fc657696023cc3a74eee6febe0d2fc0decda668f874bfa42abe6222d8566.yml
openapi_spec_hash: dcd015b362c3fcb4ef449606a8027873
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/mixedbread%2Fmixedbread-2b47fdec8c177fb55b563457ef8e3e972177a8d395a341b77112a26909e98d43.yml
openapi_spec_hash: d818396c05166e73b409c28893e790b7
config_hash: 2de40c343cf7b242d5925e3405ee8908
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 0.32.1 (2025-10-01)

Full Changelog: [v0.32.0...v0.32.1](https://github.com/mixedbread-ai/mixedbread-python/compare/v0.32.0...v0.32.1)

### Chores

* add the stores helper functions ([153269e](https://github.com/mixedbread-ai/mixedbread-python/commit/153269ec4c3f5ae1d4d7353d592b1a6bdcc58b01))

## 0.32.0 (2025-10-01)

Full Changelog: [v0.31.0...v0.32.0](https://github.com/mixedbread-ai/mixedbread-python/compare/v0.31.0...v0.32.0)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "mixedbread"
version = "0.32.0"
version = "0.32.1"
description = "The official Python library for the Mixedbread API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion src/mixedbread/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "mixedbread"
__version__ = "0.32.0" # x-release-please-version
__version__ = "0.32.1" # x-release-please-version
222 changes: 220 additions & 2 deletions src/mixedbread/resources/stores/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

from __future__ import annotations

from typing import List, Union, Iterable, Optional
import functools
from typing import Any, List, Union, Iterable, Optional

import httpx

from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
from ...lib import polling
from ..._types import Body, FileTypes, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
from ..._utils import maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
Expand Down Expand Up @@ -340,6 +342,112 @@ def search(
cast_to=FileSearchResponse,
)

def poll(
self,
file_id: str,
*,
store_identifier: str,
poll_interval_ms: int | NotGiven = not_given,
poll_timeout_ms: float | NotGiven = not_given,
**kwargs: Any,
) -> StoreFile:
"""
Poll for a file's status until it reaches a terminal state.
Args:
file_id: The ID of the file to poll
store_identifier: The ID of the store
poll_interval_ms: The interval between polls in milliseconds
poll_timeout_ms: The maximum time to poll for in milliseconds
Returns:
The file object once it reaches a terminal state
"""
polling_interval_ms = poll_interval_ms or 500
polling_timeout_ms = poll_timeout_ms or None
return polling.poll(
fn=functools.partial(self.retrieve, file_id, store_identifier=store_identifier, **kwargs),
condition=lambda res: res.status == "completed" or res.status == "failed" or res.status == "cancelled",
interval_seconds=polling_interval_ms / 1000,
timeout_seconds=polling_timeout_ms / 1000 if polling_timeout_ms else None,
)

def create_and_poll(
self,
file_id: str,
*,
store_identifier: str,
metadata: Optional[object] | NotGiven = not_given,
experimental: file_create_params.Experimental | Omit = omit,
poll_interval_ms: int | NotGiven = not_given,
poll_timeout_ms: float | NotGiven = not_given,
**kwargs: Any,
) -> StoreFile:
"""
Attach a file to the given store and wait for it to be processed.
Args:
file_id: The ID of the file to poll
store_identifier: The ID of the store
metadata: The metadata to attach to the file
poll_interval_ms: The interval between polls in milliseconds
poll_timeout_ms: The maximum time to poll for in milliseconds
Returns:
The file object once it reaches a terminal state
"""
self.create(
store_identifier=store_identifier, file_id=file_id, metadata=metadata, experimental=experimental, **kwargs
)
return self.poll(
file_id,
store_identifier=store_identifier,
poll_interval_ms=poll_interval_ms,
poll_timeout_ms=poll_timeout_ms,
**kwargs,
)

def upload(
self,
*,
store_identifier: str,
file: FileTypes,
metadata: Optional[object] | Omit = omit,
experimental: file_create_params.Experimental | Omit = omit,
**kwargs: Any,
) -> StoreFile:
"""Upload a file to the `files` API and then attach it to the given store.
Note the file will be asynchronously processed (you can use the alternative
polling helper method to wait for processing to complete).
"""
file_obj = self._client.files.create(file=file, **kwargs)
return self.create(
store_identifier=store_identifier,
file_id=file_obj.id,
metadata=metadata,
experimental=experimental,
**kwargs,
)

def upload_and_poll(
self,
*,
store_identifier: str,
file: FileTypes,
metadata: Optional[object] | NotGiven = not_given,
experimental: file_create_params.Experimental | Omit = omit,
poll_interval_ms: int | NotGiven = not_given,
poll_timeout_ms: float | NotGiven = not_given,
**kwargs: Any,
) -> StoreFile:
"""Add a file to a store and poll until processing is complete."""
file_obj = self._client.files.create(file=file, **kwargs)
return self.create_and_poll(
store_identifier=store_identifier,
file_id=file_obj.id,
metadata=metadata,
experimental=experimental,
poll_interval_ms=poll_interval_ms,
poll_timeout_ms=poll_timeout_ms,
**kwargs,
)


class AsyncFilesResource(AsyncAPIResource):
@cached_property
Expand Down Expand Up @@ -656,6 +764,116 @@ async def search(
cast_to=FileSearchResponse,
)

async def poll(
self,
file_id: str,
*,
store_identifier: str,
poll_interval_ms: int | NotGiven = not_given,
poll_timeout_ms: float | NotGiven = not_given,
**kwargs: Any,
) -> StoreFile:
"""
Poll for a file's status until it reaches a terminal state.
Args:
file_id: The ID of the file to poll
store_identifier: The ID of the store
poll_interval_ms: The interval between polls in milliseconds
poll_timeout_ms: The maximum time to poll for in milliseconds
Returns:
The file object once it reaches a terminal state
"""
polling_interval_ms = poll_interval_ms or 500
polling_timeout_ms = poll_timeout_ms or None
return await polling.poll_async(
fn=functools.partial(self.retrieve, file_id, store_identifier=store_identifier, **kwargs),
condition=lambda res: res.status == "completed" or res.status == "failed" or res.status == "cancelled",
interval_seconds=polling_interval_ms / 1000,
timeout_seconds=polling_timeout_ms / 1000 if polling_timeout_ms else None,
)

async def create_and_poll(
self,
file_id: str,
*,
store_identifier: str,
metadata: Optional[object] | NotGiven = not_given,
experimental: file_create_params.Experimental | Omit = omit,
poll_interval_ms: int | NotGiven = not_given,
poll_timeout_ms: float | NotGiven = not_given,
**kwargs: Any,
) -> StoreFile:
"""
Attach a file to the given vector store and wait for it to be processed.
Args:
file_id: The ID of the file to poll
store_identifier: The ID of the store
metadata: The metadata to attach to the file
poll_interval_ms: The interval between polls in milliseconds
poll_timeout_ms: The maximum time to poll for in milliseconds
Returns:
The file object once it reaches a terminal state
"""
await self.create(
store_identifier=store_identifier,
file_id=file_id,
metadata=metadata,
experimental=experimental,
**kwargs,
)
return await self.poll(
file_id,
store_identifier=store_identifier,
poll_interval_ms=poll_interval_ms,
poll_timeout_ms=poll_timeout_ms,
**kwargs,
)

async def upload(
self,
*,
store_identifier: str,
file: FileTypes,
metadata: Optional[object] | NotGiven = not_given,
experimental: file_create_params.Experimental | Omit = omit,
**kwargs: Any,
) -> StoreFile:
"""Upload a file to the `files` API and then attach it to the given vector store.
Note the file will be asynchronously processed (you can use the alternative
polling helper method to wait for processing to complete).
"""
file_obj = await self._client.files.create(file=file, **kwargs)
return await self.create(
store_identifier=store_identifier,
file_id=file_obj.id,
metadata=metadata,
experimental=experimental,
**kwargs,
)

async def upload_and_poll(
self,
*,
store_identifier: str,
file: FileTypes,
metadata: Optional[object] | NotGiven = not_given,
experimental: file_create_params.Experimental | Omit = omit,
poll_interval_ms: int | NotGiven = not_given,
poll_timeout_ms: float | NotGiven = not_given,
**kwargs: Any,
) -> StoreFile:
"""Add a file to a store and poll until processing is complete."""
file_obj = await self._client.files.create(file=file, **kwargs)
return await self.create_and_poll(
store_identifier=store_identifier,
file_id=file_obj.id,
metadata=metadata,
experimental=experimental,
poll_interval_ms=poll_interval_ms,
poll_timeout_ms=poll_timeout_ms,
**kwargs,
)


class FilesResourceWithRawResponse:
def __init__(self, files: FilesResource) -> None:
Expand Down
Loading