feat: adding endpoints for files and uploads (#1070)

Summary:
Adds spec definitions for file uploads operations.

This API focuses around two high level operations:
* Initiating and managing upload session
* Accessing uploaded file information

Usage examples:

To start a file upload session:
```
curl -X POST https://localhost:8321/v1/files \
-d '{
   "key": "image123.jpg',
   "bucket": "images",
   "mime_type": "image/jpg",
   "size": 12345
}'

# Returns
{
  “id”: <session_id>
  “url”: “https://localhost:8321/v1/files/session:<session_id>”,
  "offset": 0,
  "size": 12345
}

```

To upload file content to an existing session
```
curl -i -X POST "https://localhost:8321/v1/files/session:<session_id> \
  --data-binary @<path_to_local_file>

# Returns
{
  "key": "image123.jpg",
  "bucket": "images",
  "mime_type": "image/jpg",
  "bytes": 12345,
  "created_at": 1737492240
}

# Implementing on server side (Flask example for simplicity):
@app.route('/uploads/{upload_id}', methods=['POST'])
def upload_content_to_session(upload_id):
    try:
        # Get the binary file data from the request body
        file_data = request.data

        # Save the file to disk
        save_path = f"./uploads/{upload_id}"
        with open(save_path, 'wb') as f:
            f.write(file_data)
        return {__uploaded_file_json__}, 200
    except Exception as e:
        return 500

```

To read information about an existing upload session
```
curl -i -X GET "https://localhost:8321/v1/files/session:<session_id>

# Returns
{
  “id”: <session_id>
  “url”: “https://localhost:8321/v1/files/session:<session_id>”,
  "offset": 1024,
  "size": 12345
}
```

To list buckets
```
GET /files

# Returns
{
  "data": [
     {"name": "bucket1"},
     {"name": "bucket2"},
   ]
}
```

To list all files in a bucket
```
GET /files/{bucket}

# Returns
{
  "data": [
    {
      "key": "shiba.jpg",
      "bucket": "dogs",
      "mime_type": "image/jpg",
      "bytes": 82334,
      "created_at": 1737492240,
    },
    {
      "key": "persian_cat.jpg",
      "mime_type": "image/jpg",
      "bucket": "cats",
      "bytes": 39924,
      "created_at": 1727493440,
    },
  ]
}
```

To get specific file info
```
GET /files/{bucket}/{key}

{
  "key": "shiba.jpg",
  "bucket": "dogs",
  "mime_type": "image/jpg",
  "bytes": 82334,
  "created_at": 1737492240,
}

```

To delete specific file
```
DELETE /files/{bucket}/{key}

{
  "key": "shiba.jpg",
  "bucket": "dogs",
  "mime_type": "image/jpg",
  "bytes": 82334,
  "created_at": 1737492240,
}

```
This commit is contained in:
Vladimir Ivić 2025-02-20 13:09:00 -08:00 committed by GitHub
parent eddef0b2ae
commit f7161611c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 897 additions and 3 deletions

View file

@ -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",