Skip to content

Commit 1eb4429

Browse files
feat: improve API request and response models and docs (#154)
* feat: improve API request and response models and docs
1 parent a29acb6 commit 1eb4429

File tree

13 files changed

+235
-153
lines changed

13 files changed

+235
-153
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ To use different LLM providers, for more info check out our <a href="https://top
5757

5858
If you are using Networkx, create an account on Graphistry to visualize results:
5959
```
60-
cognee.config.set_graphistry_config({
61-
"username": "YOUR_USERNAME",
62-
"password": "YOUR_PASSWORD"
63-
})
60+
cognee.config.set_graphistry_config({
61+
"username": "YOUR_USERNAME",
62+
"password": "YOUR_PASSWORD"
63+
})
6464
```
6565

6666
(Optional) To run the UI, go to cognee-frontend directory and run:

cognee-frontend/src/ui/Partials/SettingsModal/Settings.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export default function Settings({ onDone = () => {}, submitButtonText = 'Save'
8282
},
8383
body: JSON.stringify({
8484
llm: newLLMConfig,
85-
vectorDB: newVectorConfig,
85+
vectorDb: newVectorConfig,
8686
}),
8787
})
8888
.then(() => {
@@ -145,7 +145,7 @@ export default function Settings({ onDone = () => {}, submitButtonText = 'Save'
145145
settings.llm.model = settings.llm.models[settings.llm.provider.value][0];
146146
}
147147
setLLMConfig(settings.llm);
148-
setVectorDBConfig(settings.vectorDB);
148+
setVectorDBConfig(settings.vectorDb);
149149
};
150150
fetchConfig();
151151
}, []);

cognee/api/DTO.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from pydantic import BaseModel, ConfigDict
2+
from pydantic.alias_generators import to_camel, to_snake
3+
4+
5+
class OutDTO(BaseModel):
6+
model_config = ConfigDict(
7+
alias_generator = to_camel,
8+
populate_by_name = True,
9+
)
10+
11+
class InDTO(BaseModel):
12+
model_config = ConfigDict(
13+
alias_generator = to_camel,
14+
populate_by_name = True,
15+
)

cognee/api/client.py

Lines changed: 87 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
""" FastAPI server for the Cognee API. """
2+
from datetime import datetime
23
import os
4+
from uuid import UUID
35
import aiohttp
46
import uvicorn
57
import logging
68
import sentry_sdk
7-
from typing import Dict, Any, List, Union, Optional, Literal
9+
from typing import List, Union, Optional, Literal
810
from typing_extensions import Annotated
911
from fastapi import FastAPI, HTTPException, Form, UploadFile, Query, Depends
1012
from fastapi.responses import JSONResponse, FileResponse, Response
1113
from fastapi.middleware.cors import CORSMiddleware
1214
from pydantic import BaseModel
15+
16+
from cognee.api.DTO import InDTO, OutDTO
1317
from cognee.api.v1.search import SearchType
1418
from cognee.modules.users.models import User
1519
from cognee.modules.users.methods import get_authenticated_user
20+
from cognee.modules.pipelines.models import PipelineRunStatus
1621

1722

1823
# Set up logging
@@ -124,48 +129,54 @@ async def root():
124129
"""
125130
return {"message": "Hello, World, I am alive!"}
126131

132+
127133
@app.get("/health")
128134
def health_check():
129135
"""
130136
Health check endpoint that returns the server status.
131137
"""
132138
return Response(status_code = 200)
133139

134-
@app.get("/api/v1/datasets", response_model = list)
140+
141+
class ErrorResponseDTO(BaseModel):
142+
message: str
143+
144+
145+
class DatasetDTO(OutDTO):
146+
id: UUID
147+
name: str
148+
created_at: datetime
149+
updated_at: Optional[datetime]
150+
owner_id: UUID
151+
152+
@app.get("/api/v1/datasets", response_model = list[DatasetDTO])
135153
async def get_datasets(user: User = Depends(get_authenticated_user)):
136154
try:
137155
from cognee.modules.data.methods import get_datasets
138156
datasets = await get_datasets(user.id)
139157

140-
return JSONResponse(
141-
status_code = 200,
142-
content = [dataset.to_json() for dataset in datasets],
143-
)
158+
return datasets
144159
except Exception as error:
160+
logger.error(f"Error retrieving datasets: {str(error)}")
145161
raise HTTPException(status_code = 500, detail = f"Error retrieving datasets: {str(error)}") from error
146162

147-
@app.delete("/api/v1/datasets/{dataset_id}", response_model = dict)
163+
164+
@app.delete("/api/v1/datasets/{dataset_id}", response_model = None, responses = { 404: { "model": ErrorResponseDTO }})
148165
async def delete_dataset(dataset_id: str, user: User = Depends(get_authenticated_user)):
149166
from cognee.modules.data.methods import get_dataset, delete_dataset
150167

151-
dataset = get_dataset(user.id, dataset_id)
168+
dataset = await get_dataset(user.id, dataset_id)
152169

153170
if dataset is None:
154-
return JSONResponse(
171+
raise HTTPException(
155172
status_code = 404,
156-
content = {
157-
"detail": f"Dataset ({dataset_id}) not found."
158-
}
173+
detail = f"Dataset ({dataset_id}) not found."
159174
)
160175

161176
await delete_dataset(dataset)
162177

163-
return JSONResponse(
164-
status_code = 200,
165-
content = "OK",
166-
)
167178

168-
@app.get("/api/v1/datasets/{dataset_id}/graph", response_model=list)
179+
@app.get("/api/v1/datasets/{dataset_id}/graph", response_model = str)
169180
async def get_dataset_graph(dataset_id: str, user: User = Depends(get_authenticated_user)):
170181
from cognee.shared.utils import render_graph
171182
from cognee.infrastructure.databases.graph import get_graph_engine
@@ -184,7 +195,17 @@ async def get_dataset_graph(dataset_id: str, user: User = Depends(get_authentica
184195
content = "Graphistry credentials are not set. Please set them in your .env file.",
185196
)
186197

187-
@app.get("/api/v1/datasets/{dataset_id}/data", response_model=list)
198+
199+
class DataDTO(OutDTO):
200+
id: UUID
201+
name: str
202+
created_at: datetime
203+
updated_at: Optional[datetime]
204+
extension: str
205+
mime_type: str
206+
raw_data_location: str
207+
208+
@app.get("/api/v1/datasets/{dataset_id}/data", response_model = list[DataDTO], responses = { 404: { "model": ErrorResponseDTO }})
188209
async def get_dataset_data(dataset_id: str, user: User = Depends(get_authenticated_user)):
189210
from cognee.modules.data.methods import get_dataset_data, get_dataset
190211

@@ -193,38 +214,33 @@ async def get_dataset_data(dataset_id: str, user: User = Depends(get_authenticat
193214
if dataset is None:
194215
return JSONResponse(
195216
status_code = 404,
196-
content = {
197-
"detail": f"Dataset ({dataset_id}) not found."
198-
}
217+
content = ErrorResponseDTO(f"Dataset ({dataset_id}) not found."),
199218
)
200219

201220
dataset_data = await get_dataset_data(dataset_id = dataset.id)
202221

203222
if dataset_data is None:
204-
raise HTTPException(status_code = 404, detail = f"Dataset ({dataset.id}) not found.")
223+
return []
224+
225+
return dataset_data
205226

206-
return [
207-
data.to_json() for data in dataset_data
208-
]
209227

210-
@app.get("/api/v1/datasets/status", response_model=dict)
228+
@app.get("/api/v1/datasets/status", response_model = dict[str, PipelineRunStatus])
211229
async def get_dataset_status(datasets: Annotated[List[str], Query(alias="dataset")] = None, user: User = Depends(get_authenticated_user)):
212230
from cognee.api.v1.datasets.datasets import datasets as cognee_datasets
213231

214232
try:
215233
datasets_statuses = await cognee_datasets.get_status(datasets)
216234

217-
return JSONResponse(
218-
status_code = 200,
219-
content = datasets_statuses,
220-
)
235+
return datasets_statuses
221236
except Exception as error:
222237
return JSONResponse(
223238
status_code = 409,
224239
content = {"error": str(error)}
225240
)
226241

227-
@app.get("/api/v1/datasets/{dataset_id}/data/{data_id}/raw", response_class=FileResponse)
242+
243+
@app.get("/api/v1/datasets/{dataset_id}/data/{data_id}/raw", response_class = FileResponse)
228244
async def get_raw_data(dataset_id: str, data_id: str, user: User = Depends(get_authenticated_user)):
229245
from cognee.modules.data.methods import get_dataset, get_dataset_data
230246

@@ -255,13 +271,8 @@ async def get_raw_data(dataset_id: str, data_id: str, user: User = Depends(get_a
255271

256272
return data.raw_data_location
257273

258-
class AddPayload(BaseModel):
259-
data: Union[str, UploadFile, List[Union[str, UploadFile]]]
260-
dataset_id: str
261-
class Config:
262-
arbitrary_types_allowed = True
263274

264-
@app.post("/api/v1/add", response_model=dict)
275+
@app.post("/api/v1/add", response_model = None)
265276
async def add(
266277
data: List[UploadFile],
267278
datasetId: str = Form(...),
@@ -297,90 +308,89 @@ async def add(
297308
datasetId,
298309
user = user,
299310
)
300-
return JSONResponse(
301-
status_code = 200,
302-
content = {
303-
"message": "OK"
304-
}
305-
)
306311
except Exception as error:
307312
return JSONResponse(
308313
status_code = 409,
309314
content = {"error": str(error)}
310315
)
311316

312-
class CognifyPayload(BaseModel):
317+
318+
class CognifyPayloadDTO(BaseModel):
313319
datasets: List[str]
314320

315-
@app.post("/api/v1/cognify", response_model=dict)
316-
async def cognify(payload: CognifyPayload, user: User = Depends(get_authenticated_user)):
321+
@app.post("/api/v1/cognify", response_model = None)
322+
async def cognify(payload: CognifyPayloadDTO, user: User = Depends(get_authenticated_user)):
317323
""" This endpoint is responsible for the cognitive processing of the content."""
318324
from cognee.api.v1.cognify.cognify_v2 import cognify as cognee_cognify
319325
try:
320326
await cognee_cognify(payload.datasets, user)
321-
return JSONResponse(
322-
status_code = 200,
323-
content = {
324-
"message": "OK"
325-
}
326-
)
327327
except Exception as error:
328328
return JSONResponse(
329329
status_code = 409,
330330
content = {"error": str(error)}
331331
)
332332

333-
class SearchPayload(BaseModel):
334-
searchType: SearchType
333+
334+
class SearchPayloadDTO(InDTO):
335+
search_type: SearchType
335336
query: str
336337

337-
@app.post("/api/v1/search", response_model=list)
338-
async def search(payload: SearchPayload, user: User = Depends(get_authenticated_user)):
338+
@app.post("/api/v1/search", response_model = list)
339+
async def search(payload: SearchPayloadDTO, user: User = Depends(get_authenticated_user)):
339340
""" This endpoint is responsible for searching for nodes in the graph."""
340341
from cognee.api.v1.search import search as cognee_search
342+
341343
try:
342-
results = await cognee_search(payload.searchType, payload.query, user)
344+
results = await cognee_search(payload.search_type, payload.query, user)
343345

344-
return JSONResponse(
345-
status_code = 200,
346-
content = results,
347-
)
346+
return results
348347
except Exception as error:
349348
return JSONResponse(
350349
status_code = 409,
351350
content = {"error": str(error)}
352351
)
353352

354-
@app.get("/api/v1/settings", response_model=dict)
353+
from cognee.modules.settings.get_settings import LLMConfig, VectorDBConfig
354+
355+
class LLMConfigDTO(OutDTO, LLMConfig):
356+
pass
357+
358+
class VectorDBConfigDTO(OutDTO, VectorDBConfig):
359+
pass
360+
361+
class SettingsDTO(OutDTO):
362+
llm: LLMConfigDTO
363+
vector_db: VectorDBConfigDTO
364+
365+
@app.get("/api/v1/settings", response_model = SettingsDTO)
355366
async def get_settings(user: User = Depends(get_authenticated_user)):
356367
from cognee.modules.settings import get_settings as get_cognee_settings
357368
return get_cognee_settings()
358369

359-
class LLMConfig(BaseModel):
370+
371+
class LLMConfigDTO(InDTO):
360372
provider: Union[Literal["openai"], Literal["ollama"], Literal["anthropic"]]
361373
model: str
362-
apiKey: str
374+
api_key: str
363375

364-
class VectorDBConfig(BaseModel):
376+
class VectorDBConfigDTO(InDTO):
365377
provider: Union[Literal["lancedb"], Literal["qdrant"], Literal["weaviate"]]
366378
url: str
367-
apiKey: str
379+
api_key: str
368380

369-
class SettingsPayload(BaseModel):
370-
llm: Optional[LLMConfig] = None
371-
vectorDB: Optional[VectorDBConfig] = None
381+
class SettingsPayloadDTO(InDTO):
382+
llm: Optional[LLMConfigDTO] = None
383+
vector_db: Optional[VectorDBConfigDTO] = None
372384

373-
@app.post("/api/v1/settings", response_model=dict)
374-
async def save_config(new_settings: SettingsPayload, user: User = Depends(get_authenticated_user)):
385+
@app.post("/api/v1/settings", response_model = None)
386+
async def save_settings(new_settings: SettingsPayloadDTO, user: User = Depends(get_authenticated_user)):
375387
from cognee.modules.settings import save_llm_config, save_vector_db_config
388+
376389
if new_settings.llm is not None:
377390
await save_llm_config(new_settings.llm)
378-
if new_settings.vectorDB is not None:
379-
await save_vector_db_config(new_settings.vectorDB)
380-
return JSONResponse(
381-
status_code=200,
382-
content="OK",
383-
)
391+
392+
if new_settings.vector_db is not None:
393+
await save_vector_db_config(new_settings.vector_db)
384394

385395

386396
def start_api_server(host: str = "0.0.0.0", port: int = 8000):

cognee/api/v1/cognify/cognify_v2.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from cognee.modules.pipelines import run_tasks, run_tasks_parallel
1313
from cognee.modules.users.models import User
1414
from cognee.modules.users.methods import get_default_user
15+
from cognee.modules.pipelines.models import PipelineRunStatus
1516
from cognee.modules.pipelines.operations.get_pipeline_status import get_pipeline_status
1617
from cognee.modules.pipelines.operations.log_pipeline_status import log_pipeline_status
1718
from cognee.tasks import chunk_naive_llm_classifier, \
@@ -75,11 +76,11 @@ async def run_cognify_pipeline(dataset: Dataset, user: User):
7576
async with update_status_lock:
7677
task_status = await get_pipeline_status([dataset_id])
7778

78-
if dataset_id in task_status and task_status[dataset_id] == "DATASET_PROCESSING_STARTED":
79+
if dataset_id in task_status and task_status[dataset_id] == PipelineRunStatus.DATASET_PROCESSING_STARTED:
7980
logger.info("Dataset %s is already being processed.", dataset_name)
8081
return
8182

82-
await log_pipeline_status(dataset_id, "DATASET_PROCESSING_STARTED", {
83+
await log_pipeline_status(dataset_id, PipelineRunStatus.DATASET_PROCESSING_STARTED, {
8384
"dataset_name": dataset_name,
8485
"files": document_ids_str,
8586
})
@@ -120,14 +121,14 @@ async def run_cognify_pipeline(dataset: Dataset, user: User):
120121

121122
send_telemetry("cognee.cognify EXECUTION COMPLETED", user.id)
122123

123-
await log_pipeline_status(dataset_id, "DATASET_PROCESSING_COMPLETED", {
124+
await log_pipeline_status(dataset_id, PipelineRunStatus.DATASET_PROCESSING_COMPLETED, {
124125
"dataset_name": dataset_name,
125126
"files": document_ids_str,
126127
})
127128
except Exception as error:
128129
send_telemetry("cognee.cognify EXECUTION ERRORED", user.id)
129130

130-
await log_pipeline_status(dataset_id, "DATASET_PROCESSING_ERRORED", {
131+
await log_pipeline_status(dataset_id, PipelineRunStatus.DATASET_PROCESSING_ERRORED, {
131132
"dataset_name": dataset_name,
132133
"files": document_ids_str,
133134
})

0 commit comments

Comments
 (0)