feat: add retrieve_file endpoint to get file content [LET-6188] (#7485)

* feat: add retrieve_file endpoint to get file content

* Restore package-lock.json to main
This commit is contained in:
Ari Webb
2025-12-19 10:31:58 -08:00
committed by Caren Thomas
parent 61da937841
commit cb283373b7
2 changed files with 98 additions and 0 deletions

View File

@@ -3802,6 +3802,80 @@
}
}
},
"/v1/folders/{folder_id}/files/{file_id}": {
"get": {
"tags": ["folders"],
"summary": "Retrieve File",
"description": "Retrieve a file from a folder by ID.",
"operationId": "retrieve_file",
"parameters": [
{
"name": "folder_id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"minLength": 43,
"maxLength": 43,
"pattern": "^source-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
"description": "The ID of the source in the format 'source-<uuid4>'",
"examples": ["source-123e4567-e89b-42d3-8456-426614174000"],
"title": "Folder Id"
},
"description": "The ID of the source in the format 'source-<uuid4>'"
},
{
"name": "file_id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"minLength": 41,
"maxLength": 41,
"pattern": "^file-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
"description": "The ID of the file in the format 'file-<uuid4>'",
"examples": ["file-123e4567-e89b-42d3-8456-426614174000"],
"title": "File Id"
},
"description": "The ID of the file in the format 'file-<uuid4>'"
},
{
"name": "include_content",
"in": "query",
"required": false,
"schema": {
"type": "boolean",
"description": "Whether to include full file content",
"default": false,
"title": "Include Content"
},
"description": "Whether to include full file content"
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FileMetadata"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
},
"/v1/folders/{folder_id}/{file_id}": {
"delete": {
"tags": ["folders"],

View File

@@ -470,6 +470,30 @@ async def list_files_for_folder(
)
@router.get("/{folder_id}/files/{file_id}", response_model=FileMetadata, operation_id="retrieve_file")
async def retrieve_file(
folder_id: FolderId,
file_id: FileId,
include_content: bool = Query(False, description="Whether to include full file content"),
server: "SyncServer" = Depends(get_letta_server),
headers: HeaderParams = Depends(get_headers),
):
"""
Retrieve a file from a folder by ID.
"""
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
# NoResultFound will propagate and be handled as 404 by the global exception handler
file_metadata = await server.file_manager.get_file_by_id(
file_id=file_id, actor=actor, include_content=include_content, strip_directory_prefix=True
)
if file_metadata.source_id != folder_id:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"File with id={file_id} not found in folder {folder_id}")
return file_metadata
# @router.get("/{folder_id}/files/{file_id}", response_model=FileMetadata, operation_id="get_file_metadata")
# async def get_file_metadata(
# folder_id: str,