feat: openai files api (#2321)

# What does this PR do?
* Adds the OpenAI compatible Files API
* Modified doc gen script to support multipart parameter

## Test Plan

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with
[ReviewStack](https://reviewstack.dev/meta-llama/llama-stack/pull/2321).
* #2330
* __->__ #2321
This commit is contained in:
ehhuang 2025-06-02 11:45:53 -07:00 committed by GitHub
parent 17f4414be9
commit 31a3ae60f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 881 additions and 946 deletions

View file

@ -633,90 +633,6 @@
} }
} }
}, },
"/v1/files": {
"get": {
"responses": {
"200": {
"description": "A ListBucketResponse.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ListBucketResponse"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest400"
},
"429": {
"$ref": "#/components/responses/TooManyRequests429"
},
"500": {
"$ref": "#/components/responses/InternalServerError500"
},
"default": {
"$ref": "#/components/responses/DefaultError"
}
},
"tags": [
"Files"
],
"description": "List all buckets.",
"parameters": [
{
"name": "bucket",
"in": "query",
"description": "Bucket name (valid chars: a-zA-Z0-9_-).",
"required": true,
"schema": {
"type": "string"
}
}
]
},
"post": {
"responses": {
"200": {
"description": "A FileUploadResponse.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FileUploadResponse"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest400"
},
"429": {
"$ref": "#/components/responses/TooManyRequests429"
},
"500": {
"$ref": "#/components/responses/InternalServerError500"
},
"default": {
"$ref": "#/components/responses/DefaultError"
}
},
"tags": [
"Files"
],
"description": "Create a new upload session for a file identified by a bucket and key.",
"parameters": [],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateUploadSessionRequest"
}
}
},
"required": true
}
}
},
"/v1/agents/{agent_id}": { "/v1/agents/{agent_id}": {
"get": { "get": {
"responses": { "responses": {
@ -901,101 +817,6 @@
] ]
} }
}, },
"/v1/files/{bucket}/{key}": {
"get": {
"responses": {
"200": {
"description": "A FileResponse.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FileResponse"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest400"
},
"429": {
"$ref": "#/components/responses/TooManyRequests429"
},
"500": {
"$ref": "#/components/responses/InternalServerError500"
},
"default": {
"$ref": "#/components/responses/DefaultError"
}
},
"tags": [
"Files"
],
"description": "Get a file info identified by a bucket and key.",
"parameters": [
{
"name": "bucket",
"in": "path",
"description": "Bucket name (valid chars: a-zA-Z0-9_-).",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "key",
"in": "path",
"description": "Key under which the file is stored (valid chars: a-zA-Z0-9_-/.).",
"required": true,
"schema": {
"type": "string"
}
}
]
},
"delete": {
"responses": {
"200": {
"description": "OK"
},
"400": {
"$ref": "#/components/responses/BadRequest400"
},
"429": {
"$ref": "#/components/responses/TooManyRequests429"
},
"500": {
"$ref": "#/components/responses/InternalServerError500"
},
"default": {
"$ref": "#/components/responses/DefaultError"
}
},
"tags": [
"Files"
],
"description": "Delete a file identified by a bucket and key.",
"parameters": [
{
"name": "bucket",
"in": "path",
"description": "Bucket name (valid chars: a-zA-Z0-9_-).",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "key",
"in": "path",
"description": "Key under which the file is stored (valid chars: a-zA-Z0-9_-/.).",
"required": true,
"schema": {
"type": "string"
}
}
]
}
},
"/v1/inference/embeddings": { "/v1/inference/embeddings": {
"post": { "post": {
"responses": { "responses": {
@ -1979,108 +1800,6 @@
"parameters": [] "parameters": []
} }
}, },
"/v1/files/session:{upload_id}": {
"get": {
"responses": {
"200": {
"description": "A FileUploadResponse.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FileUploadResponse"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest400"
},
"429": {
"$ref": "#/components/responses/TooManyRequests429"
},
"500": {
"$ref": "#/components/responses/InternalServerError500"
},
"default": {
"$ref": "#/components/responses/DefaultError"
}
},
"tags": [
"Files"
],
"description": "Returns information about an existsing upload session.",
"parameters": [
{
"name": "upload_id",
"in": "path",
"description": "ID of the upload session.",
"required": true,
"schema": {
"type": "string"
}
}
]
},
"post": {
"responses": {
"200": {
"description": "A FileResponse or None if the upload is not complete.",
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/FileResponse"
},
{
"type": "null"
}
]
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest400"
},
"429": {
"$ref": "#/components/responses/TooManyRequests429"
},
"500": {
"$ref": "#/components/responses/InternalServerError500"
},
"default": {
"$ref": "#/components/responses/DefaultError"
}
},
"tags": [
"Files"
],
"description": "Upload file content to an existing upload session. On the server, request body will have the raw bytes that are uploaded.",
"parameters": [
{
"name": "upload_id",
"in": "path",
"description": "ID of the upload session.",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/octet-stream": {
"schema": {
"type": "string",
"format": "binary"
}
}
},
"required": true
}
}
},
"/v1/vector-dbs/{vector_db_id}": { "/v1/vector-dbs/{vector_db_id}": {
"get": { "get": {
"responses": { "responses": {
@ -2877,49 +2596,6 @@
} }
} }
}, },
"/v1/files/{bucket}": {
"get": {
"responses": {
"200": {
"description": "A ListFileResponse.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ListFileResponse"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest400"
},
"429": {
"$ref": "#/components/responses/TooManyRequests429"
},
"500": {
"$ref": "#/components/responses/InternalServerError500"
},
"default": {
"$ref": "#/components/responses/DefaultError"
}
},
"tags": [
"Files"
],
"description": "List all files in a bucket.",
"parameters": [
{
"name": "bucket",
"in": "path",
"description": "Bucket name (valid chars: a-zA-Z0-9_-).",
"required": true,
"schema": {
"type": "string"
}
}
]
}
},
"/v1/models": { "/v1/models": {
"get": { "get": {
"responses": { "responses": {
@ -3607,6 +3283,90 @@
} }
} }
}, },
"/v1/openai/v1/files/{file_id}": {
"get": {
"responses": {
"200": {
"description": "An OpenAIFileObject containing file information.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OpenAIFileObject"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest400"
},
"429": {
"$ref": "#/components/responses/TooManyRequests429"
},
"500": {
"$ref": "#/components/responses/InternalServerError500"
},
"default": {
"$ref": "#/components/responses/DefaultError"
}
},
"tags": [
"Files"
],
"description": "Returns information about a specific file.",
"parameters": [
{
"name": "file_id",
"in": "path",
"description": "The ID of the file to use for this request.",
"required": true,
"schema": {
"type": "string"
}
}
]
},
"delete": {
"responses": {
"200": {
"description": "An OpenAIFileDeleteResponse indicating successful deletion.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OpenAIFileDeleteResponse"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest400"
},
"429": {
"$ref": "#/components/responses/TooManyRequests429"
},
"500": {
"$ref": "#/components/responses/InternalServerError500"
},
"default": {
"$ref": "#/components/responses/DefaultError"
}
},
"tags": [
"Files"
],
"description": "Delete a file.",
"parameters": [
{
"name": "file_id",
"in": "path",
"description": "The ID of the file to use for this request.",
"required": true,
"schema": {
"type": "string"
}
}
]
}
},
"/v1/openai/v1/embeddings": { "/v1/openai/v1/embeddings": {
"post": { "post": {
"responses": { "responses": {
@ -3650,6 +3410,130 @@
} }
} }
}, },
"/v1/openai/v1/files": {
"get": {
"responses": {
"200": {
"description": "An ListOpenAIFileResponse containing the list of files.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ListOpenAIFileResponse"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest400"
},
"429": {
"$ref": "#/components/responses/TooManyRequests429"
},
"500": {
"$ref": "#/components/responses/InternalServerError500"
},
"default": {
"$ref": "#/components/responses/DefaultError"
}
},
"tags": [
"Files"
],
"description": "Returns a list of files that belong to the user's organization.",
"parameters": [
{
"name": "after",
"in": "query",
"description": "A cursor for use in pagination. `after` is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, ending with obj_foo, your subsequent call can include after=obj_foo in order to fetch the next page of the list.",
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "limit",
"in": "query",
"description": "A limit on the number of objects to be returned. Limit can range between 1 and 10,000, and the default is 10,000.",
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "order",
"in": "query",
"description": "Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and `desc` for descending order.",
"required": false,
"schema": {
"$ref": "#/components/schemas/Order"
}
},
{
"name": "purpose",
"in": "query",
"description": "Only return files with the given purpose.",
"required": false,
"schema": {
"$ref": "#/components/schemas/OpenAIFilePurpose"
}
}
]
},
"post": {
"responses": {
"200": {
"description": "An OpenAIFileObject representing the uploaded file.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OpenAIFileObject"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest400"
},
"429": {
"$ref": "#/components/responses/TooManyRequests429"
},
"500": {
"$ref": "#/components/responses/InternalServerError500"
},
"default": {
"$ref": "#/components/responses/DefaultError"
}
},
"tags": [
"Files"
],
"description": "Upload a file that can be used across various endpoints.\nThe file upload should be a multipart form request with:\n- file: The File object (not file name) to be uploaded.\n- purpose: The intended purpose of the uploaded file.",
"parameters": [],
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"properties": {
"file": {
"type": "string",
"format": "binary"
},
"purpose": {
"$ref": "#/components/schemas/OpenAIFilePurpose"
}
},
"required": [
"file",
"purpose"
]
}
}
},
"required": true
}
}
},
"/v1/openai/v1/models": { "/v1/openai/v1/models": {
"get": { "get": {
"responses": { "responses": {
@ -3683,6 +3567,49 @@
"parameters": [] "parameters": []
} }
}, },
"/v1/openai/v1/files/{file_id}/content": {
"get": {
"responses": {
"200": {
"description": "The raw file content as a binary response.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Response"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest400"
},
"429": {
"$ref": "#/components/responses/TooManyRequests429"
},
"500": {
"$ref": "#/components/responses/InternalServerError500"
},
"default": {
"$ref": "#/components/responses/DefaultError"
}
},
"tags": [
"Files"
],
"description": "Returns the contents of the specified file.",
"parameters": [
{
"name": "file_id",
"in": "path",
"description": "The ID of the file to use for this request.",
"required": true,
"schema": {
"type": "string"
}
}
]
}
},
"/v1/post-training/preference-optimize": { "/v1/post-training/preference-optimize": {
"post": { "post": {
"responses": { "responses": {
@ -7672,65 +7599,6 @@
], ],
"title": "OpenAIResponseObjectStreamResponseOutputTextDelta" "title": "OpenAIResponseObjectStreamResponseOutputTextDelta"
}, },
"CreateUploadSessionRequest": {
"type": "object",
"properties": {
"bucket": {
"type": "string",
"description": "Bucket under which the file is stored (valid chars: a-zA-Z0-9_-)."
},
"key": {
"type": "string",
"description": "Key under which the file is stored (valid chars: a-zA-Z0-9_-/.)."
},
"mime_type": {
"type": "string",
"description": "MIME type of the file."
},
"size": {
"type": "integer",
"description": "File size in bytes."
}
},
"additionalProperties": false,
"required": [
"bucket",
"key",
"mime_type",
"size"
],
"title": "CreateUploadSessionRequest"
},
"FileUploadResponse": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "ID of the upload session"
},
"url": {
"type": "string",
"description": "Upload URL for the file or file parts"
},
"offset": {
"type": "integer",
"description": "Upload content offset"
},
"size": {
"type": "integer",
"description": "Upload content size"
}
},
"additionalProperties": false,
"required": [
"id",
"url",
"offset",
"size"
],
"title": "FileUploadResponse",
"description": "Response after initiating a file upload session."
},
"EmbeddingsRequest": { "EmbeddingsRequest": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -8994,46 +8862,6 @@
"title": "URIDataSource", "title": "URIDataSource",
"description": "A dataset that can be obtained from a URI." "description": "A dataset that can be obtained from a URI."
}, },
"FileResponse": {
"type": "object",
"properties": {
"bucket": {
"type": "string",
"description": "Bucket under which the file is stored (valid chars: a-zA-Z0-9_-)"
},
"key": {
"type": "string",
"description": "Key under which the file is stored (valid chars: a-zA-Z0-9_-/.)"
},
"mime_type": {
"type": "string",
"description": "MIME type of the file"
},
"url": {
"type": "string",
"description": "Upload URL for the file contents"
},
"bytes": {
"type": "integer",
"description": "Size of the file in bytes"
},
"created_at": {
"type": "integer",
"description": "Timestamp of when the file was created"
}
},
"additionalProperties": false,
"required": [
"bucket",
"key",
"mime_type",
"url",
"bytes",
"created_at"
],
"title": "FileResponse",
"description": "Response representing a file entry."
},
"Model": { "Model": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -10347,37 +10175,6 @@
], ],
"title": "Job" "title": "Job"
}, },
"BucketResponse": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"name"
],
"title": "BucketResponse"
},
"ListBucketResponse": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/BucketResponse"
},
"description": "List of FileResponse entries"
}
},
"additionalProperties": false,
"required": [
"data"
],
"title": "ListBucketResponse",
"description": "Response representing a list of file entries."
},
"ListBenchmarksResponse": { "ListBenchmarksResponse": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -10495,24 +10292,6 @@
], ],
"title": "ListDatasetsResponse" "title": "ListDatasetsResponse"
}, },
"ListFileResponse": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/FileResponse"
},
"description": "List of FileResponse entries"
}
},
"additionalProperties": false,
"required": [
"data"
],
"title": "ListFileResponse",
"description": "Response representing a list of file entries."
},
"ListModelsResponse": { "ListModelsResponse": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -11820,6 +11599,33 @@
"title": "OpenAICompletionChoice", "title": "OpenAICompletionChoice",
"description": "A choice from an OpenAI-compatible completion response." "description": "A choice from an OpenAI-compatible completion response."
}, },
"OpenAIFileDeleteResponse": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The file identifier that was deleted"
},
"object": {
"type": "string",
"const": "file",
"default": "file",
"description": "The object type, which is always \"file\""
},
"deleted": {
"type": "boolean",
"description": "Whether the file was successfully deleted"
}
},
"additionalProperties": false,
"required": [
"id",
"object",
"deleted"
],
"title": "OpenAIFileDeleteResponse",
"description": "Response for deleting a file in OpenAI Files API."
},
"OpenaiEmbeddingsRequest": { "OpenaiEmbeddingsRequest": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -11953,6 +11759,101 @@
"title": "OpenAIEmbeddingsResponse", "title": "OpenAIEmbeddingsResponse",
"description": "Response from an OpenAI-compatible embeddings request." "description": "Response from an OpenAI-compatible embeddings request."
}, },
"OpenAIFilePurpose": {
"type": "string",
"enum": [
"assistants"
],
"title": "OpenAIFilePurpose",
"description": "Valid purpose values for OpenAI Files API."
},
"ListOpenAIFileResponse": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/OpenAIFileObject"
},
"description": "List of file objects"
},
"has_more": {
"type": "boolean"
},
"first_id": {
"type": "string"
},
"last_id": {
"type": "string"
},
"object": {
"type": "string",
"const": "list",
"default": "list",
"description": "The object type, which is always \"list\""
}
},
"additionalProperties": false,
"required": [
"data",
"has_more",
"first_id",
"last_id",
"object"
],
"title": "ListOpenAIFileResponse",
"description": "Response for listing files in OpenAI Files API."
},
"OpenAIFileObject": {
"type": "object",
"properties": {
"object": {
"type": "string",
"const": "file",
"default": "file",
"description": "The object type, which is always \"file\""
},
"id": {
"type": "string",
"description": "The file identifier, which can be referenced in the API endpoints"
},
"bytes": {
"type": "integer",
"description": "The size of the file, in bytes"
},
"created_at": {
"type": "integer",
"description": "The Unix timestamp (in seconds) for when the file was created"
},
"expires_at": {
"type": "integer",
"description": "The Unix timestamp (in seconds) for when the file expires"
},
"filename": {
"type": "string",
"description": "The name of the file"
},
"purpose": {
"type": "string",
"enum": [
"assistants"
],
"description": "The intended purpose of the file"
}
},
"additionalProperties": false,
"required": [
"object",
"id",
"bytes",
"created_at",
"expires_at",
"filename",
"purpose"
],
"title": "OpenAIFileObject",
"description": "OpenAI File object as defined in the OpenAI Files API."
},
"OpenAIModel": { "OpenAIModel": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -11997,6 +11898,10 @@
], ],
"title": "OpenAIListModelsResponse" "title": "OpenAIListModelsResponse"
}, },
"Response": {
"type": "object",
"title": "Response"
},
"DPOAlignmentConfig": { "DPOAlignmentConfig": {
"type": "object", "type": "object",
"properties": { "properties": {

View file

@ -427,64 +427,6 @@ paths:
schema: schema:
$ref: '#/components/schemas/CreateOpenaiResponseRequest' $ref: '#/components/schemas/CreateOpenaiResponseRequest'
required: true required: true
/v1/files:
get:
responses:
'200':
description: A ListBucketResponse.
content:
application/json:
schema:
$ref: '#/components/schemas/ListBucketResponse'
'400':
$ref: '#/components/responses/BadRequest400'
'429':
$ref: >-
#/components/responses/TooManyRequests429
'500':
$ref: >-
#/components/responses/InternalServerError500
default:
$ref: '#/components/responses/DefaultError'
tags:
- Files
description: List all buckets.
parameters:
- name: bucket
in: query
description: 'Bucket name (valid chars: a-zA-Z0-9_-).'
required: true
schema:
type: string
post:
responses:
'200':
description: A FileUploadResponse.
content:
application/json:
schema:
$ref: '#/components/schemas/FileUploadResponse'
'400':
$ref: '#/components/responses/BadRequest400'
'429':
$ref: >-
#/components/responses/TooManyRequests429
'500':
$ref: >-
#/components/responses/InternalServerError500
default:
$ref: '#/components/responses/DefaultError'
tags:
- Files
description: >-
Create a new upload session for a file identified by a bucket and key.
parameters: []
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUploadSessionRequest'
required: true
/v1/agents/{agent_id}: /v1/agents/{agent_id}:
get: get:
responses: responses:
@ -616,75 +558,6 @@ paths:
required: true required: true
schema: schema:
type: string type: string
/v1/files/{bucket}/{key}:
get:
responses:
'200':
description: A FileResponse.
content:
application/json:
schema:
$ref: '#/components/schemas/FileResponse'
'400':
$ref: '#/components/responses/BadRequest400'
'429':
$ref: >-
#/components/responses/TooManyRequests429
'500':
$ref: >-
#/components/responses/InternalServerError500
default:
$ref: '#/components/responses/DefaultError'
tags:
- Files
description: >-
Get a file info identified by a bucket and key.
parameters:
- name: bucket
in: path
description: 'Bucket name (valid chars: a-zA-Z0-9_-).'
required: true
schema:
type: string
- name: key
in: path
description: >-
Key under which the file is stored (valid chars: a-zA-Z0-9_-/.).
required: true
schema:
type: string
delete:
responses:
'200':
description: OK
'400':
$ref: '#/components/responses/BadRequest400'
'429':
$ref: >-
#/components/responses/TooManyRequests429
'500':
$ref: >-
#/components/responses/InternalServerError500
default:
$ref: '#/components/responses/DefaultError'
tags:
- Files
description: >-
Delete a file identified by a bucket and key.
parameters:
- name: bucket
in: path
description: 'Bucket name (valid chars: a-zA-Z0-9_-).'
required: true
schema:
type: string
- name: key
in: path
description: >-
Key under which the file is stored (valid chars: a-zA-Z0-9_-/.).
required: true
schema:
type: string
/v1/inference/embeddings: /v1/inference/embeddings:
post: post:
responses: responses:
@ -1363,76 +1236,6 @@ paths:
- PostTraining (Coming Soon) - PostTraining (Coming Soon)
description: Get all training jobs. description: Get all training jobs.
parameters: [] parameters: []
/v1/files/session:{upload_id}:
get:
responses:
'200':
description: A FileUploadResponse.
content:
application/json:
schema:
$ref: '#/components/schemas/FileUploadResponse'
'400':
$ref: '#/components/responses/BadRequest400'
'429':
$ref: >-
#/components/responses/TooManyRequests429
'500':
$ref: >-
#/components/responses/InternalServerError500
default:
$ref: '#/components/responses/DefaultError'
tags:
- Files
description: >-
Returns information about an existsing upload session.
parameters:
- name: upload_id
in: path
description: ID of the upload session.
required: true
schema:
type: string
post:
responses:
'200':
description: >-
A FileResponse or None if the upload is not complete.
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/FileResponse'
- type: 'null'
'400':
$ref: '#/components/responses/BadRequest400'
'429':
$ref: >-
#/components/responses/TooManyRequests429
'500':
$ref: >-
#/components/responses/InternalServerError500
default:
$ref: '#/components/responses/DefaultError'
tags:
- Files
description: >-
Upload file content to an existing upload session. On the server, request
body will have the raw bytes that are uploaded.
parameters:
- name: upload_id
in: path
description: ID of the upload session.
required: true
schema:
type: string
requestBody:
content:
application/octet-stream:
schema:
type: string
format: binary
required: true
/v1/vector-dbs/{vector_db_id}: /v1/vector-dbs/{vector_db_id}:
get: get:
responses: responses:
@ -2005,35 +1808,6 @@ paths:
schema: schema:
$ref: '#/components/schemas/RegisterDatasetRequest' $ref: '#/components/schemas/RegisterDatasetRequest'
required: true required: true
/v1/files/{bucket}:
get:
responses:
'200':
description: A ListFileResponse.
content:
application/json:
schema:
$ref: '#/components/schemas/ListFileResponse'
'400':
$ref: '#/components/responses/BadRequest400'
'429':
$ref: >-
#/components/responses/TooManyRequests429
'500':
$ref: >-
#/components/responses/InternalServerError500
default:
$ref: '#/components/responses/DefaultError'
tags:
- Files
description: List all files in a bucket.
parameters:
- name: bucket
in: path
description: 'Bucket name (valid chars: a-zA-Z0-9_-).'
required: true
schema:
type: string
/v1/models: /v1/models:
get: get:
responses: responses:
@ -2520,6 +2294,68 @@ paths:
schema: schema:
$ref: '#/components/schemas/OpenaiCompletionRequest' $ref: '#/components/schemas/OpenaiCompletionRequest'
required: true required: true
/v1/openai/v1/files/{file_id}:
get:
responses:
'200':
description: >-
An OpenAIFileObject containing file information.
content:
application/json:
schema:
$ref: '#/components/schemas/OpenAIFileObject'
'400':
$ref: '#/components/responses/BadRequest400'
'429':
$ref: >-
#/components/responses/TooManyRequests429
'500':
$ref: >-
#/components/responses/InternalServerError500
default:
$ref: '#/components/responses/DefaultError'
tags:
- Files
description: >-
Returns information about a specific file.
parameters:
- name: file_id
in: path
description: >-
The ID of the file to use for this request.
required: true
schema:
type: string
delete:
responses:
'200':
description: >-
An OpenAIFileDeleteResponse indicating successful deletion.
content:
application/json:
schema:
$ref: '#/components/schemas/OpenAIFileDeleteResponse'
'400':
$ref: '#/components/responses/BadRequest400'
'429':
$ref: >-
#/components/responses/TooManyRequests429
'500':
$ref: >-
#/components/responses/InternalServerError500
default:
$ref: '#/components/responses/DefaultError'
tags:
- Files
description: Delete a file.
parameters:
- name: file_id
in: path
description: >-
The ID of the file to use for this request.
required: true
schema:
type: string
/v1/openai/v1/embeddings: /v1/openai/v1/embeddings:
post: post:
responses: responses:
@ -2552,6 +2388,109 @@ paths:
schema: schema:
$ref: '#/components/schemas/OpenaiEmbeddingsRequest' $ref: '#/components/schemas/OpenaiEmbeddingsRequest'
required: true required: true
/v1/openai/v1/files:
get:
responses:
'200':
description: >-
An ListOpenAIFileResponse containing the list of files.
content:
application/json:
schema:
$ref: '#/components/schemas/ListOpenAIFileResponse'
'400':
$ref: '#/components/responses/BadRequest400'
'429':
$ref: >-
#/components/responses/TooManyRequests429
'500':
$ref: >-
#/components/responses/InternalServerError500
default:
$ref: '#/components/responses/DefaultError'
tags:
- Files
description: >-
Returns a list of files that belong to the user's organization.
parameters:
- name: after
in: query
description: >-
A cursor for use in pagination. `after` is an object ID that defines your
place in the list. For instance, if you make a list request and receive
100 objects, ending with obj_foo, your subsequent call can include after=obj_foo
in order to fetch the next page of the list.
required: false
schema:
type: string
- name: limit
in: query
description: >-
A limit on the number of objects to be returned. Limit can range between
1 and 10,000, and the default is 10,000.
required: false
schema:
type: integer
- name: order
in: query
description: >-
Sort order by the `created_at` timestamp of the objects. `asc` for ascending
order and `desc` for descending order.
required: false
schema:
$ref: '#/components/schemas/Order'
- name: purpose
in: query
description: >-
Only return files with the given purpose.
required: false
schema:
$ref: '#/components/schemas/OpenAIFilePurpose'
post:
responses:
'200':
description: >-
An OpenAIFileObject representing the uploaded file.
content:
application/json:
schema:
$ref: '#/components/schemas/OpenAIFileObject'
'400':
$ref: '#/components/responses/BadRequest400'
'429':
$ref: >-
#/components/responses/TooManyRequests429
'500':
$ref: >-
#/components/responses/InternalServerError500
default:
$ref: '#/components/responses/DefaultError'
tags:
- Files
description: >-
Upload a file that can be used across various endpoints.
The file upload should be a multipart form request with:
- file: The File object (not file name) to be uploaded.
- purpose: The intended purpose of the uploaded file.
parameters: []
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
purpose:
$ref: '#/components/schemas/OpenAIFilePurpose'
required:
- file
- purpose
required: true
/v1/openai/v1/models: /v1/openai/v1/models:
get: get:
responses: responses:
@ -2575,6 +2514,38 @@ paths:
- Models - Models
description: List models using the OpenAI API. description: List models using the OpenAI API.
parameters: [] parameters: []
/v1/openai/v1/files/{file_id}/content:
get:
responses:
'200':
description: >-
The raw file content as a binary response.
content:
application/json:
schema:
$ref: '#/components/schemas/Response'
'400':
$ref: '#/components/responses/BadRequest400'
'429':
$ref: >-
#/components/responses/TooManyRequests429
'500':
$ref: >-
#/components/responses/InternalServerError500
default:
$ref: '#/components/responses/DefaultError'
tags:
- Files
description: >-
Returns the contents of the specified file.
parameters:
- name: file_id
in: path
description: >-
The ID of the file to use for this request.
required: true
schema:
type: string
/v1/post-training/preference-optimize: /v1/post-training/preference-optimize:
post: post:
responses: responses:
@ -5391,54 +5362,6 @@ components:
- type - type
title: >- title: >-
OpenAIResponseObjectStreamResponseOutputTextDelta OpenAIResponseObjectStreamResponseOutputTextDelta
CreateUploadSessionRequest:
type: object
properties:
bucket:
type: string
description: >-
Bucket under which the file is stored (valid chars: a-zA-Z0-9_-).
key:
type: string
description: >-
Key under which the file is stored (valid chars: a-zA-Z0-9_-/.).
mime_type:
type: string
description: MIME type of the file.
size:
type: integer
description: File size in bytes.
additionalProperties: false
required:
- bucket
- key
- mime_type
- size
title: CreateUploadSessionRequest
FileUploadResponse:
type: object
properties:
id:
type: string
description: ID of the upload session
url:
type: string
description: Upload URL for the file or file parts
offset:
type: integer
description: Upload content offset
size:
type: integer
description: Upload content size
additionalProperties: false
required:
- id
- url
- offset
- size
title: FileUploadResponse
description: >-
Response after initiating a file upload session.
EmbeddingsRequest: EmbeddingsRequest:
type: object type: object
properties: properties:
@ -6343,39 +6266,6 @@ components:
title: URIDataSource title: URIDataSource
description: >- description: >-
A dataset that can be obtained from a URI. A dataset that can be obtained from a URI.
FileResponse:
type: object
properties:
bucket:
type: string
description: >-
Bucket under which the file is stored (valid chars: a-zA-Z0-9_-)
key:
type: string
description: >-
Key under which the file is stored (valid chars: a-zA-Z0-9_-/.)
mime_type:
type: string
description: MIME type of the file
url:
type: string
description: Upload URL for the file contents
bytes:
type: integer
description: Size of the file in bytes
created_at:
type: integer
description: Timestamp of when the file was created
additionalProperties: false
required:
- bucket
- key
- mime_type
- url
- bytes
- created_at
title: FileResponse
description: Response representing a file entry.
Model: Model:
type: object type: object
properties: properties:
@ -7227,29 +7117,6 @@ components:
- job_id - job_id
- status - status
title: Job title: Job
BucketResponse:
type: object
properties:
name:
type: string
additionalProperties: false
required:
- name
title: BucketResponse
ListBucketResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/BucketResponse'
description: List of FileResponse entries
additionalProperties: false
required:
- data
title: ListBucketResponse
description: >-
Response representing a list of file entries.
ListBenchmarksResponse: ListBenchmarksResponse:
type: object type: object
properties: properties:
@ -7339,20 +7206,6 @@ components:
required: required:
- data - data
title: ListDatasetsResponse title: ListDatasetsResponse
ListFileResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/FileResponse'
description: List of FileResponse entries
additionalProperties: false
required:
- data
title: ListFileResponse
description: >-
Response representing a list of file entries.
ListModelsResponse: ListModelsResponse:
type: object type: object
properties: properties:
@ -8229,6 +8082,29 @@ components:
title: OpenAICompletionChoice title: OpenAICompletionChoice
description: >- description: >-
A choice from an OpenAI-compatible completion response. A choice from an OpenAI-compatible completion response.
OpenAIFileDeleteResponse:
type: object
properties:
id:
type: string
description: The file identifier that was deleted
object:
type: string
const: file
default: file
description: The object type, which is always "file"
deleted:
type: boolean
description: >-
Whether the file was successfully deleted
additionalProperties: false
required:
- id
- object
- deleted
title: OpenAIFileDeleteResponse
description: >-
Response for deleting a file in OpenAI Files API.
OpenaiEmbeddingsRequest: OpenaiEmbeddingsRequest:
type: object type: object
properties: properties:
@ -8341,6 +8217,85 @@ components:
title: OpenAIEmbeddingsResponse title: OpenAIEmbeddingsResponse
description: >- description: >-
Response from an OpenAI-compatible embeddings request. Response from an OpenAI-compatible embeddings request.
OpenAIFilePurpose:
type: string
enum:
- assistants
title: OpenAIFilePurpose
description: >-
Valid purpose values for OpenAI Files API.
ListOpenAIFileResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/OpenAIFileObject'
description: List of file objects
has_more:
type: boolean
first_id:
type: string
last_id:
type: string
object:
type: string
const: list
default: list
description: The object type, which is always "list"
additionalProperties: false
required:
- data
- has_more
- first_id
- last_id
- object
title: ListOpenAIFileResponse
description: >-
Response for listing files in OpenAI Files API.
OpenAIFileObject:
type: object
properties:
object:
type: string
const: file
default: file
description: The object type, which is always "file"
id:
type: string
description: >-
The file identifier, which can be referenced in the API endpoints
bytes:
type: integer
description: The size of the file, in bytes
created_at:
type: integer
description: >-
The Unix timestamp (in seconds) for when the file was created
expires_at:
type: integer
description: >-
The Unix timestamp (in seconds) for when the file expires
filename:
type: string
description: The name of the file
purpose:
type: string
enum:
- assistants
description: The intended purpose of the file
additionalProperties: false
required:
- object
- id
- bytes
- created_at
- expires_at
- filename
- purpose
title: OpenAIFileObject
description: >-
OpenAI File object as defined in the OpenAI Files API.
OpenAIModel: OpenAIModel:
type: object type: object
properties: properties:
@ -8373,6 +8328,9 @@ components:
required: required:
- data - data
title: OpenAIListModelsResponse title: OpenAIListModelsResponse
Response:
type: object
title: Response
DPOAlignmentConfig: DPOAlignmentConfig:
type: object type: object
properties: properties:

View file

@ -30,6 +30,9 @@ from llama_stack.strong_typing.schema import (
Schema, Schema,
SchemaOptions, SchemaOptions,
) )
from typing import get_origin, get_args
from typing import Annotated
from fastapi import UploadFile
from llama_stack.strong_typing.serialization import json_dump_string, object_to_json from llama_stack.strong_typing.serialization import json_dump_string, object_to_json
from .operations import ( from .operations import (
@ -618,6 +621,45 @@ class Generator:
}, },
required=True, required=True,
) )
# data passed in request body as multipart/form-data
elif op.multipart_params:
builder = ContentBuilder(self.schema_builder)
# Create schema properties for multipart form fields
properties = {}
required_fields = []
for name, param_type in op.multipart_params:
if get_origin(param_type) is Annotated:
base_type = get_args(param_type)[0]
else:
base_type = param_type
if base_type is UploadFile:
# File upload
properties[name] = {
"type": "string",
"format": "binary"
}
else:
# Form field
properties[name] = self.schema_builder.classdef_to_ref(base_type)
required_fields.append(name)
multipart_schema = {
"type": "object",
"properties": properties,
"required": required_fields
}
requestBody = RequestBody(
content={
"multipart/form-data": {
"schema": multipart_schema
}
},
required=True,
)
# data passed in payload as JSON and mapped to request parameters # data passed in payload as JSON and mapped to request parameters
elif op.request_params: elif op.request_params:
builder = ContentBuilder(self.schema_builder) builder = ContentBuilder(self.schema_builder)

View file

@ -17,6 +17,12 @@ from termcolor import colored
from llama_stack.strong_typing.inspection import get_signature from llama_stack.strong_typing.inspection import get_signature
from typing import get_origin, get_args
from fastapi import UploadFile
from fastapi.params import File, Form
from typing import Annotated
def split_prefix( def split_prefix(
s: str, sep: str, prefix: Union[str, Iterable[str]] s: str, sep: str, prefix: Union[str, Iterable[str]]
@ -82,6 +88,7 @@ class EndpointOperation:
:param path_params: Parameters of the operation signature that are passed in the path component of the URL string. :param path_params: Parameters of the operation signature that are passed in the path component of the URL string.
:param query_params: Parameters of the operation signature that are passed in the query string as `key=value` pairs. :param query_params: Parameters of the operation signature that are passed in the query string as `key=value` pairs.
:param request_params: The parameter that corresponds to the data transmitted in the request body. :param request_params: The parameter that corresponds to the data transmitted in the request body.
:param multipart_params: Parameters that indicate multipart/form-data request body.
:param event_type: The Python type of the data that is transmitted out-of-band (e.g. via websockets) while the operation is in progress. :param event_type: The Python type of the data that is transmitted out-of-band (e.g. via websockets) while the operation is in progress.
:param response_type: The Python type of the data that is transmitted in the response body. :param response_type: The Python type of the data that is transmitted in the response body.
:param http_method: The HTTP method used to invoke the endpoint such as POST, GET or PUT. :param http_method: The HTTP method used to invoke the endpoint such as POST, GET or PUT.
@ -98,6 +105,7 @@ class EndpointOperation:
path_params: List[OperationParameter] path_params: List[OperationParameter]
query_params: List[OperationParameter] query_params: List[OperationParameter]
request_params: Optional[OperationParameter] request_params: Optional[OperationParameter]
multipart_params: List[OperationParameter]
event_type: Optional[type] event_type: Optional[type]
response_type: type response_type: type
http_method: HTTPMethod http_method: HTTPMethod
@ -252,6 +260,7 @@ def get_endpoint_operations(
path_params = [] path_params = []
query_params = [] query_params = []
request_params = [] request_params = []
multipart_params = []
for param_name, parameter in signature.parameters.items(): for param_name, parameter in signature.parameters.items():
param_type = _get_annotation_type(parameter.annotation, func_ref) param_type = _get_annotation_type(parameter.annotation, func_ref)
@ -266,6 +275,8 @@ def get_endpoint_operations(
f"parameter '{param_name}' in function '{func_name}' has no type annotation" f"parameter '{param_name}' in function '{func_name}' has no type annotation"
) )
is_multipart = _is_multipart_param(param_type)
if prefix in ["get", "delete"]: if prefix in ["get", "delete"]:
if route_params is not None and param_name in route_params: if route_params is not None and param_name in route_params:
path_params.append((param_name, param_type)) path_params.append((param_name, param_type))
@ -274,6 +285,8 @@ def get_endpoint_operations(
else: else:
if route_params is not None and param_name in route_params: if route_params is not None and param_name in route_params:
path_params.append((param_name, param_type)) path_params.append((param_name, param_type))
elif is_multipart:
multipart_params.append((param_name, param_type))
else: else:
request_params.append((param_name, param_type)) request_params.append((param_name, param_type))
@ -333,6 +346,7 @@ def get_endpoint_operations(
path_params=path_params, path_params=path_params,
query_params=query_params, query_params=query_params,
request_params=request_params, request_params=request_params,
multipart_params=multipart_params,
event_type=event_type, event_type=event_type,
response_type=response_type, response_type=response_type,
http_method=http_method, http_method=http_method,
@ -377,3 +391,34 @@ def get_endpoint_events(endpoint: type) -> Dict[str, type]:
results[param_type.__name__] = param_type results[param_type.__name__] = param_type
return results return results
def _is_multipart_param(param_type: type) -> bool:
"""
Check if a parameter type indicates multipart form data.
Returns True if the type is:
- UploadFile
- Annotated[UploadFile, File()]
- Annotated[str, Form()]
- Annotated[Any, File()]
- Annotated[Any, Form()]
"""
if param_type is UploadFile:
return True
# Check for Annotated types
origin = get_origin(param_type)
if origin is None:
return False
if origin is Annotated:
args = get_args(param_type)
if len(args) < 2:
return False
# Check the annotations for File() or Form()
for annotation in args[1:]:
if isinstance(annotation, (File, Form)):
return True
return False

View file

@ -153,6 +153,12 @@ def _validate_api_delete_method_returns_none(method) -> str | None:
return "has no return type annotation" return "has no return type annotation"
return_type = hints['return'] return_type = hints['return']
# Allow OpenAI endpoints to return response objects since they follow OpenAI specification
method_name = getattr(method, '__name__', '')
if method_name.startswith('openai_'):
return None
if return_type is not None and return_type is not type(None): if return_type is not None and return_type is not type(None):
return "does not return None where None is mandatory" return "does not return None where None is mandatory"

View file

@ -4,179 +4,158 @@
# This source code is licensed under the terms described in the LICENSE file in # This source code is licensed under the terms described in the LICENSE file in
# the root directory of this source tree. # the root directory of this source tree.
from typing import Protocol, runtime_checkable from enum import Enum
from typing import Annotated, Literal, Protocol, runtime_checkable
from fastapi import File, Form, Response, UploadFile
from pydantic import BaseModel from pydantic import BaseModel
from llama_stack.apis.common.responses import Order
from llama_stack.providers.utils.telemetry.trace_protocol import trace_protocol from llama_stack.providers.utils.telemetry.trace_protocol import trace_protocol
from llama_stack.schema_utils import json_schema_type, webmethod from llama_stack.schema_utils import json_schema_type, webmethod
@json_schema_type # OpenAI Files API Models
class FileUploadResponse(BaseModel): class OpenAIFilePurpose(str, Enum):
"""
Valid purpose values for OpenAI Files API.
""" """
Response after initiating a file upload session.
:param id: ID of the upload session ASSISTANTS = "assistants"
:param url: Upload URL for the file or file parts # TODO: Add other purposes as needed
:param offset: Upload content offset
:param size: Upload content size
@json_schema_type
class OpenAIFileObject(BaseModel):
"""
OpenAI File object as defined in the OpenAI Files API.
:param object: The object type, which is always "file"
:param id: The file identifier, which can be referenced in the API endpoints
:param bytes: The size of the file, in bytes
:param created_at: The Unix timestamp (in seconds) for when the file was created
:param expires_at: The Unix timestamp (in seconds) for when the file expires
:param filename: The name of the file
:param purpose: The intended purpose of the file
"""
object: Literal["file"] = "file"
id: str
bytes: int
created_at: int
expires_at: int
filename: str
purpose: OpenAIFilePurpose
@json_schema_type
class ListOpenAIFileResponse(BaseModel):
"""
Response for listing files in OpenAI Files API.
:param data: List of file objects
:param object: The object type, which is always "list"
"""
data: list[OpenAIFileObject]
has_more: bool
first_id: str
last_id: str
object: Literal["list"] = "list"
@json_schema_type
class OpenAIFileDeleteResponse(BaseModel):
"""
Response for deleting a file in OpenAI Files API.
:param id: The file identifier that was deleted
:param object: The object type, which is always "file"
:param deleted: Whether the file was successfully deleted
""" """
id: str id: str
url: str object: Literal["file"] = "file"
offset: int deleted: bool
size: int
@json_schema_type
class BucketResponse(BaseModel):
name: str
@json_schema_type
class ListBucketResponse(BaseModel):
"""
Response representing a list of file entries.
:param data: List of FileResponse entries
"""
data: list[BucketResponse]
@json_schema_type
class FileResponse(BaseModel):
"""
Response representing a file entry.
:param bucket: Bucket under which the file is stored (valid chars: a-zA-Z0-9_-)
:param key: Key under which the file is stored (valid chars: a-zA-Z0-9_-/.)
:param mime_type: MIME type of the file
:param url: Upload URL for the file contents
:param bytes: Size of the file in bytes
:param created_at: Timestamp of when the file was created
"""
bucket: str
key: str
mime_type: str
url: str
bytes: int
created_at: int
@json_schema_type
class ListFileResponse(BaseModel):
"""
Response representing a list of file entries.
:param data: List of FileResponse entries
"""
data: list[FileResponse]
@runtime_checkable @runtime_checkable
@trace_protocol @trace_protocol
class Files(Protocol): class Files(Protocol):
@webmethod(route="/files", method="POST") # OpenAI Files API Endpoints
async def create_upload_session( @webmethod(route="/openai/v1/files", method="POST")
async def openai_upload_file(
self, self,
bucket: str, file: Annotated[UploadFile, File()],
key: str, purpose: Annotated[OpenAIFilePurpose, Form()],
mime_type: str, ) -> OpenAIFileObject:
size: int,
) -> FileUploadResponse:
""" """
Create a new upload session for a file identified by a bucket and key. Upload a file that can be used across various endpoints.
:param bucket: Bucket under which the file is stored (valid chars: a-zA-Z0-9_-). The file upload should be a multipart form request with:
:param key: Key under which the file is stored (valid chars: a-zA-Z0-9_-/.). - file: The File object (not file name) to be uploaded.
:param mime_type: MIME type of the file. - purpose: The intended purpose of the uploaded file.
:param size: File size in bytes.
:returns: A FileUploadResponse. :param file: The uploaded file object containing content and metadata (filename, content_type, etc.).
:param purpose: The intended purpose of the uploaded file (e.g., "assistants", "fine-tune").
:returns: An OpenAIFileObject representing the uploaded file.
""" """
... ...
@webmethod(route="/files/session:{upload_id}", method="POST", raw_bytes_request_body=True) @webmethod(route="/openai/v1/files", method="GET")
async def upload_content_to_session( async def openai_list_files(
self, self,
upload_id: str, after: str | None = None,
) -> FileResponse | None: limit: int | None = 10000,
order: Order | None = Order.desc,
purpose: OpenAIFilePurpose | None = None,
) -> ListOpenAIFileResponse:
""" """
Upload file content to an existing upload session. Returns a list of files that belong to the user's organization.
On the server, request body will have the raw bytes that are uploaded.
:param upload_id: ID of the upload session. :param after: A cursor for use in pagination. `after` is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, ending with obj_foo, your subsequent call can include after=obj_foo in order to fetch the next page of the list.
:returns: A FileResponse or None if the upload is not complete. :param limit: A limit on the number of objects to be returned. Limit can range between 1 and 10,000, and the default is 10,000.
:param order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and `desc` for descending order.
:param purpose: Only return files with the given purpose.
:returns: An ListOpenAIFileResponse containing the list of files.
""" """
... ...
@webmethod(route="/files/session:{upload_id}", method="GET") @webmethod(route="/openai/v1/files/{file_id}", method="GET")
async def get_upload_session_info( async def openai_retrieve_file(
self, self,
upload_id: str, file_id: str,
) -> FileUploadResponse: ) -> OpenAIFileObject:
""" """
Returns information about an existsing upload session. Returns information about a specific file.
:param upload_id: ID of the upload session. :param file_id: The ID of the file to use for this request.
:returns: A FileUploadResponse. :returns: An OpenAIFileObject containing file information.
""" """
... ...
@webmethod(route="/files", method="GET") @webmethod(route="/openai/v1/files/{file_id}", method="DELETE")
async def list_all_buckets( async def openai_delete_file(
self, self,
bucket: str, file_id: str,
) -> ListBucketResponse: ) -> OpenAIFileDeleteResponse:
""" """
List all buckets. Delete a file.
:param bucket: Bucket name (valid chars: a-zA-Z0-9_-). :param file_id: The ID of the file to use for this request.
:returns: A ListBucketResponse. :returns: An OpenAIFileDeleteResponse indicating successful deletion.
""" """
... ...
@webmethod(route="/files/{bucket}", method="GET") @webmethod(route="/openai/v1/files/{file_id}/content", method="GET")
async def list_files_in_bucket( async def openai_retrieve_file_content(
self, self,
bucket: str, file_id: str,
) -> ListFileResponse: ) -> Response:
""" """
List all files in a bucket. Returns the contents of the specified file.
:param bucket: Bucket name (valid chars: a-zA-Z0-9_-). :param file_id: The ID of the file to use for this request.
:returns: A ListFileResponse. :returns: The raw file content as a binary response.
"""
...
@webmethod(route="/files/{bucket}/{key:path}", method="GET")
async def get_file(
self,
bucket: str,
key: str,
) -> FileResponse:
"""
Get a file info identified by a bucket and key.
:param bucket: Bucket name (valid chars: a-zA-Z0-9_-).
:param key: Key under which the file is stored (valid chars: a-zA-Z0-9_-/.).
:returns: A FileResponse.
"""
...
@webmethod(route="/files/{bucket}/{key:path}", method="DELETE")
async def delete_file(
self,
bucket: str,
key: str,
) -> None:
"""
Delete a file identified by a bucket and key.
:param bucket: Bucket name (valid chars: a-zA-Z0-9_-).
:param key: Key under which the file is stored (valid chars: a-zA-Z0-9_-/.).
""" """
... ...