Skip to content

Commit 01fc91b

Browse files
authored
feat(API): add queue API (#246)
1 parent 37d8f37 commit 01fc91b

File tree

9 files changed

+515
-4
lines changed

9 files changed

+515
-4
lines changed

docs/reference/api/index.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,58 @@ Delete an index.
126126

127127
- 404: Index not found
128128

129+
### GET /api/v1/queue
130+
131+
List all tasks in the queue.
132+
133+
Optionally filter by task type.
134+
135+
136+
#### Parameters
137+
138+
| Name | Type | Required | Description |
139+
|------|------|----------|-------------|
140+
| task_type | | False | |
141+
142+
143+
#### Responses
144+
145+
- 200: Successful Response
146+
147+
[TaskListResponse](#tasklistresponse)
148+
149+
- 500: Internal server error
150+
151+
- 401: Unauthorized
152+
153+
- 422: Invalid request
154+
155+
### GET /api/v1/queue/{task_id}
156+
157+
Get details of a specific task in the queue.
158+
159+
160+
#### Parameters
161+
162+
| Name | Type | Required | Description |
163+
|------|------|----------|-------------|
164+
| task_id | string | True | |
165+
166+
167+
#### Responses
168+
169+
- 200: Successful Response
170+
171+
[TaskResponse](#taskresponse)
172+
173+
- 500: Internal server error
174+
175+
- 401: Unauthorized
176+
177+
- 422: Invalid request
178+
179+
- 404: Task not found
180+
129181
### POST /api/v1/search
130182

131183
Search code snippets with filters matching MCP tool.
@@ -351,6 +403,64 @@ Snippet data for JSON:API responses.
351403
| attributes | | |
352404

353405

406+
### TaskAttributes
407+
408+
409+
Task attributes for JSON:API responses.
410+
411+
412+
| Field | Type | Description |
413+
|-------|------|-------------|
414+
| type | string | |
415+
| priority | integer | |
416+
| payload | object | |
417+
| created_at | | |
418+
| updated_at | | |
419+
420+
421+
### TaskData
422+
423+
424+
Task data for JSON:API responses.
425+
426+
427+
| Field | Type | Description |
428+
|-------|------|-------------|
429+
| type | string | |
430+
| id | string | |
431+
| attributes | | |
432+
433+
434+
### TaskListResponse
435+
436+
437+
JSON:API response for task list.
438+
439+
440+
| Field | Type | Description |
441+
|-------|------|-------------|
442+
| data | array | |
443+
444+
445+
### TaskResponse
446+
447+
448+
JSON:API response for single task.
449+
450+
451+
| Field | Type | Description |
452+
|-------|------|-------------|
453+
| data | | |
454+
455+
456+
### TaskType
457+
458+
459+
Task type.
460+
461+
462+
463+
354464
### ValidationError
355465

356466

docs/reference/api/openapi.json

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,110 @@
197197
}
198198
}
199199
},
200+
"/api/v1/queue": {
201+
"get": {
202+
"tags": [
203+
"queue"
204+
],
205+
"summary": "List Queue Tasks",
206+
"description": "List all tasks in the queue.\n\nOptionally filter by task type.",
207+
"operationId": "list_queue_tasks_api_v1_queue_get",
208+
"security": [
209+
{
210+
"Header (X-API-KEY)": []
211+
}
212+
],
213+
"parameters": [
214+
{
215+
"name": "task_type",
216+
"in": "query",
217+
"required": false,
218+
"schema": {
219+
"anyOf": [
220+
{
221+
"$ref": "#/components/schemas/TaskType"
222+
},
223+
{
224+
"type": "null"
225+
}
226+
],
227+
"title": "Task Type"
228+
}
229+
}
230+
],
231+
"responses": {
232+
"200": {
233+
"description": "Successful Response",
234+
"content": {
235+
"application/json": {
236+
"schema": {
237+
"$ref": "#/components/schemas/TaskListResponse"
238+
}
239+
}
240+
}
241+
},
242+
"500": {
243+
"description": "Internal server error"
244+
},
245+
"401": {
246+
"description": "Unauthorized"
247+
},
248+
"422": {
249+
"description": "Invalid request"
250+
}
251+
}
252+
}
253+
},
254+
"/api/v1/queue/{task_id}": {
255+
"get": {
256+
"tags": [
257+
"queue"
258+
],
259+
"summary": "Get Queue Task",
260+
"description": "Get details of a specific task in the queue.",
261+
"operationId": "get_queue_task_api_v1_queue__task_id__get",
262+
"security": [
263+
{
264+
"Header (X-API-KEY)": []
265+
}
266+
],
267+
"parameters": [
268+
{
269+
"name": "task_id",
270+
"in": "path",
271+
"required": true,
272+
"schema": {
273+
"type": "string",
274+
"title": "Task Id"
275+
}
276+
}
277+
],
278+
"responses": {
279+
"200": {
280+
"description": "Successful Response",
281+
"content": {
282+
"application/json": {
283+
"schema": {
284+
"$ref": "#/components/schemas/TaskResponse"
285+
}
286+
}
287+
}
288+
},
289+
"500": {
290+
"description": "Internal server error"
291+
},
292+
"401": {
293+
"description": "Unauthorized"
294+
},
295+
"422": {
296+
"description": "Invalid request"
297+
},
298+
"404": {
299+
"description": "Task not found"
300+
}
301+
}
302+
}
303+
},
200304
"/api/v1/search": {
201305
"post": {
202306
"tags": [
@@ -692,6 +796,118 @@
692796
"title": "SnippetData",
693797
"description": "Snippet data for JSON:API responses."
694798
},
799+
"TaskAttributes": {
800+
"properties": {
801+
"type": {
802+
"type": "string",
803+
"title": "Type"
804+
},
805+
"priority": {
806+
"type": "integer",
807+
"title": "Priority"
808+
},
809+
"payload": {
810+
"additionalProperties": true,
811+
"type": "object",
812+
"title": "Payload"
813+
},
814+
"created_at": {
815+
"anyOf": [
816+
{
817+
"type": "string",
818+
"format": "date-time"
819+
},
820+
{
821+
"type": "null"
822+
}
823+
],
824+
"title": "Created At"
825+
},
826+
"updated_at": {
827+
"anyOf": [
828+
{
829+
"type": "string",
830+
"format": "date-time"
831+
},
832+
{
833+
"type": "null"
834+
}
835+
],
836+
"title": "Updated At"
837+
}
838+
},
839+
"type": "object",
840+
"required": [
841+
"type",
842+
"priority",
843+
"payload",
844+
"created_at",
845+
"updated_at"
846+
],
847+
"title": "TaskAttributes",
848+
"description": "Task attributes for JSON:API responses."
849+
},
850+
"TaskData": {
851+
"properties": {
852+
"type": {
853+
"type": "string",
854+
"title": "Type",
855+
"default": "task"
856+
},
857+
"id": {
858+
"type": "string",
859+
"title": "Id"
860+
},
861+
"attributes": {
862+
"$ref": "#/components/schemas/TaskAttributes"
863+
}
864+
},
865+
"type": "object",
866+
"required": [
867+
"id",
868+
"attributes"
869+
],
870+
"title": "TaskData",
871+
"description": "Task data for JSON:API responses."
872+
},
873+
"TaskListResponse": {
874+
"properties": {
875+
"data": {
876+
"items": {
877+
"$ref": "#/components/schemas/TaskData"
878+
},
879+
"type": "array",
880+
"title": "Data"
881+
}
882+
},
883+
"type": "object",
884+
"required": [
885+
"data"
886+
],
887+
"title": "TaskListResponse",
888+
"description": "JSON:API response for task list."
889+
},
890+
"TaskResponse": {
891+
"properties": {
892+
"data": {
893+
"$ref": "#/components/schemas/TaskData"
894+
}
895+
},
896+
"type": "object",
897+
"required": [
898+
"data"
899+
],
900+
"title": "TaskResponse",
901+
"description": "JSON:API response for single task."
902+
},
903+
"TaskType": {
904+
"type": "integer",
905+
"enum": [
906+
1
907+
],
908+
"title": "TaskType",
909+
"description": "Task type."
910+
},
695911
"ValidationError": {
696912
"properties": {
697913
"loc": {

src/kodit/app.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212
from kodit.application.services.indexing_worker_service import IndexingWorkerService
1313
from kodit.application.services.sync_scheduler import SyncSchedulerService
1414
from kodit.config import AppContext
15-
from kodit.infrastructure.api.v1.routers import indexes_router, search_router
15+
from kodit.infrastructure.api.v1.routers import (
16+
indexes_router,
17+
queue_router,
18+
search_router,
19+
)
1620
from kodit.infrastructure.api.v1.schemas.context import AppLifespanState
1721
from kodit.mcp import mcp
1822
from kodit.middleware import ASGICancelledErrorMiddleware, logging_middleware
@@ -113,6 +117,7 @@ async def healthz() -> Response:
113117

114118
# Include API routers
115119
app.include_router(indexes_router)
120+
app.include_router(queue_router)
116121
app.include_router(search_router)
117122

118123

src/kodit/application/services/queue_service.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,8 @@ async def list_tasks(self, task_type: TaskType | None = None) -> list[Task]:
5050
"""List all tasks in the queue."""
5151
repo = SqlAlchemyTaskRepository(self.session)
5252
return await repo.list(task_type)
53+
54+
async def get_task(self, task_id: str) -> Task | None:
55+
"""Get a specific task by ID."""
56+
repo = SqlAlchemyTaskRepository(self.session)
57+
return await repo.get(task_id)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""API v1 modules."""
22

3-
from .routers import indexes_router, search_router
3+
from .routers import indexes_router, queue_router, search_router
44

5-
__all__ = ["indexes_router", "search_router"]
5+
__all__ = ["indexes_router", "queue_router", "search_router"]

0 commit comments

Comments
 (0)