Spaces:
Sleeping
Sleeping
update
Browse files- common/auth.py +48 -0
- main.py +3 -1
- requirements.txt +1 -1
- routes/auth.py +32 -0
- routes/dataset.py +26 -8
- routes/document.py +15 -6
- routes/entity.py +11 -5
- routes/llm.py +1 -1
- routes/llm_config.py +19 -10
- routes/llm_prompt.py +20 -11
- routes/log.py +7 -4
common/auth.py
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi.security import OAuth2PasswordBearer
|
2 |
+
from fastapi import HTTPException, Depends
|
3 |
+
from datetime import datetime, timedelta, timezone
|
4 |
+
from typing import Optional
|
5 |
+
from pydantic import BaseModel
|
6 |
+
import jwt
|
7 |
+
import os
|
8 |
+
|
9 |
+
# Секретный ключ для JWT
|
10 |
+
SECRET_KEY = os.environ.get("JWT_SECRET", "ooooooh_thats_my_super_secret_key")
|
11 |
+
ALGORITHM = "HS256"
|
12 |
+
ACCESS_TOKEN_EXPIRE_MINUTES = 30
|
13 |
+
|
14 |
+
# Захардкоженные пользователи
|
15 |
+
USERS = [
|
16 |
+
{"username": "admin", "password": "admin123"},
|
17 |
+
{"username": "user", "password": "user123"},
|
18 |
+
]
|
19 |
+
|
20 |
+
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/login")
|
21 |
+
|
22 |
+
class LoginRequest(BaseModel):
|
23 |
+
username: str
|
24 |
+
password: str
|
25 |
+
grant_type: str
|
26 |
+
|
27 |
+
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
|
28 |
+
to_encode = data.copy()
|
29 |
+
if expires_delta:
|
30 |
+
expire = datetime.now(timezone.utc) + expires_delta
|
31 |
+
else:
|
32 |
+
expire = datetime.now(timezone.utc) + timedelta(minutes=15)
|
33 |
+
to_encode.update({"exp": expire})
|
34 |
+
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
|
35 |
+
return encoded_jwt
|
36 |
+
|
37 |
+
async def get_current_user(token: str = Depends(oauth2_scheme)):
|
38 |
+
try:
|
39 |
+
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
40 |
+
username: str = payload.get("sub")
|
41 |
+
if username is None:
|
42 |
+
raise HTTPException(status_code=401, detail="Invalid token")
|
43 |
+
user = next((u for u in USERS if u["username"] == username), None)
|
44 |
+
if user is None:
|
45 |
+
raise HTTPException(status_code=401, detail="User not found")
|
46 |
+
return user
|
47 |
+
except jwt.PyJWTError:
|
48 |
+
raise HTTPException(status_code=401, detail="Invalid token")
|
main.py
CHANGED
@@ -20,6 +20,7 @@ from routes.entity import router as entity_router
|
|
20 |
from routes.llm import router as llm_router
|
21 |
from routes.llm_config import router as llm_config_router
|
22 |
from routes.llm_prompt import router as llm_prompt_router
|
|
|
23 |
|
24 |
# from main_before import config
|
25 |
|
@@ -73,12 +74,13 @@ app.include_router(document_router)
|
|
73 |
app.include_router(llm_config_router)
|
74 |
app.include_router(llm_prompt_router)
|
75 |
app.include_router(entity_router)
|
|
|
76 |
|
77 |
if __name__ == "__main__":
|
78 |
uvicorn.run(
|
79 |
"main:app",
|
80 |
host="localhost",
|
81 |
-
port=
|
82 |
reload=False,
|
83 |
workers=1
|
84 |
)
|
|
|
20 |
from routes.llm import router as llm_router
|
21 |
from routes.llm_config import router as llm_config_router
|
22 |
from routes.llm_prompt import router as llm_prompt_router
|
23 |
+
from routes.auth import router as auth_router
|
24 |
|
25 |
# from main_before import config
|
26 |
|
|
|
74 |
app.include_router(llm_config_router)
|
75 |
app.include_router(llm_prompt_router)
|
76 |
app.include_router(entity_router)
|
77 |
+
app.include_router(auth_router)
|
78 |
|
79 |
if __name__ == "__main__":
|
80 |
uvicorn.run(
|
81 |
"main:app",
|
82 |
host="localhost",
|
83 |
+
port=7860,
|
84 |
reload=False,
|
85 |
workers=1
|
86 |
)
|
requirements.txt
CHANGED
@@ -23,4 +23,4 @@ elasticsearch==8.17.2
|
|
23 |
uvicorn==0.34.0
|
24 |
python-multipart==0.0.20
|
25 |
python-dotenv==1.1.0
|
26 |
-
|
|
|
23 |
uvicorn==0.34.0
|
24 |
python-multipart==0.0.20
|
25 |
python-dotenv==1.1.0
|
26 |
+
pyjwt==2.10.1
|
routes/auth.py
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Optional
|
2 |
+
from fastapi import APIRouter, Form, HTTPException
|
3 |
+
from datetime import timedelta
|
4 |
+
import common.auth as auth
|
5 |
+
|
6 |
+
router = APIRouter(prefix="/auth", tags=["Auth"])
|
7 |
+
|
8 |
+
@router.post("/login")
|
9 |
+
async def login(username: Optional[str] = Form(default=None),
|
10 |
+
password: Optional[str] = Form(default=None),
|
11 |
+
request: Optional[auth.LoginRequest] = None):
|
12 |
+
|
13 |
+
# Если данные пришли через Form Data
|
14 |
+
if username is not None and password is not None:
|
15 |
+
final_username = username
|
16 |
+
final_password = password
|
17 |
+
# Если данные пришли через JSON
|
18 |
+
elif request is not None:
|
19 |
+
final_username = request.username
|
20 |
+
final_password = request.password
|
21 |
+
else:
|
22 |
+
raise HTTPException(status_code=400, detail="Не указаны логин и пароль")
|
23 |
+
|
24 |
+
user = next((u for u in auth.USERS if u["username"] == final_username), None)
|
25 |
+
if not user or user["password"] != final_password:
|
26 |
+
raise HTTPException(status_code=401, detail="Неверный логин или пароль")
|
27 |
+
|
28 |
+
access_token_expires = timedelta(minutes=auth.ACCESS_TOKEN_EXPIRE_MINUTES)
|
29 |
+
access_token = auth.create_access_token(
|
30 |
+
data={"sub": user["username"]}, expires_delta=access_token_expires
|
31 |
+
)
|
32 |
+
return {"access_token": access_token, "token_type": "bearer"}
|
routes/dataset.py
CHANGED
@@ -4,16 +4,19 @@ from typing import Annotated
|
|
4 |
from fastapi import (APIRouter, BackgroundTasks, Depends, HTTPException,
|
5 |
Response, UploadFile)
|
6 |
|
|
|
7 |
import common.dependencies as DI
|
8 |
from components.services.dataset import DatasetService
|
9 |
from schemas.dataset import (Dataset, DatasetExpanded, DatasetProcessing,
|
10 |
SortQuery, SortQueryList)
|
11 |
|
12 |
-
router = APIRouter(prefix='/datasets')
|
13 |
logger = logging.getLogger(__name__)
|
14 |
|
15 |
@router.get('/')
|
16 |
-
async def get_datasets(dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)]
|
|
|
|
|
17 |
logger.info("Handling GET request to /datasets")
|
18 |
try:
|
19 |
result = dataset_service.get_datasets()
|
@@ -25,7 +28,9 @@ async def get_datasets(dataset_service: Annotated[DatasetService, Depends(DI.get
|
|
25 |
|
26 |
|
27 |
@router.get('/processing')
|
28 |
-
async def get_processing(dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)]
|
|
|
|
|
29 |
logger.info("Handling GET request to /datasets/processing")
|
30 |
try:
|
31 |
result = dataset_service.get_processing()
|
@@ -54,7 +59,8 @@ def try_create_default_dataset(dataset_service: DatasetService):
|
|
54 |
)
|
55 |
|
56 |
@router.get('/try_init_default_dataset')
|
57 |
-
async def try_init_default_dataset(dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)]
|
|
|
58 |
logger.info(f"Handling GET request try_init_default_dataset")
|
59 |
try_create_default_dataset(dataset_service)
|
60 |
try:
|
@@ -68,6 +74,7 @@ async def try_init_default_dataset(dataset_service: Annotated[DatasetService, De
|
|
68 |
async def get_dataset(
|
69 |
dataset_id: int,
|
70 |
dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)],
|
|
|
71 |
page: int = 1,
|
72 |
page_size: int = 20,
|
73 |
search: str = '',
|
@@ -103,7 +110,9 @@ async def get_dataset(
|
|
103 |
|
104 |
|
105 |
@router.post('/{parent_id}/edit')
|
106 |
-
async def create_draft(parent_id: int, dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)]
|
|
|
|
|
107 |
logger.info(f"Handling POST request to /datasets/{parent_id}/edit")
|
108 |
try:
|
109 |
result = dataset_service.create_draft(parent_id)
|
@@ -115,7 +124,10 @@ async def create_draft(parent_id: int, dataset_service: Annotated[DatasetService
|
|
115 |
|
116 |
|
117 |
@router.post('/{dataset_id}')
|
118 |
-
async def make_active(dataset_id: int, dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)],
|
|
|
|
|
|
|
119 |
logger.info(f"Handling POST request to /datasets/{dataset_id}/activate")
|
120 |
try:
|
121 |
result = dataset_service.activate_dataset(dataset_id, background_tasks)
|
@@ -127,7 +139,10 @@ async def make_active(dataset_id: int, dataset_service: Annotated[DatasetService
|
|
127 |
|
128 |
|
129 |
@router.delete('/{dataset_id}')
|
130 |
-
async def delete_dataset(dataset_id: int,
|
|
|
|
|
|
|
131 |
logger.info(f"Handling DELETE request to /datasets/{dataset_id}")
|
132 |
try:
|
133 |
dataset_service.delete_dataset(dataset_id)
|
@@ -139,7 +154,10 @@ async def delete_dataset(dataset_id: int, dataset_service: Annotated[DatasetSer
|
|
139 |
|
140 |
|
141 |
@router.post('/')
|
142 |
-
async def upload_zip(file: UploadFile,
|
|
|
|
|
|
|
143 |
logger.info(f"Handling POST request to /datasets/upload with file {file.filename}")
|
144 |
try:
|
145 |
result = dataset_service.upload_zip(file)
|
|
|
4 |
from fastapi import (APIRouter, BackgroundTasks, Depends, HTTPException,
|
5 |
Response, UploadFile)
|
6 |
|
7 |
+
from common import auth
|
8 |
import common.dependencies as DI
|
9 |
from components.services.dataset import DatasetService
|
10 |
from schemas.dataset import (Dataset, DatasetExpanded, DatasetProcessing,
|
11 |
SortQuery, SortQueryList)
|
12 |
|
13 |
+
router = APIRouter(prefix='/datasets', tags=['Datasets'])
|
14 |
logger = logging.getLogger(__name__)
|
15 |
|
16 |
@router.get('/')
|
17 |
+
async def get_datasets(dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)],
|
18 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
19 |
+
) -> list[Dataset]:
|
20 |
logger.info("Handling GET request to /datasets")
|
21 |
try:
|
22 |
result = dataset_service.get_datasets()
|
|
|
28 |
|
29 |
|
30 |
@router.get('/processing')
|
31 |
+
async def get_processing(dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)],
|
32 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
33 |
+
) -> DatasetProcessing:
|
34 |
logger.info("Handling GET request to /datasets/processing")
|
35 |
try:
|
36 |
result = dataset_service.get_processing()
|
|
|
59 |
)
|
60 |
|
61 |
@router.get('/try_init_default_dataset')
|
62 |
+
async def try_init_default_dataset(dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)],
|
63 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]):
|
64 |
logger.info(f"Handling GET request try_init_default_dataset")
|
65 |
try_create_default_dataset(dataset_service)
|
66 |
try:
|
|
|
74 |
async def get_dataset(
|
75 |
dataset_id: int,
|
76 |
dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)],
|
77 |
+
current_user: Annotated[any, Depends(auth.get_current_user)],
|
78 |
page: int = 1,
|
79 |
page_size: int = 20,
|
80 |
search: str = '',
|
|
|
110 |
|
111 |
|
112 |
@router.post('/{parent_id}/edit')
|
113 |
+
async def create_draft(parent_id: int, dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)],
|
114 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
115 |
+
) -> Dataset:
|
116 |
logger.info(f"Handling POST request to /datasets/{parent_id}/edit")
|
117 |
try:
|
118 |
result = dataset_service.create_draft(parent_id)
|
|
|
124 |
|
125 |
|
126 |
@router.post('/{dataset_id}')
|
127 |
+
async def make_active(dataset_id: int, dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)],
|
128 |
+
background_tasks: BackgroundTasks,
|
129 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
130 |
+
) -> DatasetExpanded:
|
131 |
logger.info(f"Handling POST request to /datasets/{dataset_id}/activate")
|
132 |
try:
|
133 |
result = dataset_service.activate_dataset(dataset_id, background_tasks)
|
|
|
139 |
|
140 |
|
141 |
@router.delete('/{dataset_id}')
|
142 |
+
async def delete_dataset(dataset_id: int,
|
143 |
+
dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)],
|
144 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
145 |
+
) -> None:
|
146 |
logger.info(f"Handling DELETE request to /datasets/{dataset_id}")
|
147 |
try:
|
148 |
dataset_service.delete_dataset(dataset_id)
|
|
|
154 |
|
155 |
|
156 |
@router.post('/')
|
157 |
+
async def upload_zip(file: UploadFile,
|
158 |
+
dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)],
|
159 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
160 |
+
) -> DatasetExpanded:
|
161 |
logger.info(f"Handling POST request to /datasets/upload with file {file.filename}")
|
162 |
try:
|
163 |
result = dataset_service.upload_zip(file)
|
routes/document.py
CHANGED
@@ -1,19 +1,24 @@
|
|
1 |
import logging
|
|
|
2 |
|
3 |
from fastapi import APIRouter, Response, UploadFile, Depends
|
4 |
from fastapi.responses import FileResponse
|
5 |
|
|
|
6 |
from schemas.document import Document
|
7 |
from components.services.document import DocumentService
|
8 |
import common.dependencies as DI
|
9 |
|
10 |
-
router = APIRouter(prefix='/datasets/{dataset_id}/documents')
|
11 |
logger = logging.getLogger(__name__)
|
12 |
|
13 |
|
14 |
@router.get('/{document_id}')
|
15 |
-
async def get_document(document_id: int,
|
16 |
-
|
|
|
|
|
|
|
17 |
logger.info(f"Handling GET request to /documents/{document_id}")
|
18 |
try:
|
19 |
result = document_service.get_document(document_id, dataset_id)
|
@@ -30,13 +35,17 @@ async def get_document(document_id: int, dataset_id: int | None = None,
|
|
30 |
|
31 |
|
32 |
@router.delete('/{document_id}')
|
33 |
-
async def delete_document(dataset_id: int, document_id: int,
|
34 |
-
|
|
|
|
|
35 |
document_service.delete_document(dataset_id, document_id)
|
36 |
return Response(status_code=200)
|
37 |
|
38 |
|
39 |
@router.post('/')
|
40 |
async def add_document(dataset_id: int, file: UploadFile,
|
41 |
-
|
|
|
|
|
42 |
return document_service.add_document(dataset_id, file)
|
|
|
1 |
import logging
|
2 |
+
from typing import Annotated
|
3 |
|
4 |
from fastapi import APIRouter, Response, UploadFile, Depends
|
5 |
from fastapi.responses import FileResponse
|
6 |
|
7 |
+
from common import auth
|
8 |
from schemas.document import Document
|
9 |
from components.services.document import DocumentService
|
10 |
import common.dependencies as DI
|
11 |
|
12 |
+
router = APIRouter(prefix='/datasets/{dataset_id}/documents', tags=['Documents'])
|
13 |
logger = logging.getLogger(__name__)
|
14 |
|
15 |
|
16 |
@router.get('/{document_id}')
|
17 |
+
async def get_document(document_id: int,
|
18 |
+
document_service: Annotated[DocumentService, Depends(DI.get_document_service)],
|
19 |
+
current_user: Annotated[any, Depends(auth.get_current_user)],
|
20 |
+
dataset_id: int | None = None
|
21 |
+
) -> FileResponse:
|
22 |
logger.info(f"Handling GET request to /documents/{document_id}")
|
23 |
try:
|
24 |
result = document_service.get_document(document_id, dataset_id)
|
|
|
35 |
|
36 |
|
37 |
@router.delete('/{document_id}')
|
38 |
+
async def delete_document(dataset_id: int, document_id: int,
|
39 |
+
document_service: Annotated[DocumentService, Depends(DI.get_document_service)],
|
40 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
41 |
+
) -> None:
|
42 |
document_service.delete_document(dataset_id, document_id)
|
43 |
return Response(status_code=200)
|
44 |
|
45 |
|
46 |
@router.post('/')
|
47 |
async def add_document(dataset_id: int, file: UploadFile,
|
48 |
+
document_service: Annotated[DocumentService, Depends(DI.get_document_service)],
|
49 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
50 |
+
) -> Document:
|
51 |
return document_service.add_document(dataset_id, file)
|
routes/entity.py
CHANGED
@@ -4,6 +4,7 @@ import numpy as np
|
|
4 |
from fastapi import APIRouter, Depends, HTTPException
|
5 |
from sqlalchemy.orm import Session
|
6 |
|
|
|
7 |
import common.dependencies as DI
|
8 |
from components.dbo.chunk_repository import ChunkRepository
|
9 |
from components.services.entity import EntityService
|
@@ -13,13 +14,14 @@ from schemas.entity import (EntityNeighborsRequest, EntityNeighborsResponse,
|
|
13 |
EntitySearchWithTextResponse, EntityTextRequest,
|
14 |
EntityTextResponse)
|
15 |
|
16 |
-
router = APIRouter(prefix="/entity", tags=["
|
17 |
|
18 |
|
19 |
@router.post("/search", response_model=EntitySearchResponse)
|
20 |
async def search_entities(
|
21 |
request: EntitySearchRequest,
|
22 |
-
entity_service: EntityService
|
|
|
23 |
) -> EntitySearchResponse:
|
24 |
"""
|
25 |
Поиск похожих сущностей по векторному сходству (только ID).
|
@@ -69,7 +71,8 @@ async def search_entities(
|
|
69 |
@router.post("/search/with_text", response_model=EntitySearchWithTextResponse)
|
70 |
async def search_entities_with_text(
|
71 |
request: EntitySearchWithTextRequest,
|
72 |
-
entity_service: EntityService
|
|
|
73 |
) -> EntitySearchWithTextResponse:
|
74 |
"""
|
75 |
Поиск похожих сущностей по векторному сходству с возвратом текстов.
|
@@ -129,7 +132,8 @@ async def search_entities_with_text(
|
|
129 |
@router.post("/text", response_model=EntityTextResponse)
|
130 |
async def build_entity_text(
|
131 |
request: EntityTextRequest,
|
132 |
-
entity_service: EntityService
|
|
|
133 |
) -> EntityTextResponse:
|
134 |
"""
|
135 |
Сборка текста из сущностей.
|
@@ -170,7 +174,8 @@ async def build_entity_text(
|
|
170 |
@router.post("/neighbors", response_model=EntityNeighborsResponse)
|
171 |
async def get_neighboring_chunks(
|
172 |
request: EntityNeighborsRequest,
|
173 |
-
entity_service: EntityService
|
|
|
174 |
) -> EntityNeighborsResponse:
|
175 |
"""
|
176 |
Получение соседних чанков для заданных сущностей.
|
@@ -213,6 +218,7 @@ async def get_neighboring_chunks(
|
|
213 |
async def get_entity_info(
|
214 |
dataset_id: int,
|
215 |
db: Annotated[Session, Depends(DI.get_db)],
|
|
|
216 |
) -> dict:
|
217 |
"""
|
218 |
Получить информацию о сущностях в датасете.
|
|
|
4 |
from fastapi import APIRouter, Depends, HTTPException
|
5 |
from sqlalchemy.orm import Session
|
6 |
|
7 |
+
from common import auth
|
8 |
import common.dependencies as DI
|
9 |
from components.dbo.chunk_repository import ChunkRepository
|
10 |
from components.services.entity import EntityService
|
|
|
14 |
EntitySearchWithTextResponse, EntityTextRequest,
|
15 |
EntityTextResponse)
|
16 |
|
17 |
+
router = APIRouter(prefix="/entity", tags=["Entity"])
|
18 |
|
19 |
|
20 |
@router.post("/search", response_model=EntitySearchResponse)
|
21 |
async def search_entities(
|
22 |
request: EntitySearchRequest,
|
23 |
+
entity_service: Annotated[EntityService, Depends(DI.get_entity_service)],
|
24 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
25 |
) -> EntitySearchResponse:
|
26 |
"""
|
27 |
Поиск похожих сущностей по векторному сходству (только ID).
|
|
|
71 |
@router.post("/search/with_text", response_model=EntitySearchWithTextResponse)
|
72 |
async def search_entities_with_text(
|
73 |
request: EntitySearchWithTextRequest,
|
74 |
+
entity_service: Annotated[EntityService, Depends(DI.get_entity_service)],
|
75 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
76 |
) -> EntitySearchWithTextResponse:
|
77 |
"""
|
78 |
Поиск похожих сущностей по векторному сходству с возвратом текстов.
|
|
|
132 |
@router.post("/text", response_model=EntityTextResponse)
|
133 |
async def build_entity_text(
|
134 |
request: EntityTextRequest,
|
135 |
+
entity_service: Annotated[EntityService, Depends(DI.get_entity_service)],
|
136 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
137 |
) -> EntityTextResponse:
|
138 |
"""
|
139 |
Сборка текста из сущностей.
|
|
|
174 |
@router.post("/neighbors", response_model=EntityNeighborsResponse)
|
175 |
async def get_neighboring_chunks(
|
176 |
request: EntityNeighborsRequest,
|
177 |
+
entity_service: Annotated[EntityService, Depends(DI.get_entity_service)],
|
178 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
179 |
) -> EntityNeighborsResponse:
|
180 |
"""
|
181 |
Получение соседних чанков для заданных сущностей.
|
|
|
218 |
async def get_entity_info(
|
219 |
dataset_id: int,
|
220 |
db: Annotated[Session, Depends(DI.get_db)],
|
221 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
222 |
) -> dict:
|
223 |
"""
|
224 |
Получить информацию о сущностях в датасете.
|
routes/llm.py
CHANGED
@@ -15,7 +15,7 @@ from components.llm.utils import append_llm_response_to_history
|
|
15 |
from components.services.llm_config import LLMConfigService
|
16 |
from components.services.llm_prompt import LlmPromptService
|
17 |
|
18 |
-
router = APIRouter(prefix='/llm')
|
19 |
logger = logging.getLogger(__name__)
|
20 |
|
21 |
conf = DI.get_config()
|
|
|
15 |
from components.services.llm_config import LLMConfigService
|
16 |
from components.services.llm_prompt import LlmPromptService
|
17 |
|
18 |
+
router = APIRouter(prefix='/llm', tags=['LLM chat'])
|
19 |
logger = logging.getLogger(__name__)
|
20 |
|
21 |
conf = DI.get_config()
|
routes/llm_config.py
CHANGED
@@ -1,20 +1,24 @@
|
|
1 |
import logging
|
|
|
2 |
|
3 |
from fastapi import APIRouter, Response, UploadFile, Depends
|
4 |
from fastapi.responses import FileResponse
|
5 |
|
|
|
6 |
from schemas.llm_config import LLMConfig as LLMConfigScheme, LLMConfigCreateScheme
|
7 |
from components.dbo.models.llm_config import LLMConfig as LLMConfigSQL
|
8 |
from components.services.llm_config import LLMConfigService
|
9 |
import common.dependencies as DI
|
10 |
from schemas.llm_config import LLMConfig
|
11 |
|
12 |
-
router = APIRouter(prefix='/llm_config')
|
13 |
logger = logging.getLogger(__name__)
|
14 |
|
15 |
|
16 |
@router.get('/')
|
17 |
-
async def get_llm_config_list(llm_config_service: LLMConfigService
|
|
|
|
|
18 |
logger.info("Handling GET request to /llm_config/{config_id}}")
|
19 |
try:
|
20 |
config = llm_config_service.get_list()
|
@@ -24,9 +28,9 @@ async def get_llm_config_list(llm_config_service: LLMConfigService = Depends(DI.
|
|
24 |
raise e
|
25 |
|
26 |
@router.get('/default')
|
27 |
-
async def get_llm_default_config(llm_config_service:
|
28 |
-
|
29 |
-
|
30 |
logger.info("Handling GET request to /llm_config/default/")
|
31 |
try:
|
32 |
config = llm_config_service.get_default()
|
@@ -41,7 +45,8 @@ async def get_llm_default_config(llm_config_service:
|
|
41 |
|
42 |
@router.get('/{config_id}')
|
43 |
async def get_llm_config(config_id: int,
|
44 |
-
llm_config_service: LLMConfigService
|
|
|
45 |
) -> LLMConfig:
|
46 |
logger.info("Handling GET request to /llm_config/{config_id}}")
|
47 |
try:
|
@@ -57,7 +62,8 @@ async def get_llm_config(config_id: int,
|
|
57 |
|
58 |
@router.put('/default/{config_id}')
|
59 |
async def set_as_default_config(config_id: int,
|
60 |
-
llm_config_service: LLMConfigService
|
|
|
61 |
logger.info("Handling PUT request to /llm_config/default/{config_id}")
|
62 |
try:
|
63 |
llm_config_service.set_as_default(config_id)
|
@@ -72,7 +78,8 @@ async def set_as_default_config(config_id: int,
|
|
72 |
|
73 |
@router.delete('/{config_id}')
|
74 |
async def delete_config(config_id: int,
|
75 |
-
llm_config_service: LLMConfigService
|
|
|
76 |
logger.info("Handling DELETE request to /llm_config/{config_id}")
|
77 |
try:
|
78 |
llm_config_service.delete(config_id)
|
@@ -87,7 +94,8 @@ async def delete_config(config_id: int,
|
|
87 |
|
88 |
@router.post('/')
|
89 |
async def create_config(data: LLMConfigCreateScheme,
|
90 |
-
|
|
|
91 |
logger.info("Handling POST request to /llm_config")
|
92 |
try:
|
93 |
new_config = llm_config_service.create(data)
|
@@ -102,7 +110,8 @@ async def create_config(data: LLMConfigCreateScheme,
|
|
102 |
|
103 |
@router.put('/{config_id}')
|
104 |
async def update_config(config_id: int, file: LLMConfigScheme,
|
105 |
-
llm_config_service: LLMConfigService
|
|
|
106 |
logger.info("Handling PUT request to /llm_config/{config_id}")
|
107 |
try:
|
108 |
updated_config = llm_config_service.update(config_id, file)
|
|
|
1 |
import logging
|
2 |
+
from typing import Annotated
|
3 |
|
4 |
from fastapi import APIRouter, Response, UploadFile, Depends
|
5 |
from fastapi.responses import FileResponse
|
6 |
|
7 |
+
import common.auth as auth
|
8 |
from schemas.llm_config import LLMConfig as LLMConfigScheme, LLMConfigCreateScheme
|
9 |
from components.dbo.models.llm_config import LLMConfig as LLMConfigSQL
|
10 |
from components.services.llm_config import LLMConfigService
|
11 |
import common.dependencies as DI
|
12 |
from schemas.llm_config import LLMConfig
|
13 |
|
14 |
+
router = APIRouter(prefix='/llm_config', tags=['LLM parameters'])
|
15 |
logger = logging.getLogger(__name__)
|
16 |
|
17 |
|
18 |
@router.get('/')
|
19 |
+
async def get_llm_config_list(llm_config_service: Annotated[LLMConfigService, Depends(DI.get_llm_config_service)],
|
20 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
21 |
+
) -> list[LLMConfig]:
|
22 |
logger.info("Handling GET request to /llm_config/{config_id}}")
|
23 |
try:
|
24 |
config = llm_config_service.get_list()
|
|
|
28 |
raise e
|
29 |
|
30 |
@router.get('/default')
|
31 |
+
async def get_llm_default_config(llm_config_service: Annotated[LLMConfigService, Depends(DI.get_llm_config_service)],
|
32 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
33 |
+
) -> LLMConfig:
|
34 |
logger.info("Handling GET request to /llm_config/default/")
|
35 |
try:
|
36 |
config = llm_config_service.get_default()
|
|
|
45 |
|
46 |
@router.get('/{config_id}')
|
47 |
async def get_llm_config(config_id: int,
|
48 |
+
llm_config_service: Annotated[LLMConfigService, Depends(DI.get_llm_config_service)],
|
49 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
50 |
) -> LLMConfig:
|
51 |
logger.info("Handling GET request to /llm_config/{config_id}}")
|
52 |
try:
|
|
|
62 |
|
63 |
@router.put('/default/{config_id}')
|
64 |
async def set_as_default_config(config_id: int,
|
65 |
+
llm_config_service: Annotated[LLMConfigService, Depends(DI.get_llm_config_service)],
|
66 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]):
|
67 |
logger.info("Handling PUT request to /llm_config/default/{config_id}")
|
68 |
try:
|
69 |
llm_config_service.set_as_default(config_id)
|
|
|
78 |
|
79 |
@router.delete('/{config_id}')
|
80 |
async def delete_config(config_id: int,
|
81 |
+
llm_config_service: Annotated[LLMConfigService, Depends(DI.get_llm_config_service)],
|
82 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]):
|
83 |
logger.info("Handling DELETE request to /llm_config/{config_id}")
|
84 |
try:
|
85 |
llm_config_service.delete(config_id)
|
|
|
94 |
|
95 |
@router.post('/')
|
96 |
async def create_config(data: LLMConfigCreateScheme,
|
97 |
+
llm_config_service: Annotated[LLMConfigService, Depends(DI.get_llm_config_service)],
|
98 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]):
|
99 |
logger.info("Handling POST request to /llm_config")
|
100 |
try:
|
101 |
new_config = llm_config_service.create(data)
|
|
|
110 |
|
111 |
@router.put('/{config_id}')
|
112 |
async def update_config(config_id: int, file: LLMConfigScheme,
|
113 |
+
llm_config_service: Annotated[LLMConfigService, Depends(DI.get_llm_config_service)],
|
114 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]):
|
115 |
logger.info("Handling PUT request to /llm_config/{config_id}")
|
116 |
try:
|
117 |
updated_config = llm_config_service.update(config_id, file)
|
routes/llm_prompt.py
CHANGED
@@ -1,18 +1,22 @@
|
|
1 |
import logging
|
|
|
2 |
|
3 |
from fastapi import APIRouter, Response, UploadFile, Depends
|
4 |
from fastapi.responses import FileResponse
|
5 |
|
|
|
6 |
from schemas.llm_prompt import LlmPromptCreateSchema, LlmPromptSchema
|
7 |
from components.services.llm_prompt import LlmPromptService
|
8 |
import common.dependencies as DI
|
9 |
|
10 |
-
router = APIRouter(prefix='/llm_prompt')
|
11 |
logger = logging.getLogger(__name__)
|
12 |
|
13 |
|
14 |
@router.get('/')
|
15 |
-
async def get_llm_prompt_list(llm_prompt_service: LlmPromptService
|
|
|
|
|
16 |
logger.info("Handling GET request to /llm_prompt/{prompt_id}}")
|
17 |
try:
|
18 |
prompt = llm_prompt_service.get_list()
|
@@ -22,9 +26,9 @@ async def get_llm_prompt_list(llm_prompt_service: LlmPromptService = Depends(DI.
|
|
22 |
raise e
|
23 |
|
24 |
@router.get('/default')
|
25 |
-
async def get_llm_default_prompt(llm_prompt_service:
|
26 |
-
|
27 |
-
|
28 |
logger.info("Handling GET request to /llm_prompt/default/")
|
29 |
try:
|
30 |
prompt = llm_prompt_service.get_default()
|
@@ -39,8 +43,9 @@ async def get_llm_default_prompt(llm_prompt_service:
|
|
39 |
|
40 |
@router.get('/{prompt_id}')
|
41 |
async def get_llm_prompt(prompt_id: int,
|
42 |
-
llm_prompt_service: LlmPromptService
|
43 |
-
|
|
|
44 |
logger.info("Handling GET request to /llm_prompt/{prompt_id}}")
|
45 |
try:
|
46 |
prompt = llm_prompt_service.get_by_id(prompt_id)
|
@@ -55,7 +60,8 @@ async def get_llm_prompt(prompt_id: int,
|
|
55 |
|
56 |
@router.put('/default/{prompt_id}')
|
57 |
async def set_as_default_prompt(prompt_id: int,
|
58 |
-
llm_prompt_service: LlmPromptService
|
|
|
59 |
logger.info("Handling PUT request to /llm_prompt/default/{prompt_id}")
|
60 |
try:
|
61 |
llm_prompt_service.set_as_default(prompt_id)
|
@@ -70,7 +76,8 @@ async def set_as_default_prompt(prompt_id: int,
|
|
70 |
|
71 |
@router.delete('/{prompt_id}')
|
72 |
async def delete_prompt(prompt_id: int,
|
73 |
-
llm_prompt_service: LlmPromptService
|
|
|
74 |
logger.info("Handling DELETE request to /llm_prompt/{prompt_id}")
|
75 |
try:
|
76 |
llm_prompt_service.delete(prompt_id)
|
@@ -85,7 +92,8 @@ async def delete_prompt(prompt_id: int,
|
|
85 |
|
86 |
@router.post('/')
|
87 |
async def create_prompt(data: LlmPromptCreateSchema,
|
88 |
-
llm_prompt_service: LlmPromptService
|
|
|
89 |
logger.info("Handling POST request to /llm_prompt")
|
90 |
try:
|
91 |
new_prompt = llm_prompt_service.create(data)
|
@@ -100,7 +108,8 @@ async def create_prompt(data: LlmPromptCreateSchema,
|
|
100 |
|
101 |
@router.put('/{prompt_id}')
|
102 |
async def update_prompt(prompt_id: int, file: LlmPromptSchema,
|
103 |
-
llm_prompt_service: LlmPromptService
|
|
|
104 |
logger.info("Handling PUT request to /llm_prompt/{prompt_id}")
|
105 |
try:
|
106 |
updated_prompt = llm_prompt_service.update(prompt_id, file)
|
|
|
1 |
import logging
|
2 |
+
from typing import Annotated
|
3 |
|
4 |
from fastapi import APIRouter, Response, UploadFile, Depends
|
5 |
from fastapi.responses import FileResponse
|
6 |
|
7 |
+
from common import auth
|
8 |
from schemas.llm_prompt import LlmPromptCreateSchema, LlmPromptSchema
|
9 |
from components.services.llm_prompt import LlmPromptService
|
10 |
import common.dependencies as DI
|
11 |
|
12 |
+
router = APIRouter(prefix='/llm_prompt', tags=['Prompt settings'])
|
13 |
logger = logging.getLogger(__name__)
|
14 |
|
15 |
|
16 |
@router.get('/')
|
17 |
+
async def get_llm_prompt_list(llm_prompt_service: Annotated[LlmPromptService, Depends(DI.get_llm_prompt_service)],
|
18 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
19 |
+
) -> list[LlmPromptSchema]:
|
20 |
logger.info("Handling GET request to /llm_prompt/{prompt_id}}")
|
21 |
try:
|
22 |
prompt = llm_prompt_service.get_list()
|
|
|
26 |
raise e
|
27 |
|
28 |
@router.get('/default')
|
29 |
+
async def get_llm_default_prompt(llm_prompt_service: Annotated[LlmPromptService, Depends(DI.get_llm_prompt_service)],
|
30 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
31 |
+
) -> LlmPromptSchema:
|
32 |
logger.info("Handling GET request to /llm_prompt/default/")
|
33 |
try:
|
34 |
prompt = llm_prompt_service.get_default()
|
|
|
43 |
|
44 |
@router.get('/{prompt_id}')
|
45 |
async def get_llm_prompt(prompt_id: int,
|
46 |
+
llm_prompt_service: Annotated[LlmPromptService, Depends(DI.get_llm_prompt_service)],
|
47 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]
|
48 |
+
) -> LlmPromptSchema:
|
49 |
logger.info("Handling GET request to /llm_prompt/{prompt_id}}")
|
50 |
try:
|
51 |
prompt = llm_prompt_service.get_by_id(prompt_id)
|
|
|
60 |
|
61 |
@router.put('/default/{prompt_id}')
|
62 |
async def set_as_default_prompt(prompt_id: int,
|
63 |
+
llm_prompt_service: Annotated[LlmPromptService, Depends(DI.get_llm_prompt_service)],
|
64 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]):
|
65 |
logger.info("Handling PUT request to /llm_prompt/default/{prompt_id}")
|
66 |
try:
|
67 |
llm_prompt_service.set_as_default(prompt_id)
|
|
|
76 |
|
77 |
@router.delete('/{prompt_id}')
|
78 |
async def delete_prompt(prompt_id: int,
|
79 |
+
llm_prompt_service: Annotated[LlmPromptService, Depends(DI.get_llm_prompt_service)],
|
80 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]):
|
81 |
logger.info("Handling DELETE request to /llm_prompt/{prompt_id}")
|
82 |
try:
|
83 |
llm_prompt_service.delete(prompt_id)
|
|
|
92 |
|
93 |
@router.post('/')
|
94 |
async def create_prompt(data: LlmPromptCreateSchema,
|
95 |
+
llm_prompt_service: Annotated[LlmPromptService, Depends(DI.get_llm_prompt_service)],
|
96 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]):
|
97 |
logger.info("Handling POST request to /llm_prompt")
|
98 |
try:
|
99 |
new_prompt = llm_prompt_service.create(data)
|
|
|
108 |
|
109 |
@router.put('/{prompt_id}')
|
110 |
async def update_prompt(prompt_id: int, file: LlmPromptSchema,
|
111 |
+
llm_prompt_service: Annotated[LlmPromptService, Depends(DI.get_llm_prompt_service)],
|
112 |
+
current_user: Annotated[any, Depends(auth.get_current_user)]):
|
113 |
logger.info("Handling PUT request to /llm_prompt/{prompt_id}")
|
114 |
try:
|
115 |
updated_prompt = llm_prompt_service.update(prompt_id, file)
|
routes/log.py
CHANGED
@@ -6,6 +6,7 @@ from fastapi import APIRouter, Depends, Query
|
|
6 |
from sqlalchemy.orm import aliased
|
7 |
from starlette import status
|
8 |
|
|
|
9 |
from common.common import configure_logging
|
10 |
from common.exceptions import LogNotFoundException
|
11 |
from components.dbo.models.feedback import Feedback
|
@@ -14,7 +15,7 @@ from schemas.log import LogCreate
|
|
14 |
import common.dependencies as DI
|
15 |
from sqlalchemy.orm import sessionmaker
|
16 |
|
17 |
-
router = APIRouter()
|
18 |
|
19 |
logger = logging.getLogger(__name__)
|
20 |
configure_logging()
|
@@ -22,9 +23,10 @@ configure_logging()
|
|
22 |
|
23 |
@router.get('/logs', status_code=status.HTTP_200_OK)
|
24 |
async def get_all_logs(
|
25 |
-
db: Annotated[sessionmaker, Depends(DI.get_db)],
|
|
|
26 |
date_start: Optional[datetime] = Query(None, alias="date_start"),
|
27 |
-
date_end: Optional[datetime] = Query(None, alias="date_end")
|
28 |
):
|
29 |
logger.info(f'GET /logs: start')
|
30 |
logger.info(f'GET /logs: start_date={date_start}, end_date={date_end}')
|
@@ -86,7 +88,8 @@ async def get_all_logs(
|
|
86 |
|
87 |
|
88 |
@router.get('/log/{log_id}', status_code=status.HTTP_200_OK)
|
89 |
-
async def get_log(db: Annotated[sessionmaker, Depends(DI.get_db)],
|
|
|
90 |
log = db.query(Log).filter(Log.id == log_id).first()
|
91 |
if log is None:
|
92 |
raise LogNotFoundException(log_id)
|
|
|
6 |
from sqlalchemy.orm import aliased
|
7 |
from starlette import status
|
8 |
|
9 |
+
from common import auth
|
10 |
from common.common import configure_logging
|
11 |
from common.exceptions import LogNotFoundException
|
12 |
from components.dbo.models.feedback import Feedback
|
|
|
15 |
import common.dependencies as DI
|
16 |
from sqlalchemy.orm import sessionmaker
|
17 |
|
18 |
+
router = APIRouter(tags=['Logs'])
|
19 |
|
20 |
logger = logging.getLogger(__name__)
|
21 |
configure_logging()
|
|
|
23 |
|
24 |
@router.get('/logs', status_code=status.HTTP_200_OK)
|
25 |
async def get_all_logs(
|
26 |
+
db: Annotated[sessionmaker, Depends(DI.get_db)],
|
27 |
+
current_user: Annotated[any, Depends(auth.get_current_user)],
|
28 |
date_start: Optional[datetime] = Query(None, alias="date_start"),
|
29 |
+
date_end: Optional[datetime] = Query(None, alias="date_end")
|
30 |
):
|
31 |
logger.info(f'GET /logs: start')
|
32 |
logger.info(f'GET /logs: start_date={date_start}, end_date={date_end}')
|
|
|
88 |
|
89 |
|
90 |
@router.get('/log/{log_id}', status_code=status.HTTP_200_OK)
|
91 |
+
async def get_log(db: Annotated[sessionmaker, Depends(DI.get_db)],
|
92 |
+
current_user: Annotated[any, Depends(auth.get_current_user)], log_id):
|
93 |
log = db.query(Log).filter(Log.id == log_id).first()
|
94 |
if log is None:
|
95 |
raise LogNotFoundException(log_id)
|