diff --git a/docs/_static/llama-stack-spec.html b/docs/_static/llama-stack-spec.html
index 2b6e1d11c..02d05776d 100644
--- a/docs/_static/llama-stack-spec.html
+++ b/docs/_static/llama-stack-spec.html
@@ -678,6 +678,65 @@
}
}
},
+ "/v1/files": {
+ "get": {
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListBucketResponse"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Files (Coming Soon)"
+ ],
+ "description": "List all buckets.",
+ "parameters": [
+ {
+ "name": "bucket",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ]
+ },
+ "post": {
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FileUploadResponse"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Files (Coming Soon)"
+ ],
+ "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}": {
"delete": {
"responses": {
@@ -779,6 +838,84 @@
]
}
},
+ "/v1/files/{bucket}/{key}": {
+ "get": {
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FileResponse"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Files (Coming Soon)"
+ ],
+ "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",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FileResponse"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Files (Coming Soon)"
+ ],
+ "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": {
"post": {
"responses": {
@@ -1470,6 +1607,91 @@
"parameters": []
}
},
+ "/v1/files/session:{upload_id}": {
+ "get": {
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/FileUploadResponse"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Files (Coming Soon)"
+ ],
+ "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": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/FileResponse"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Files (Coming Soon)"
+ ],
+ "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}": {
"get": {
"responses": {
@@ -1826,6 +2048,37 @@
}
}
},
+ "/v1/files/{bucket}": {
+ "get": {
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListFileResponse"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Files (Coming Soon)"
+ ],
+ "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": {
"get": {
"responses": {
@@ -5441,6 +5694,105 @@
],
"title": "AgentTurnResponseTurnStartPayload"
},
+ "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."
+ },
+ "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."
+ },
"EmbeddingsRequest": {
"type": "object",
"properties": {
@@ -6756,6 +7108,37 @@
],
"title": "ToolInvocationResult"
},
+ "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."
+ },
"ListDatasetsResponse": {
"type": "object",
"properties": {
@@ -6772,6 +7155,24 @@
],
"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": {
"type": "object",
"properties": {
@@ -8543,6 +8944,9 @@
{
"name": "Eval"
},
+ {
+ "name": "Files (Coming Soon)"
+ },
{
"name": "Inference",
"description": "This API provides the raw interface to the underlying models. Two kinds of models are supported:\n- LLM models: these models generate \"raw\" and \"chat\" (conversational) completions.\n- Embedding models: these models generate embeddings to be used for semantic search.",
@@ -8598,6 +9002,7 @@
"DatasetIO",
"Datasets",
"Eval",
+ "Files (Coming Soon)",
"Inference",
"Inspect",
"Models",
diff --git a/docs/_static/llama-stack-spec.yaml b/docs/_static/llama-stack-spec.yaml
index 99300fedf..f79120f1d 100644
--- a/docs/_static/llama-stack-spec.yaml
+++ b/docs/_static/llama-stack-spec.yaml
@@ -406,6 +406,43 @@ paths:
schema:
$ref: '#/components/schemas/CreateAgentTurnRequest'
required: true
+ /v1/files:
+ get:
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ListBucketResponse'
+ tags:
+ - Files (Coming Soon)
+ description: List all buckets.
+ parameters:
+ - name: bucket
+ in: query
+ required: true
+ schema:
+ type: string
+ post:
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FileUploadResponse'
+ tags:
+ - Files (Coming Soon)
+ 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}:
delete:
responses:
@@ -468,6 +505,59 @@ paths:
required: true
schema:
type: string
+ /v1/files/{bucket}/{key}:
+ get:
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FileResponse'
+ tags:
+ - Files (Coming Soon)
+ 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
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FileResponse'
+ tags:
+ - Files (Coming Soon)
+ 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:
post:
responses:
@@ -875,6 +965,57 @@ paths:
- PostTraining (Coming Soon)
description: ''
parameters: []
+ /v1/files/session:{upload_id}:
+ get:
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ oneOf:
+ - $ref: '#/components/schemas/FileUploadResponse'
+ - type: 'null'
+ tags:
+ - Files (Coming Soon)
+ 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: OK
+ content:
+ application/json:
+ schema:
+ oneOf:
+ - $ref: '#/components/schemas/FileResponse'
+ - type: 'null'
+ tags:
+ - Files (Coming Soon)
+ 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}:
get:
responses:
@@ -1091,6 +1232,25 @@ paths:
schema:
$ref: '#/components/schemas/RegisterDatasetRequest'
required: true
+ /v1/files/{bucket}:
+ get:
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ListFileResponse'
+ tags:
+ - Files (Coming Soon)
+ 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:
get:
responses:
@@ -3508,6 +3668,87 @@ components:
- event_type
- turn_id
title: AgentTurnResponseTurnStartPayload
+ 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.
+ 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.
EmbeddingsRequest:
type: object
properties:
@@ -4339,6 +4580,29 @@ components:
required:
- content
title: ToolInvocationResult
+ 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.
ListDatasetsResponse:
type: object
properties:
@@ -4350,6 +4614,20 @@ components:
required:
- data
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:
type: object
properties:
@@ -5467,6 +5745,7 @@ tags:
- name: DatasetIO
- name: Datasets
- name: Eval
+ - name: Files (Coming Soon)
- name: Inference
description: >-
This API provides the raw interface to the underlying models. Two kinds of models
@@ -5501,6 +5780,7 @@ x-tagGroups:
- DatasetIO
- Datasets
- Eval
+ - Files (Coming Soon)
- Inference
- Inspect
- Models
diff --git a/docs/openapi_generator/pyopenapi/generator.py b/docs/openapi_generator/pyopenapi/generator.py
index 60cd7a242..4220cfc05 100644
--- a/docs/openapi_generator/pyopenapi/generator.py
+++ b/docs/openapi_generator/pyopenapi/generator.py
@@ -477,6 +477,7 @@ class Generator:
"SyntheticDataGeneration",
"PostTraining",
"BatchInference",
+ "Files",
]:
op.defining_class.__name__ = f"{op.defining_class.__name__} (Coming Soon)"
print(op.defining_class.__name__)
@@ -520,8 +521,30 @@ class Generator:
# parameters passed anywhere
parameters = path_parameters + query_parameters
- # data passed in payload
- if op.request_params:
+ webmethod = getattr(op.func_ref, "__webmethod__", None)
+ raw_bytes_request_body = False
+ if webmethod:
+ raw_bytes_request_body = getattr(webmethod, "raw_bytes_request_body", False)
+
+ # data passed in request body as raw bytes cannot have request parameters
+ if raw_bytes_request_body and op.request_params:
+ raise ValueError("Cannot have both raw bytes request body and request parameters")
+
+ # data passed in request body as raw bytes
+ if raw_bytes_request_body:
+ requestBody = RequestBody(
+ content={
+ "application/octet-stream": {
+ "schema": {
+ "type": "string",
+ "format": "binary",
+ }
+ }
+ },
+ required=True,
+ )
+ # data passed in payload as JSON and mapped to request parameters
+ elif op.request_params:
builder = ContentBuilder(self.schema_builder)
first = next(iter(op.request_params))
request_name, request_type = first
diff --git a/docs/openapi_generator/pyopenapi/specification.py b/docs/openapi_generator/pyopenapi/specification.py
index 9e5363b4a..d3e5a1f19 100644
--- a/docs/openapi_generator/pyopenapi/specification.py
+++ b/docs/openapi_generator/pyopenapi/specification.py
@@ -78,7 +78,7 @@ class MediaType:
@dataclass
class RequestBody:
- content: Dict[str, MediaType]
+ content: Dict[str, MediaType | Dict[str, Any]]
description: Optional[str] = None
required: Optional[bool] = None
diff --git a/llama_stack/apis/files/__init__.py b/llama_stack/apis/files/__init__.py
new file mode 100644
index 000000000..269baf177
--- /dev/null
+++ b/llama_stack/apis/files/__init__.py
@@ -0,0 +1,7 @@
+# Copyright (c) Meta Platforms, Inc. and affiliates.
+# All rights reserved.
+#
+# This source code is licensed under the terms described in the LICENSE file in
+# the root directory of this source tree.
+
+from .files import * # noqa: F401 F403
diff --git a/llama_stack/apis/files/files.py b/llama_stack/apis/files/files.py
new file mode 100644
index 000000000..f17fadc8c
--- /dev/null
+++ b/llama_stack/apis/files/files.py
@@ -0,0 +1,174 @@
+# Copyright (c) Meta Platforms, Inc. and affiliates.
+# All rights reserved.
+#
+# This source code is licensed under the terms described in the LICENSE file in
+# the root directory of this source tree.
+
+from typing import List, Optional, Protocol, runtime_checkable
+
+from pydantic import BaseModel
+
+from llama_stack.providers.utils.telemetry.trace_protocol import trace_protocol
+from llama_stack.schema_utils import json_schema_type, webmethod
+
+
+@json_schema_type
+class FileUploadResponse(BaseModel):
+ """
+ Response after initiating a file upload session.
+
+ :param id: ID of the upload session
+ :param url: Upload URL for the file or file parts
+ :param offset: Upload content offset
+ :param size: Upload content size
+ """
+
+ id: str
+ url: str
+ offset: int
+ 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
+@trace_protocol
+class Files(Protocol):
+ @webmethod(route="/files", method="POST")
+ async def create_upload_session(
+ self,
+ bucket: str,
+ key: str,
+ mime_type: str,
+ size: int,
+ ) -> FileUploadResponse:
+ """
+ Create a new upload session for a file identified by a bucket and key.
+
+ :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 size: File size in bytes
+ """
+ ...
+
+ @webmethod(route="/files/session:{upload_id}", method="POST", raw_bytes_request_body=True)
+ async def upload_content_to_session(
+ self,
+ upload_id: str,
+ ) -> Optional[FileResponse]:
+ """
+ Upload file content to an existing upload session.
+ On the server, request body will have the raw bytes that are uploaded.
+
+ :param upload_id: ID of the upload session
+ """
+ ...
+
+ @webmethod(route="/files/session:{upload_id}", method="GET")
+ async def get_upload_session_info(
+ self,
+ upload_id: str,
+ ) -> Optional[FileUploadResponse]:
+ """
+ Returns information about an existsing upload session
+
+ :param upload_id: ID of the upload session
+ """
+ ...
+
+ @webmethod(route="/files", method="GET")
+ async def list_all_buckets(
+ self,
+ bucket: str,
+ ) -> ListBucketResponse:
+ """
+ List all buckets.
+ """
+ ...
+
+ @webmethod(route="/files/{bucket}", method="GET")
+ async def list_files_in_bucket(
+ self,
+ bucket: str,
+ ) -> ListFileResponse:
+ """
+ List all files in a bucket.
+
+ :param bucket: Bucket name (valid chars: a-zA-Z0-9_-)
+ """
+ ...
+
+ @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_-/.)
+ """
+ ...
+
+ @webmethod(route="/files/{bucket}/{key:path}", method="DELETE")
+ async def delete_file(
+ self,
+ bucket: str,
+ key: str,
+ ) -> FileResponse:
+ """
+ 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_-/.)
+ """
+ ...
diff --git a/llama_stack/distribution/stack.py b/llama_stack/distribution/stack.py
index 9335dc3a9..1328c88ef 100644
--- a/llama_stack/distribution/stack.py
+++ b/llama_stack/distribution/stack.py
@@ -19,6 +19,7 @@ from llama_stack.apis.benchmarks import Benchmarks
from llama_stack.apis.datasetio import DatasetIO
from llama_stack.apis.datasets import Datasets
from llama_stack.apis.eval import Eval
+from llama_stack.apis.files import Files
from llama_stack.apis.inference import Inference
from llama_stack.apis.inspect import Inspect
from llama_stack.apis.models import Models
@@ -63,6 +64,7 @@ class LlamaStack(
ToolGroups,
ToolRuntime,
RAGToolRuntime,
+ Files,
):
pass
diff --git a/llama_stack/schema_utils.py b/llama_stack/schema_utils.py
index 56b9e5e4c..581404844 100644
--- a/llama_stack/schema_utils.py
+++ b/llama_stack/schema_utils.py
@@ -19,6 +19,7 @@ class WebMethod:
request_examples: Optional[List[Any]] = None
response_examples: Optional[List[Any]] = None
method: Optional[str] = None
+ raw_bytes_request_body: Optional[bool] = False
def webmethod(
@@ -27,6 +28,7 @@ def webmethod(
public: Optional[bool] = False,
request_examples: Optional[List[Any]] = None,
response_examples: Optional[List[Any]] = None,
+ raw_bytes_request_body: Optional[bool] = False,
) -> Callable[[T], T]:
"""
Decorator that supplies additional metadata to an endpoint operation function.
@@ -44,6 +46,7 @@ def webmethod(
public=public or False,
request_examples=request_examples,
response_examples=response_examples,
+ raw_bytes_request_body=raw_bytes_request_body,
)
return cls