main
1# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
3from __future__ import annotations
4
5from typing import TYPE_CHECKING, Dict, Union, Optional
6from typing_extensions import Literal, assert_never
7
8import httpx
9
10from ... import _legacy_response
11from ...types import FileChunkingStrategyParam
12from ..._types import Body, Omit, Query, Headers, NotGiven, FileTypes, omit, not_given
13from ..._utils import is_given, maybe_transform, async_maybe_transform
14from ..._compat import cached_property
15from ..._resource import SyncAPIResource, AsyncAPIResource
16from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
17from ...pagination import SyncPage, AsyncPage, SyncCursorPage, AsyncCursorPage
18from ..._base_client import AsyncPaginator, make_request_options
19from ...types.vector_stores import file_list_params, file_create_params, file_update_params
20from ...types.file_chunking_strategy_param import FileChunkingStrategyParam
21from ...types.vector_stores.vector_store_file import VectorStoreFile
22from ...types.vector_stores.file_content_response import FileContentResponse
23from ...types.vector_stores.vector_store_file_deleted import VectorStoreFileDeleted
24
25__all__ = ["Files", "AsyncFiles"]
26
27
28class Files(SyncAPIResource):
29 @cached_property
30 def with_raw_response(self) -> FilesWithRawResponse:
31 """
32 This property can be used as a prefix for any HTTP method call to return
33 the raw response object instead of the parsed content.
34
35 For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
36 """
37 return FilesWithRawResponse(self)
38
39 @cached_property
40 def with_streaming_response(self) -> FilesWithStreamingResponse:
41 """
42 An alternative to `.with_raw_response` that doesn't eagerly read the response body.
43
44 For more information, see https://www.github.com/openai/openai-python#with_streaming_response
45 """
46 return FilesWithStreamingResponse(self)
47
48 def create(
49 self,
50 vector_store_id: str,
51 *,
52 file_id: str,
53 attributes: Optional[Dict[str, Union[str, float, bool]]] | Omit = omit,
54 chunking_strategy: FileChunkingStrategyParam | Omit = omit,
55 # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
56 # The extra values given here take precedence over values defined on the client or passed to this method.
57 extra_headers: Headers | None = None,
58 extra_query: Query | None = None,
59 extra_body: Body | None = None,
60 timeout: float | httpx.Timeout | None | NotGiven = not_given,
61 ) -> VectorStoreFile:
62 """
63 Create a vector store file by attaching a
64 [File](https://platform.openai.com/docs/api-reference/files) to a
65 [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object).
66
67 Args:
68 file_id: A [File](https://platform.openai.com/docs/api-reference/files) ID that the
69 vector store should use. Useful for tools like `file_search` that can access
70 files.
71
72 attributes: Set of 16 key-value pairs that can be attached to an object. This can be useful
73 for storing additional information about the object in a structured format, and
74 querying for objects via API or the dashboard. Keys are strings with a maximum
75 length of 64 characters. Values are strings with a maximum length of 512
76 characters, booleans, or numbers.
77
78 chunking_strategy: The chunking strategy used to chunk the file(s). If not set, will use the `auto`
79 strategy. Only applicable if `file_ids` is non-empty.
80
81 extra_headers: Send extra headers
82
83 extra_query: Add additional query parameters to the request
84
85 extra_body: Add additional JSON properties to the request
86
87 timeout: Override the client-level default timeout for this request, in seconds
88 """
89 if not vector_store_id:
90 raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
91 extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
92 return self._post(
93 f"/vector_stores/{vector_store_id}/files",
94 body=maybe_transform(
95 {
96 "file_id": file_id,
97 "attributes": attributes,
98 "chunking_strategy": chunking_strategy,
99 },
100 file_create_params.FileCreateParams,
101 ),
102 options=make_request_options(
103 extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
104 ),
105 cast_to=VectorStoreFile,
106 )
107
108 def retrieve(
109 self,
110 file_id: str,
111 *,
112 vector_store_id: str,
113 # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
114 # The extra values given here take precedence over values defined on the client or passed to this method.
115 extra_headers: Headers | None = None,
116 extra_query: Query | None = None,
117 extra_body: Body | None = None,
118 timeout: float | httpx.Timeout | None | NotGiven = not_given,
119 ) -> VectorStoreFile:
120 """
121 Retrieves a vector store file.
122
123 Args:
124 extra_headers: Send extra headers
125
126 extra_query: Add additional query parameters to the request
127
128 extra_body: Add additional JSON properties to the request
129
130 timeout: Override the client-level default timeout for this request, in seconds
131 """
132 if not vector_store_id:
133 raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
134 if not file_id:
135 raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
136 extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
137 return self._get(
138 f"/vector_stores/{vector_store_id}/files/{file_id}",
139 options=make_request_options(
140 extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
141 ),
142 cast_to=VectorStoreFile,
143 )
144
145 def update(
146 self,
147 file_id: str,
148 *,
149 vector_store_id: str,
150 attributes: Optional[Dict[str, Union[str, float, bool]]],
151 # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
152 # The extra values given here take precedence over values defined on the client or passed to this method.
153 extra_headers: Headers | None = None,
154 extra_query: Query | None = None,
155 extra_body: Body | None = None,
156 timeout: float | httpx.Timeout | None | NotGiven = not_given,
157 ) -> VectorStoreFile:
158 """
159 Update attributes on a vector store file.
160
161 Args:
162 attributes: Set of 16 key-value pairs that can be attached to an object. This can be useful
163 for storing additional information about the object in a structured format, and
164 querying for objects via API or the dashboard. Keys are strings with a maximum
165 length of 64 characters. Values are strings with a maximum length of 512
166 characters, booleans, or numbers.
167
168 extra_headers: Send extra headers
169
170 extra_query: Add additional query parameters to the request
171
172 extra_body: Add additional JSON properties to the request
173
174 timeout: Override the client-level default timeout for this request, in seconds
175 """
176 if not vector_store_id:
177 raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
178 if not file_id:
179 raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
180 extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
181 return self._post(
182 f"/vector_stores/{vector_store_id}/files/{file_id}",
183 body=maybe_transform({"attributes": attributes}, file_update_params.FileUpdateParams),
184 options=make_request_options(
185 extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
186 ),
187 cast_to=VectorStoreFile,
188 )
189
190 def list(
191 self,
192 vector_store_id: str,
193 *,
194 after: str | Omit = omit,
195 before: str | Omit = omit,
196 filter: Literal["in_progress", "completed", "failed", "cancelled"] | Omit = omit,
197 limit: int | Omit = omit,
198 order: Literal["asc", "desc"] | Omit = omit,
199 # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
200 # The extra values given here take precedence over values defined on the client or passed to this method.
201 extra_headers: Headers | None = None,
202 extra_query: Query | None = None,
203 extra_body: Body | None = None,
204 timeout: float | httpx.Timeout | None | NotGiven = not_given,
205 ) -> SyncCursorPage[VectorStoreFile]:
206 """
207 Returns a list of vector store files.
208
209 Args:
210 after: A cursor for use in pagination. `after` is an object ID that defines your place
211 in the list. For instance, if you make a list request and receive 100 objects,
212 ending with obj_foo, your subsequent call can include after=obj_foo in order to
213 fetch the next page of the list.
214
215 before: A cursor for use in pagination. `before` is an object ID that defines your place
216 in the list. For instance, if you make a list request and receive 100 objects,
217 starting with obj_foo, your subsequent call can include before=obj_foo in order
218 to fetch the previous page of the list.
219
220 filter: Filter by file status. One of `in_progress`, `completed`, `failed`, `cancelled`.
221
222 limit: A limit on the number of objects to be returned. Limit can range between 1 and
223 100, and the default is 20.
224
225 order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending
226 order and `desc` for descending order.
227
228 extra_headers: Send extra headers
229
230 extra_query: Add additional query parameters to the request
231
232 extra_body: Add additional JSON properties to the request
233
234 timeout: Override the client-level default timeout for this request, in seconds
235 """
236 if not vector_store_id:
237 raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
238 extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
239 return self._get_api_list(
240 f"/vector_stores/{vector_store_id}/files",
241 page=SyncCursorPage[VectorStoreFile],
242 options=make_request_options(
243 extra_headers=extra_headers,
244 extra_query=extra_query,
245 extra_body=extra_body,
246 timeout=timeout,
247 query=maybe_transform(
248 {
249 "after": after,
250 "before": before,
251 "filter": filter,
252 "limit": limit,
253 "order": order,
254 },
255 file_list_params.FileListParams,
256 ),
257 ),
258 model=VectorStoreFile,
259 )
260
261 def delete(
262 self,
263 file_id: str,
264 *,
265 vector_store_id: str,
266 # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
267 # The extra values given here take precedence over values defined on the client or passed to this method.
268 extra_headers: Headers | None = None,
269 extra_query: Query | None = None,
270 extra_body: Body | None = None,
271 timeout: float | httpx.Timeout | None | NotGiven = not_given,
272 ) -> VectorStoreFileDeleted:
273 """Delete a vector store file.
274
275 This will remove the file from the vector store but
276 the file itself will not be deleted. To delete the file, use the
277 [delete file](https://platform.openai.com/docs/api-reference/files/delete)
278 endpoint.
279
280 Args:
281 extra_headers: Send extra headers
282
283 extra_query: Add additional query parameters to the request
284
285 extra_body: Add additional JSON properties to the request
286
287 timeout: Override the client-level default timeout for this request, in seconds
288 """
289 if not vector_store_id:
290 raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
291 if not file_id:
292 raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
293 extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
294 return self._delete(
295 f"/vector_stores/{vector_store_id}/files/{file_id}",
296 options=make_request_options(
297 extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
298 ),
299 cast_to=VectorStoreFileDeleted,
300 )
301
302 def create_and_poll(
303 self,
304 file_id: str,
305 *,
306 vector_store_id: str,
307 attributes: Optional[Dict[str, Union[str, float, bool]]] | Omit = omit,
308 poll_interval_ms: int | Omit = omit,
309 chunking_strategy: FileChunkingStrategyParam | Omit = omit,
310 ) -> VectorStoreFile:
311 """Attach a file to the given vector store and wait for it to be processed."""
312 self.create(
313 vector_store_id=vector_store_id, file_id=file_id, chunking_strategy=chunking_strategy, attributes=attributes
314 )
315
316 return self.poll(
317 file_id,
318 vector_store_id=vector_store_id,
319 poll_interval_ms=poll_interval_ms,
320 )
321
322 def poll(
323 self,
324 file_id: str,
325 *,
326 vector_store_id: str,
327 poll_interval_ms: int | Omit = omit,
328 ) -> VectorStoreFile:
329 """Wait for the vector store file to finish processing.
330
331 Note: this will return even if the file failed to process, you need to check
332 file.last_error and file.status to handle these cases
333 """
334 headers: dict[str, str] = {"X-Stainless-Poll-Helper": "true"}
335 if is_given(poll_interval_ms):
336 headers["X-Stainless-Custom-Poll-Interval"] = str(poll_interval_ms)
337
338 while True:
339 response = self.with_raw_response.retrieve(
340 file_id,
341 vector_store_id=vector_store_id,
342 extra_headers=headers,
343 )
344
345 file = response.parse()
346 if file.status == "in_progress":
347 if not is_given(poll_interval_ms):
348 from_header = response.headers.get("openai-poll-after-ms")
349 if from_header is not None:
350 poll_interval_ms = int(from_header)
351 else:
352 poll_interval_ms = 1000
353
354 self._sleep(poll_interval_ms / 1000)
355 elif file.status == "cancelled" or file.status == "completed" or file.status == "failed":
356 return file
357 else:
358 if TYPE_CHECKING: # type: ignore[unreachable]
359 assert_never(file.status)
360 else:
361 return file
362
363 def upload(
364 self,
365 *,
366 vector_store_id: str,
367 file: FileTypes,
368 chunking_strategy: FileChunkingStrategyParam | Omit = omit,
369 ) -> VectorStoreFile:
370 """Upload a file to the `files` API and then attach it to the given vector store.
371
372 Note the file will be asynchronously processed (you can use the alternative
373 polling helper method to wait for processing to complete).
374 """
375 file_obj = self._client.files.create(file=file, purpose="assistants")
376 return self.create(vector_store_id=vector_store_id, file_id=file_obj.id, chunking_strategy=chunking_strategy)
377
378 def upload_and_poll(
379 self,
380 *,
381 vector_store_id: str,
382 file: FileTypes,
383 attributes: Optional[Dict[str, Union[str, float, bool]]] | Omit = omit,
384 poll_interval_ms: int | Omit = omit,
385 chunking_strategy: FileChunkingStrategyParam | Omit = omit,
386 ) -> VectorStoreFile:
387 """Add a file to a vector store and poll until processing is complete."""
388 file_obj = self._client.files.create(file=file, purpose="assistants")
389 return self.create_and_poll(
390 vector_store_id=vector_store_id,
391 file_id=file_obj.id,
392 chunking_strategy=chunking_strategy,
393 poll_interval_ms=poll_interval_ms,
394 attributes=attributes,
395 )
396
397 def content(
398 self,
399 file_id: str,
400 *,
401 vector_store_id: str,
402 # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
403 # The extra values given here take precedence over values defined on the client or passed to this method.
404 extra_headers: Headers | None = None,
405 extra_query: Query | None = None,
406 extra_body: Body | None = None,
407 timeout: float | httpx.Timeout | None | NotGiven = not_given,
408 ) -> SyncPage[FileContentResponse]:
409 """
410 Retrieve the parsed contents of a vector store file.
411
412 Args:
413 extra_headers: Send extra headers
414
415 extra_query: Add additional query parameters to the request
416
417 extra_body: Add additional JSON properties to the request
418
419 timeout: Override the client-level default timeout for this request, in seconds
420 """
421 if not vector_store_id:
422 raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
423 if not file_id:
424 raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
425 extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
426 return self._get_api_list(
427 f"/vector_stores/{vector_store_id}/files/{file_id}/content",
428 page=SyncPage[FileContentResponse],
429 options=make_request_options(
430 extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
431 ),
432 model=FileContentResponse,
433 )
434
435
436class AsyncFiles(AsyncAPIResource):
437 @cached_property
438 def with_raw_response(self) -> AsyncFilesWithRawResponse:
439 """
440 This property can be used as a prefix for any HTTP method call to return
441 the raw response object instead of the parsed content.
442
443 For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
444 """
445 return AsyncFilesWithRawResponse(self)
446
447 @cached_property
448 def with_streaming_response(self) -> AsyncFilesWithStreamingResponse:
449 """
450 An alternative to `.with_raw_response` that doesn't eagerly read the response body.
451
452 For more information, see https://www.github.com/openai/openai-python#with_streaming_response
453 """
454 return AsyncFilesWithStreamingResponse(self)
455
456 async def create(
457 self,
458 vector_store_id: str,
459 *,
460 file_id: str,
461 attributes: Optional[Dict[str, Union[str, float, bool]]] | Omit = omit,
462 chunking_strategy: FileChunkingStrategyParam | Omit = omit,
463 # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
464 # The extra values given here take precedence over values defined on the client or passed to this method.
465 extra_headers: Headers | None = None,
466 extra_query: Query | None = None,
467 extra_body: Body | None = None,
468 timeout: float | httpx.Timeout | None | NotGiven = not_given,
469 ) -> VectorStoreFile:
470 """
471 Create a vector store file by attaching a
472 [File](https://platform.openai.com/docs/api-reference/files) to a
473 [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object).
474
475 Args:
476 file_id: A [File](https://platform.openai.com/docs/api-reference/files) ID that the
477 vector store should use. Useful for tools like `file_search` that can access
478 files.
479
480 attributes: Set of 16 key-value pairs that can be attached to an object. This can be useful
481 for storing additional information about the object in a structured format, and
482 querying for objects via API or the dashboard. Keys are strings with a maximum
483 length of 64 characters. Values are strings with a maximum length of 512
484 characters, booleans, or numbers.
485
486 chunking_strategy: The chunking strategy used to chunk the file(s). If not set, will use the `auto`
487 strategy. Only applicable if `file_ids` is non-empty.
488
489 extra_headers: Send extra headers
490
491 extra_query: Add additional query parameters to the request
492
493 extra_body: Add additional JSON properties to the request
494
495 timeout: Override the client-level default timeout for this request, in seconds
496 """
497 if not vector_store_id:
498 raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
499 extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
500 return await self._post(
501 f"/vector_stores/{vector_store_id}/files",
502 body=await async_maybe_transform(
503 {
504 "file_id": file_id,
505 "attributes": attributes,
506 "chunking_strategy": chunking_strategy,
507 },
508 file_create_params.FileCreateParams,
509 ),
510 options=make_request_options(
511 extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
512 ),
513 cast_to=VectorStoreFile,
514 )
515
516 async def retrieve(
517 self,
518 file_id: str,
519 *,
520 vector_store_id: str,
521 # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
522 # The extra values given here take precedence over values defined on the client or passed to this method.
523 extra_headers: Headers | None = None,
524 extra_query: Query | None = None,
525 extra_body: Body | None = None,
526 timeout: float | httpx.Timeout | None | NotGiven = not_given,
527 ) -> VectorStoreFile:
528 """
529 Retrieves a vector store file.
530
531 Args:
532 extra_headers: Send extra headers
533
534 extra_query: Add additional query parameters to the request
535
536 extra_body: Add additional JSON properties to the request
537
538 timeout: Override the client-level default timeout for this request, in seconds
539 """
540 if not vector_store_id:
541 raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
542 if not file_id:
543 raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
544 extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
545 return await self._get(
546 f"/vector_stores/{vector_store_id}/files/{file_id}",
547 options=make_request_options(
548 extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
549 ),
550 cast_to=VectorStoreFile,
551 )
552
553 async def update(
554 self,
555 file_id: str,
556 *,
557 vector_store_id: str,
558 attributes: Optional[Dict[str, Union[str, float, bool]]],
559 # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
560 # The extra values given here take precedence over values defined on the client or passed to this method.
561 extra_headers: Headers | None = None,
562 extra_query: Query | None = None,
563 extra_body: Body | None = None,
564 timeout: float | httpx.Timeout | None | NotGiven = not_given,
565 ) -> VectorStoreFile:
566 """
567 Update attributes on a vector store file.
568
569 Args:
570 attributes: Set of 16 key-value pairs that can be attached to an object. This can be useful
571 for storing additional information about the object in a structured format, and
572 querying for objects via API or the dashboard. Keys are strings with a maximum
573 length of 64 characters. Values are strings with a maximum length of 512
574 characters, booleans, or numbers.
575
576 extra_headers: Send extra headers
577
578 extra_query: Add additional query parameters to the request
579
580 extra_body: Add additional JSON properties to the request
581
582 timeout: Override the client-level default timeout for this request, in seconds
583 """
584 if not vector_store_id:
585 raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
586 if not file_id:
587 raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
588 extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
589 return await self._post(
590 f"/vector_stores/{vector_store_id}/files/{file_id}",
591 body=await async_maybe_transform({"attributes": attributes}, file_update_params.FileUpdateParams),
592 options=make_request_options(
593 extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
594 ),
595 cast_to=VectorStoreFile,
596 )
597
598 def list(
599 self,
600 vector_store_id: str,
601 *,
602 after: str | Omit = omit,
603 before: str | Omit = omit,
604 filter: Literal["in_progress", "completed", "failed", "cancelled"] | Omit = omit,
605 limit: int | Omit = omit,
606 order: Literal["asc", "desc"] | Omit = omit,
607 # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
608 # The extra values given here take precedence over values defined on the client or passed to this method.
609 extra_headers: Headers | None = None,
610 extra_query: Query | None = None,
611 extra_body: Body | None = None,
612 timeout: float | httpx.Timeout | None | NotGiven = not_given,
613 ) -> AsyncPaginator[VectorStoreFile, AsyncCursorPage[VectorStoreFile]]:
614 """
615 Returns a list of vector store files.
616
617 Args:
618 after: A cursor for use in pagination. `after` is an object ID that defines your place
619 in the list. For instance, if you make a list request and receive 100 objects,
620 ending with obj_foo, your subsequent call can include after=obj_foo in order to
621 fetch the next page of the list.
622
623 before: A cursor for use in pagination. `before` is an object ID that defines your place
624 in the list. For instance, if you make a list request and receive 100 objects,
625 starting with obj_foo, your subsequent call can include before=obj_foo in order
626 to fetch the previous page of the list.
627
628 filter: Filter by file status. One of `in_progress`, `completed`, `failed`, `cancelled`.
629
630 limit: A limit on the number of objects to be returned. Limit can range between 1 and
631 100, and the default is 20.
632
633 order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending
634 order and `desc` for descending order.
635
636 extra_headers: Send extra headers
637
638 extra_query: Add additional query parameters to the request
639
640 extra_body: Add additional JSON properties to the request
641
642 timeout: Override the client-level default timeout for this request, in seconds
643 """
644 if not vector_store_id:
645 raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
646 extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
647 return self._get_api_list(
648 f"/vector_stores/{vector_store_id}/files",
649 page=AsyncCursorPage[VectorStoreFile],
650 options=make_request_options(
651 extra_headers=extra_headers,
652 extra_query=extra_query,
653 extra_body=extra_body,
654 timeout=timeout,
655 query=maybe_transform(
656 {
657 "after": after,
658 "before": before,
659 "filter": filter,
660 "limit": limit,
661 "order": order,
662 },
663 file_list_params.FileListParams,
664 ),
665 ),
666 model=VectorStoreFile,
667 )
668
669 async def delete(
670 self,
671 file_id: str,
672 *,
673 vector_store_id: str,
674 # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
675 # The extra values given here take precedence over values defined on the client or passed to this method.
676 extra_headers: Headers | None = None,
677 extra_query: Query | None = None,
678 extra_body: Body | None = None,
679 timeout: float | httpx.Timeout | None | NotGiven = not_given,
680 ) -> VectorStoreFileDeleted:
681 """Delete a vector store file.
682
683 This will remove the file from the vector store but
684 the file itself will not be deleted. To delete the file, use the
685 [delete file](https://platform.openai.com/docs/api-reference/files/delete)
686 endpoint.
687
688 Args:
689 extra_headers: Send extra headers
690
691 extra_query: Add additional query parameters to the request
692
693 extra_body: Add additional JSON properties to the request
694
695 timeout: Override the client-level default timeout for this request, in seconds
696 """
697 if not vector_store_id:
698 raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
699 if not file_id:
700 raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
701 extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
702 return await self._delete(
703 f"/vector_stores/{vector_store_id}/files/{file_id}",
704 options=make_request_options(
705 extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
706 ),
707 cast_to=VectorStoreFileDeleted,
708 )
709
710 async def create_and_poll(
711 self,
712 file_id: str,
713 *,
714 vector_store_id: str,
715 attributes: Optional[Dict[str, Union[str, float, bool]]] | Omit = omit,
716 poll_interval_ms: int | Omit = omit,
717 chunking_strategy: FileChunkingStrategyParam | Omit = omit,
718 ) -> VectorStoreFile:
719 """Attach a file to the given vector store and wait for it to be processed."""
720 await self.create(
721 vector_store_id=vector_store_id, file_id=file_id, chunking_strategy=chunking_strategy, attributes=attributes
722 )
723
724 return await self.poll(
725 file_id,
726 vector_store_id=vector_store_id,
727 poll_interval_ms=poll_interval_ms,
728 )
729
730 async def poll(
731 self,
732 file_id: str,
733 *,
734 vector_store_id: str,
735 poll_interval_ms: int | Omit = omit,
736 ) -> VectorStoreFile:
737 """Wait for the vector store file to finish processing.
738
739 Note: this will return even if the file failed to process, you need to check
740 file.last_error and file.status to handle these cases
741 """
742 headers: dict[str, str] = {"X-Stainless-Poll-Helper": "true"}
743 if is_given(poll_interval_ms):
744 headers["X-Stainless-Custom-Poll-Interval"] = str(poll_interval_ms)
745
746 while True:
747 response = await self.with_raw_response.retrieve(
748 file_id,
749 vector_store_id=vector_store_id,
750 extra_headers=headers,
751 )
752
753 file = response.parse()
754 if file.status == "in_progress":
755 if not is_given(poll_interval_ms):
756 from_header = response.headers.get("openai-poll-after-ms")
757 if from_header is not None:
758 poll_interval_ms = int(from_header)
759 else:
760 poll_interval_ms = 1000
761
762 await self._sleep(poll_interval_ms / 1000)
763 elif file.status == "cancelled" or file.status == "completed" or file.status == "failed":
764 return file
765 else:
766 if TYPE_CHECKING: # type: ignore[unreachable]
767 assert_never(file.status)
768 else:
769 return file
770
771 async def upload(
772 self,
773 *,
774 vector_store_id: str,
775 file: FileTypes,
776 chunking_strategy: FileChunkingStrategyParam | Omit = omit,
777 ) -> VectorStoreFile:
778 """Upload a file to the `files` API and then attach it to the given vector store.
779
780 Note the file will be asynchronously processed (you can use the alternative
781 polling helper method to wait for processing to complete).
782 """
783 file_obj = await self._client.files.create(file=file, purpose="assistants")
784 return await self.create(
785 vector_store_id=vector_store_id, file_id=file_obj.id, chunking_strategy=chunking_strategy
786 )
787
788 async def upload_and_poll(
789 self,
790 *,
791 vector_store_id: str,
792 file: FileTypes,
793 attributes: Optional[Dict[str, Union[str, float, bool]]] | Omit = omit,
794 poll_interval_ms: int | Omit = omit,
795 chunking_strategy: FileChunkingStrategyParam | Omit = omit,
796 ) -> VectorStoreFile:
797 """Add a file to a vector store and poll until processing is complete."""
798 file_obj = await self._client.files.create(file=file, purpose="assistants")
799 return await self.create_and_poll(
800 vector_store_id=vector_store_id,
801 file_id=file_obj.id,
802 poll_interval_ms=poll_interval_ms,
803 chunking_strategy=chunking_strategy,
804 attributes=attributes,
805 )
806
807 def content(
808 self,
809 file_id: str,
810 *,
811 vector_store_id: str,
812 # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
813 # The extra values given here take precedence over values defined on the client or passed to this method.
814 extra_headers: Headers | None = None,
815 extra_query: Query | None = None,
816 extra_body: Body | None = None,
817 timeout: float | httpx.Timeout | None | NotGiven = not_given,
818 ) -> AsyncPaginator[FileContentResponse, AsyncPage[FileContentResponse]]:
819 """
820 Retrieve the parsed contents of a vector store file.
821
822 Args:
823 extra_headers: Send extra headers
824
825 extra_query: Add additional query parameters to the request
826
827 extra_body: Add additional JSON properties to the request
828
829 timeout: Override the client-level default timeout for this request, in seconds
830 """
831 if not vector_store_id:
832 raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
833 if not file_id:
834 raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
835 extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
836 return self._get_api_list(
837 f"/vector_stores/{vector_store_id}/files/{file_id}/content",
838 page=AsyncPage[FileContentResponse],
839 options=make_request_options(
840 extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
841 ),
842 model=FileContentResponse,
843 )
844
845
846class FilesWithRawResponse:
847 def __init__(self, files: Files) -> None:
848 self._files = files
849
850 self.create = _legacy_response.to_raw_response_wrapper(
851 files.create,
852 )
853 self.retrieve = _legacy_response.to_raw_response_wrapper(
854 files.retrieve,
855 )
856 self.update = _legacy_response.to_raw_response_wrapper(
857 files.update,
858 )
859 self.list = _legacy_response.to_raw_response_wrapper(
860 files.list,
861 )
862 self.delete = _legacy_response.to_raw_response_wrapper(
863 files.delete,
864 )
865 self.content = _legacy_response.to_raw_response_wrapper(
866 files.content,
867 )
868
869
870class AsyncFilesWithRawResponse:
871 def __init__(self, files: AsyncFiles) -> None:
872 self._files = files
873
874 self.create = _legacy_response.async_to_raw_response_wrapper(
875 files.create,
876 )
877 self.retrieve = _legacy_response.async_to_raw_response_wrapper(
878 files.retrieve,
879 )
880 self.update = _legacy_response.async_to_raw_response_wrapper(
881 files.update,
882 )
883 self.list = _legacy_response.async_to_raw_response_wrapper(
884 files.list,
885 )
886 self.delete = _legacy_response.async_to_raw_response_wrapper(
887 files.delete,
888 )
889 self.content = _legacy_response.async_to_raw_response_wrapper(
890 files.content,
891 )
892
893
894class FilesWithStreamingResponse:
895 def __init__(self, files: Files) -> None:
896 self._files = files
897
898 self.create = to_streamed_response_wrapper(
899 files.create,
900 )
901 self.retrieve = to_streamed_response_wrapper(
902 files.retrieve,
903 )
904 self.update = to_streamed_response_wrapper(
905 files.update,
906 )
907 self.list = to_streamed_response_wrapper(
908 files.list,
909 )
910 self.delete = to_streamed_response_wrapper(
911 files.delete,
912 )
913 self.content = to_streamed_response_wrapper(
914 files.content,
915 )
916
917
918class AsyncFilesWithStreamingResponse:
919 def __init__(self, files: AsyncFiles) -> None:
920 self._files = files
921
922 self.create = async_to_streamed_response_wrapper(
923 files.create,
924 )
925 self.retrieve = async_to_streamed_response_wrapper(
926 files.retrieve,
927 )
928 self.update = async_to_streamed_response_wrapper(
929 files.update,
930 )
931 self.list = async_to_streamed_response_wrapper(
932 files.list,
933 )
934 self.delete = async_to_streamed_response_wrapper(
935 files.delete,
936 )
937 self.content = async_to_streamed_response_wrapper(
938 files.content,
939 )