muryshev commited on
Commit
fd3c8b9
·
1 Parent(s): c5c0009
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=8885,
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)]) -> list[Dataset]:
 
 
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)]) -> DatasetProcessing:
 
 
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)]) -> Dataset:
 
 
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)], background_tasks: BackgroundTasks) -> DatasetExpanded:
 
 
 
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, dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)]) -> None:
 
 
 
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, dataset_service: Annotated[DatasetService, Depends(DI.get_dataset_service)]) -> DatasetExpanded:
 
 
 
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, dataset_id: int | None = None,
16
- document_service: DocumentService = Depends(DI.get_document_service)) -> FileResponse:
 
 
 
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
- document_service: DocumentService = Depends(DI.get_document_service)) -> None:
 
 
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
- document_service: DocumentService = Depends(DI.get_document_service)) -> Document:
 
 
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=["entity"])
17
 
18
 
19
  @router.post("/search", response_model=EntitySearchResponse)
20
  async def search_entities(
21
  request: EntitySearchRequest,
22
- entity_service: EntityService = Depends(DI.get_entity_service),
 
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 = Depends(DI.get_entity_service),
 
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 = Depends(DI.get_entity_service),
 
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 = Depends(DI.get_entity_service),
 
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 = Depends(DI.get_llm_config_service)) -> list[LLMConfig]:
 
 
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
- LLMConfigService = Depends(DI.get_llm_config_service)
29
- ) -> LLMConfig:
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 = Depends(DI.get_llm_config_service)
 
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 = Depends(DI.get_llm_config_service)):
 
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 = Depends(DI.get_llm_config_service)):
 
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
- llm_config_service: LLMConfigService = Depends(DI.get_llm_config_service)):
 
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 = Depends(DI.get_llm_config_service)):
 
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 = Depends(DI.get_llm_prompt_service)) -> list[LlmPromptSchema]:
 
 
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
- LlmPromptService = Depends(DI.get_llm_prompt_service)
27
- ) -> LlmPromptSchema:
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 = Depends(DI.get_llm_prompt_service)
43
- ) -> LlmPromptSchema:
 
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 = Depends(DI.get_llm_prompt_service)):
 
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 = Depends(DI.get_llm_prompt_service)):
 
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 = Depends(DI.get_llm_prompt_service)):
 
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 = Depends(DI.get_llm_prompt_service)):
 
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)], log_id):
 
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)