Skip to content

Commit 6bc8850

Browse files
authored
Merge pull request #810 from tisnik/lcore-780-info-about-selected-rag
LCORE-780: REST API endpoint to return info about selected RAG
2 parents 7042ac9 + c49dca8 commit 6bc8850

File tree

6 files changed

+505
-1
lines changed

6 files changed

+505
-1
lines changed

docs/openapi.json

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,58 @@
348348
}
349349
}
350350
},
351+
"/v1/rags/{rag_id}": {
352+
"get": {
353+
"tags": [
354+
"rags"
355+
],
356+
"summary": "Get Rag Endpoint Handler",
357+
"description": "Retrieve a single RAG by its unique ID.\n\nRaises:\n HTTPException:\n - 404 if RAG with the given ID is not found,\n - 500 if unable to connect to Llama Stack,\n - 500 for any unexpected retrieval errors.\n\nReturns:\n RAGResponse: A single RAG's details",
358+
"operationId": "get_rag_endpoint_handler_v1_rags__rag_id__get",
359+
"parameters": [
360+
{
361+
"name": "rag_id",
362+
"in": "path",
363+
"required": true,
364+
"schema": {
365+
"type": "string",
366+
"title": "Rag Id"
367+
}
368+
}
369+
],
370+
"responses": {
371+
"200": {
372+
"description": "Successful Response",
373+
"content": {
374+
"application/json": {
375+
"schema": {
376+
"$ref": "#/components/schemas/RAGInfoResponse"
377+
}
378+
}
379+
}
380+
},
381+
"404": {
382+
"response": "RAG with given id not found",
383+
"description": "Not Found"
384+
},
385+
"500": {
386+
"response": "Unable to retrieve list of RAGs",
387+
"cause": "Connection to Llama Stack is broken",
388+
"description": "Internal Server Error"
389+
},
390+
"422": {
391+
"description": "Validation Error",
392+
"content": {
393+
"application/json": {
394+
"schema": {
395+
"$ref": "#/components/schemas/HTTPValidationError"
396+
}
397+
}
398+
}
399+
}
400+
}
401+
}
402+
},
351403
"/v1/query": {
352404
"post": {
353405
"tags": [
@@ -3918,6 +3970,108 @@
39183970
"title": "RAGChunk",
39193971
"description": "Model representing a RAG chunk used in the response."
39203972
},
3973+
"RAGInfoResponse": {
3974+
"properties": {
3975+
"id": {
3976+
"type": "string",
3977+
"title": "Id",
3978+
"description": "Vector DB unique ID",
3979+
"examples": [
3980+
"vs_00000000_0000_0000"
3981+
]
3982+
},
3983+
"name": {
3984+
"anyOf": [
3985+
{
3986+
"type": "string"
3987+
},
3988+
{
3989+
"type": "null"
3990+
}
3991+
],
3992+
"title": "Name",
3993+
"description": "Human readable vector DB name",
3994+
"examples": [
3995+
"Faiss Store with Knowledge base"
3996+
]
3997+
},
3998+
"created_at": {
3999+
"type": "integer",
4000+
"title": "Created At",
4001+
"description": "When the vector store was created, represented as Unix time",
4002+
"examples": [
4003+
1763391371
4004+
]
4005+
},
4006+
"last_active_at": {
4007+
"anyOf": [
4008+
{
4009+
"type": "integer"
4010+
},
4011+
{
4012+
"type": "null"
4013+
}
4014+
],
4015+
"title": "Last Active At",
4016+
"description": "When the vector store was last active, represented as Unix time",
4017+
"examples": [
4018+
1763391371
4019+
]
4020+
},
4021+
"usage_bytes": {
4022+
"type": "integer",
4023+
"title": "Usage Bytes",
4024+
"description": "Storage byte(s) used by this vector DB",
4025+
"examples": [
4026+
0
4027+
]
4028+
},
4029+
"expires_at": {
4030+
"anyOf": [
4031+
{
4032+
"type": "integer"
4033+
},
4034+
{
4035+
"type": "null"
4036+
}
4037+
],
4038+
"title": "Expires At",
4039+
"description": "When the vector store expires, represented as Unix time",
4040+
"examples": [
4041+
1763391371
4042+
]
4043+
},
4044+
"object": {
4045+
"type": "string",
4046+
"title": "Object",
4047+
"description": "Object type",
4048+
"examples": [
4049+
"vector_store"
4050+
]
4051+
},
4052+
"status": {
4053+
"type": "string",
4054+
"title": "Status",
4055+
"description": "Vector DB status",
4056+
"examples": [
4057+
"completed"
4058+
]
4059+
}
4060+
},
4061+
"type": "object",
4062+
"required": [
4063+
"id",
4064+
"name",
4065+
"created_at",
4066+
"last_active_at",
4067+
"usage_bytes",
4068+
"expires_at",
4069+
"object",
4070+
"status"
4071+
],
4072+
"title": "RAGInfoResponse",
4073+
"description": "Model representing a response with information about RAG DB."
4074+
},
39214075
"RAGListResponse": {
39224076
"properties": {
39234077
"rags": {

docs/openapi.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,38 @@ Returns:
220220
|-------------|-------------|-----------|
221221
| 200 | Successful Response | [RAGListResponse](#raglistresponse) |
222222
| 500 | Connection to Llama Stack is broken | |
223+
## GET `/v1/rags/{rag_id}`
224+
225+
> **Get Rag Endpoint Handler**
226+
227+
Retrieve a single RAG by its unique ID.
228+
229+
Raises:
230+
HTTPException:
231+
- 404 if RAG with the given ID is not found,
232+
- 500 if unable to connect to Llama Stack,
233+
- 500 for any unexpected retrieval errors.
234+
235+
Returns:
236+
RAGResponse: A single RAG's details
237+
238+
239+
240+
### 🔗 Parameters
241+
242+
| Name | Type | Required | Description |
243+
|------|------|----------|-------------|
244+
| rag_id | string | True | |
245+
246+
247+
### ✅ Responses
248+
249+
| Status Code | Description | Component |
250+
|-------------|-------------|-----------|
251+
| 200 | Successful Response | [RAGInfoResponse](#raginforesponse) |
252+
| 404 | Not Found | |
253+
| 500 | Internal Server Error | |
254+
| 422 | Validation Error | [HTTPValidationError](#httpvalidationerror) |
223255
## POST `/v1/query`
224256

225257
> **Query Endpoint Handler**
@@ -1688,6 +1720,24 @@ Model representing a RAG chunk used in the response.
16881720
| score | | Relevance score |
16891721

16901722

1723+
## RAGInfoResponse
1724+
1725+
1726+
Model representing a response with information about RAG DB.
1727+
1728+
1729+
| Field | Type | Description |
1730+
|-------|------|-------------|
1731+
| id | string | Vector DB unique ID |
1732+
| name | | Human readable vector DB name |
1733+
| created_at | integer | When the vector store was created, represented as Unix time |
1734+
| last_active_at | | When the vector store was last active, represented as Unix time |
1735+
| usage_bytes | integer | Storage byte(s) used by this vector DB |
1736+
| expires_at | | When the vector store expires, represented as Unix time |
1737+
| object | string | Object type |
1738+
| status | string | Vector DB status |
1739+
1740+
16911741
## RAGListResponse
16921742

16931743

docs/output.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,38 @@ Returns:
220220
|-------------|-------------|-----------|
221221
| 200 | Successful Response | [RAGListResponse](#raglistresponse) |
222222
| 500 | Connection to Llama Stack is broken | |
223+
## GET `/v1/rags/{rag_id}`
224+
225+
> **Get Rag Endpoint Handler**
226+
227+
Retrieve a single RAG by its unique ID.
228+
229+
Raises:
230+
HTTPException:
231+
- 404 if RAG with the given ID is not found,
232+
- 500 if unable to connect to Llama Stack,
233+
- 500 for any unexpected retrieval errors.
234+
235+
Returns:
236+
RAGResponse: A single RAG's details
237+
238+
239+
240+
### 🔗 Parameters
241+
242+
| Name | Type | Required | Description |
243+
|------|------|----------|-------------|
244+
| rag_id | string | True | |
245+
246+
247+
### ✅ Responses
248+
249+
| Status Code | Description | Component |
250+
|-------------|-------------|-----------|
251+
| 200 | Successful Response | [RAGInfoResponse](#raginforesponse) |
252+
| 404 | Not Found | |
253+
| 500 | Internal Server Error | |
254+
| 422 | Validation Error | [HTTPValidationError](#httpvalidationerror) |
223255
## POST `/v1/query`
224256

225257
> **Query Endpoint Handler**
@@ -1688,6 +1720,24 @@ Model representing a RAG chunk used in the response.
16881720
| score | | Relevance score |
16891721

16901722

1723+
## RAGInfoResponse
1724+
1725+
1726+
Model representing a response with information about RAG DB.
1727+
1728+
1729+
| Field | Type | Description |
1730+
|-------|------|-------------|
1731+
| id | string | Vector DB unique ID |
1732+
| name | | Human readable vector DB name |
1733+
| created_at | integer | When the vector store was created, represented as Unix time |
1734+
| last_active_at | | When the vector store was last active, represented as Unix time |
1735+
| usage_bytes | integer | Storage byte(s) used by this vector DB |
1736+
| expires_at | | When the vector store expires, represented as Unix time |
1737+
| object | string | Object type |
1738+
| status | string | Vector DB status |
1739+
1740+
16911741
## RAGListResponse
16921742

16931743

src/app/endpoints/rags.py

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from client import AsyncLlamaStackClientHolder
1414
from configuration import configuration
1515
from models.config import Action
16-
from models.responses import RAGListResponse
16+
from models.responses import RAGListResponse, RAGInfoResponse
1717
from utils.endpoints import check_configuration_loaded
1818

1919
logger = logging.getLogger(__name__)
@@ -31,6 +31,15 @@
3131
500: {"description": "Connection to Llama Stack is broken"},
3232
}
3333

34+
rag_responses: dict[int | str, dict[str, Any]] = {
35+
200: {},
36+
404: {"response": "RAG with given id not found"},
37+
500: {
38+
"response": "Unable to retrieve list of RAGs",
39+
"cause": "Connection to Llama Stack is broken",
40+
},
41+
}
42+
3443

3544
@router.get("/rags", responses=rags_responses)
3645
@authorize(Action.LIST_RAGS)
@@ -94,3 +103,72 @@ async def rags_endpoint_handler(
94103
"cause": str(e),
95104
},
96105
) from e
106+
107+
108+
@router.get("/rags/{rag_id}", responses=rag_responses)
109+
@authorize(Action.GET_RAG)
110+
async def get_rag_endpoint_handler(
111+
request: Request,
112+
rag_id: str,
113+
auth: Annotated[AuthTuple, Depends(get_auth_dependency())],
114+
) -> RAGInfoResponse:
115+
"""Retrieve a single RAG by its unique ID.
116+
117+
Raises:
118+
HTTPException:
119+
- 404 if RAG with the given ID is not found,
120+
- 500 if unable to connect to Llama Stack,
121+
- 500 for any unexpected retrieval errors.
122+
123+
Returns:
124+
RAGInfoResponse: A single RAG's details
125+
"""
126+
# Used only by the middleware
127+
_ = auth
128+
129+
# Nothing interesting in the request
130+
_ = request
131+
132+
check_configuration_loaded(configuration)
133+
134+
llama_stack_configuration = configuration.llama_stack_configuration
135+
logger.info("Llama stack config: %s", llama_stack_configuration)
136+
137+
try:
138+
# try to get Llama Stack client
139+
client = AsyncLlamaStackClientHolder().get_client()
140+
# retrieve info about RAG
141+
rag_info = await client.vector_stores.retrieve(rag_id)
142+
return RAGInfoResponse(
143+
id=rag_info.id,
144+
name=rag_info.name,
145+
created_at=rag_info.created_at,
146+
last_active_at=rag_info.last_active_at,
147+
expires_at=rag_info.expires_at,
148+
object=rag_info.object,
149+
status=rag_info.status,
150+
usage_bytes=rag_info.usage_bytes,
151+
)
152+
153+
# connection to Llama Stack server
154+
except HTTPException:
155+
raise
156+
except APIConnectionError as e:
157+
logger.error("Unable to connect to Llama Stack: %s", e)
158+
raise HTTPException(
159+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
160+
detail={
161+
"response": "Unable to connect to Llama Stack",
162+
"cause": str(e),
163+
},
164+
) from e
165+
# any other exception that can occur during model listing
166+
except Exception as e:
167+
logger.error("Unable to retrieve info about RAG: %s", e)
168+
raise HTTPException(
169+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
170+
detail={
171+
"response": "Unable to retrieve info about RAG",
172+
"cause": str(e),
173+
},
174+
) from e

0 commit comments

Comments
 (0)