Compare commits
4 Commits
a649fb1192
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 181e67e84f | |||
| b2210105cb | |||
| 95f87c253c | |||
| 32bfec2074 |
36
logs/app.log
Normal file
36
logs/app.log
Normal file
@@ -0,0 +1,36 @@
|
||||
2025-12-23 21:37:30 - root - INFO - Starting up...
|
||||
2025-12-23 21:37:30 - root - INFO - Starting up...
|
||||
2025-12-23 21:39:37 - root - INFO - Shutting down...
|
||||
2025-12-23 21:39:37 - root - INFO - Shutting down...
|
||||
2025-12-23 21:39:42 - root - INFO - Starting up...
|
||||
2025-12-23 21:39:42 - root - INFO - Starting up...
|
||||
2025-12-23 22:07:40 - root - INFO - Shutting down...
|
||||
2025-12-23 22:07:40 - root - INFO - Shutting down...
|
||||
2025-12-23 22:07:45 - root - INFO - Starting up...
|
||||
2025-12-23 22:07:45 - root - INFO - Starting up...
|
||||
2025-12-23 22:12:42 - root - INFO - Shutting down...
|
||||
2025-12-23 22:12:42 - root - INFO - Shutting down...
|
||||
2025-12-23 22:12:47 - root - INFO - Starting up...
|
||||
2025-12-23 22:12:47 - root - INFO - Starting up...
|
||||
2025-12-23 22:23:22 - root - INFO - Shutting down...
|
||||
2025-12-23 22:23:22 - root - INFO - Shutting down...
|
||||
2025-12-23 22:23:27 - root - INFO - Starting up...
|
||||
2025-12-23 22:23:27 - root - INFO - Starting up...
|
||||
2025-12-23 22:52:47 - root - INFO - Shutting down...
|
||||
2025-12-23 22:52:47 - root - INFO - Shutting down...
|
||||
2025-12-23 22:52:54 - root - INFO - Starting up...
|
||||
2025-12-23 22:52:54 - root - INFO - Starting up...
|
||||
2025-12-23 23:12:01 - root - INFO - Shutting down...
|
||||
2025-12-23 23:12:01 - root - INFO - Shutting down...
|
||||
2025-12-23 23:12:07 - root - INFO - Starting up...
|
||||
2025-12-23 23:12:07 - root - INFO - Starting up...
|
||||
2025-12-23 23:15:05 - root - INFO - Shutting down...
|
||||
2025-12-23 23:15:05 - root - INFO - Shutting down...
|
||||
2025-12-23 23:15:10 - root - INFO - Starting up...
|
||||
2025-12-23 23:15:10 - root - INFO - Starting up...
|
||||
2025-12-24 00:01:39 - root - INFO - Shutting down...
|
||||
2025-12-24 00:01:39 - root - INFO - Shutting down...
|
||||
2025-12-24 00:01:45 - root - INFO - Starting up...
|
||||
2025-12-24 00:01:45 - root - INFO - Starting up...
|
||||
2025-12-24 01:38:58 - root - INFO - Shutting down...
|
||||
2025-12-24 01:38:58 - root - INFO - Shutting down...
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
GIGACHAT_CLIENT_ID=019966f4-1c5c-7382-9006-b84419fbe5d1
|
||||
GIGACHAT_CLIENT_SECRET=MDE5OTY2ZjQtMWM1Yy03MzgyLTkwMDYtYjg0NDE5ZmJlNWQxOjJjODBmOWE2LWU4YWMtNDE4YS1iOGVkLWE4NTE0YzVkNDAwNw==
|
||||
GIGACHAT_CLIENT_ID=019966f0-5781-76e6-a84f-ec7de158188a
|
||||
GIGACHAT_CLIENT_SECRET=MDE5OTY2ZjAtNTc4MS03NmU2LWE4NGYtZWM3ZGUxNTgxODhhOjI3MDMxZjIxLWY3NWYtNGI4NS05MzM1LTI4ZDYyOWM3MmM0MA==
|
||||
GIGACHAT_AUTH_URL=https://ngw.devices.sberbank.ru:9443/api/v2/oauth
|
||||
GIGACHAT_BASE_URL=https://gigachat.devices.sberbank.ru/api/v1
|
||||
GIGACHAT_MODEL_CHAT=GigaChat-2-Lite
|
||||
@@ -29,3 +29,5 @@ STORAGE_BUCKET=new-planet-images
|
||||
STORAGE_USE_SSL=false
|
||||
STORAGE_REGION=us-east-1
|
||||
|
||||
# Agents
|
||||
AI_AGENT_BASE_URL=http://localhost:8001
|
||||
BIN
new-planet-backend/app/__pycache__/__init__.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/__pycache__/__init__.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/__pycache__/config.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/__pycache__/config.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/__pycache__/main.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/__pycache__/main.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/api/__pycache__/__init__.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/api/__pycache__/__init__.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/api/__pycache__/deps.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/api/__pycache__/deps.cpython-313.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
new-planet-backend/app/api/v1/__pycache__/ai.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/api/v1/__pycache__/ai.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/api/v1/__pycache__/auth.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/api/v1/__pycache__/auth.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/api/v1/__pycache__/images.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/api/v1/__pycache__/images.cpython-313.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
new-planet-backend/app/api/v1/__pycache__/router.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/api/v1/__pycache__/router.cpython-313.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
new-planet-backend/app/api/v1/__pycache__/tasks.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/api/v1/__pycache__/tasks.cpython-313.pyc
Normal file
Binary file not shown.
Binary file not shown.
@@ -61,6 +61,10 @@ async def create_schedule(
|
||||
schedule_data = schedule_in.model_dump()
|
||||
schedule_data["user_id"] = current_user.id
|
||||
schedule = await crud_schedule.create(db, schedule_data)
|
||||
|
||||
# Перезагрузить расписание с tasks для корректной сериализации
|
||||
schedule = await crud_schedule.get_with_tasks(db, schedule.id)
|
||||
|
||||
return schedule
|
||||
|
||||
|
||||
@@ -86,6 +90,10 @@ async def update_schedule(
|
||||
|
||||
update_data = schedule_in.model_dump(exclude_unset=True)
|
||||
schedule = await crud_schedule.update(db, schedule, update_data)
|
||||
|
||||
# Перезагрузить расписание с tasks для корректной сериализации
|
||||
schedule = await crud_schedule.get_with_tasks(db, schedule.id)
|
||||
|
||||
return schedule
|
||||
|
||||
|
||||
|
||||
BIN
new-planet-backend/app/core/__pycache__/__init__.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/core/__pycache__/__init__.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/core/__pycache__/config.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/core/__pycache__/config.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/core/__pycache__/logging.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/core/__pycache__/logging.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/core/__pycache__/security.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/core/__pycache__/security.cpython-313.pyc
Normal file
Binary file not shown.
@@ -1,5 +1,13 @@
|
||||
from pydantic_settings import BaseSettings
|
||||
from typing import Optional
|
||||
from dotenv import load_dotenv
|
||||
from pathlib import Path
|
||||
|
||||
# Загружаем .env файл перед созданием Settings
|
||||
# Ищем .env в корне проекта (на уровень выше от app/)
|
||||
env_path = Path(__file__).parent.parent.parent / ".env"
|
||||
# override=True гарантирует, что переменные из .env перезапишут существующие
|
||||
load_dotenv(dotenv_path=env_path, override=True)
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
@@ -49,7 +57,14 @@ class Settings(BaseSettings):
|
||||
STORAGE_USE_SSL: bool = False
|
||||
STORAGE_REGION: str = "us-east-1"
|
||||
|
||||
# GigaChat
|
||||
# AI Agent Service (внешний сервис для работы с GigaChat)
|
||||
# URL можно переопределить через переменную окружения AI_AGENT_BASE_URL
|
||||
# Для Docker сети используйте: http://ai-agent:8000 (или имя сервиса из docker-compose)
|
||||
# Для локальной разработки используйте: http://localhost:8000
|
||||
AI_AGENT_BASE_URL: str = "http://ai-agent:8000"
|
||||
AI_AGENT_TIMEOUT: int = 120 # Таймаут в секундах
|
||||
|
||||
# GigaChat (оставлено для обратной совместимости, но используется через AI-agent сервис)
|
||||
GIGACHAT_CLIENT_ID: str = "019966f4-1c5c-7382-9006-b84419fbe5d1"
|
||||
GIGACHAT_CLIENT_SECRET: str = "MDE5OTY2ZjQtMWM1Yy03MzgyLTkwMDYtYjg0NDE5ZmJlNWQxOjJjODBmOWE2LWU4YWMtNDE4YS1iOGVkLWE4NTE0YzVkNDAwNw=="
|
||||
GIGACHAT_AUTH_URL: str = "https://ngw.devices.sberbank.ru:9443/api/v2/oauth"
|
||||
@@ -65,7 +80,9 @@ class Settings(BaseSettings):
|
||||
RATE_LIMIT_PER_MINUTE: int = 60
|
||||
|
||||
class Config:
|
||||
env_file = ".env"
|
||||
# Путь к .env файлу относительно корня проекта
|
||||
env_file = str(env_path) if env_path.exists() else ".env"
|
||||
env_file_encoding = "utf-8"
|
||||
case_sensitive = True
|
||||
|
||||
|
||||
|
||||
BIN
new-planet-backend/app/crud/__pycache__/__init__.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/crud/__pycache__/__init__.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/crud/__pycache__/base.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/crud/__pycache__/base.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/crud/__pycache__/schedule.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/crud/__pycache__/schedule.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/crud/__pycache__/task.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/crud/__pycache__/task.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/crud/__pycache__/user.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/crud/__pycache__/user.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/db/__pycache__/__init__.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/db/__pycache__/__init__.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/db/__pycache__/base.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/db/__pycache__/base.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/db/__pycache__/session.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/db/__pycache__/session.cpython-313.pyc
Normal file
Binary file not shown.
284
new-planet-backend/app/logs/app.log
Normal file
284
new-planet-backend/app/logs/app.log
Normal file
@@ -0,0 +1,284 @@
|
||||
2025-12-26 19:02:56 - root - INFO - Starting up...
|
||||
2025-12-26 19:02:56 - root - INFO - Starting up...
|
||||
2025-12-26 19:02:59 - root - INFO - Shutting down...
|
||||
2025-12-26 19:02:59 - root - INFO - Shutting down...
|
||||
2025-12-26 19:03:28 - root - INFO - Starting up...
|
||||
2025-12-26 19:03:28 - root - INFO - Starting up...
|
||||
2025-12-26 19:36:24 - app.middleware.error_handler - ERROR - Unhandled exception: 1 validation error:
|
||||
{'type': 'get_attribute_error', 'loc': ('response', 'tasks'), 'msg': "Error extracting attribute: MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)", 'input': <app.models.schedule.Schedule object at 0x000001BB3C11BE00>, 'ctx': {'error': "MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)"}}
|
||||
|
||||
File "C:\Users\yfili\Desktop\Planet\New-planet-api\new-planet-backend\app\api\v1\schedules.py", line 54, in create_schedule
|
||||
POST /api/v1/schedules
|
||||
Traceback (most recent call last):
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__
|
||||
await self.app(scope, receive, _send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 191, in __call__
|
||||
with recv_stream, send_stream, collapse_excgroups():
|
||||
~~~~~~~~~~~~~~~~~~^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\contextlib.py", line 162, in __exit__
|
||||
self.gen.throw(value)
|
||||
~~~~~~~~~~~~~~^^^^^^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_utils.py", line 85, in collapse_excgroups
|
||||
raise exc
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__
|
||||
response = await self.dispatch_func(request, call_next)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "C:\Users\yfili\Desktop\Planet\New-planet-api\new-planet-backend\app\middleware\rate_limiter.py", line 33, in dispatch
|
||||
response = await call_next(request)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next
|
||||
raise app_exc from app_exc.__cause__ or app_exc.__context__
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 144, in coro
|
||||
await self.app(scope, receive_or_disconnect, send_no_error)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\cors.py", line 85, in __call__
|
||||
await self.app(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__
|
||||
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
|
||||
raise exc
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
|
||||
await app(scope, receive, sender)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__
|
||||
await self.app(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\routing.py", line 716, in __call__
|
||||
await self.middleware_stack(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\routing.py", line 736, in app
|
||||
await route.handle(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\routing.py", line 290, in handle
|
||||
await self.app(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 119, in app
|
||||
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
|
||||
raise exc
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
|
||||
await app(scope, receive, sender)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 105, in app
|
||||
response = await f(request)
|
||||
^^^^^^^^^^^^^^^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 448, in app
|
||||
content = await serialize_response(
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...<10 lines>...
|
||||
)
|
||||
^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 274, in serialize_response
|
||||
raise ResponseValidationError(
|
||||
...<3 lines>...
|
||||
)
|
||||
fastapi.exceptions.ResponseValidationError: 1 validation error:
|
||||
{'type': 'get_attribute_error', 'loc': ('response', 'tasks'), 'msg': "Error extracting attribute: MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)", 'input': <app.models.schedule.Schedule object at 0x000001BB3C11BE00>, 'ctx': {'error': "MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)"}}
|
||||
|
||||
File "C:\Users\yfili\Desktop\Planet\New-planet-api\new-planet-backend\app\api\v1\schedules.py", line 54, in create_schedule
|
||||
POST /api/v1/schedules
|
||||
2025-12-26 19:36:24 - app.middleware.error_handler - ERROR - Unhandled exception: 1 validation error:
|
||||
{'type': 'get_attribute_error', 'loc': ('response', 'tasks'), 'msg': "Error extracting attribute: MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)", 'input': <app.models.schedule.Schedule object at 0x000001BB3C11BE00>, 'ctx': {'error': "MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)"}}
|
||||
|
||||
File "C:\Users\yfili\Desktop\Planet\New-planet-api\new-planet-backend\app\api\v1\schedules.py", line 54, in create_schedule
|
||||
POST /api/v1/schedules
|
||||
Traceback (most recent call last):
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__
|
||||
await self.app(scope, receive, _send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 191, in __call__
|
||||
with recv_stream, send_stream, collapse_excgroups():
|
||||
~~~~~~~~~~~~~~~~~~^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\contextlib.py", line 162, in __exit__
|
||||
self.gen.throw(value)
|
||||
~~~~~~~~~~~~~~^^^^^^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_utils.py", line 85, in collapse_excgroups
|
||||
raise exc
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__
|
||||
response = await self.dispatch_func(request, call_next)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "C:\Users\yfili\Desktop\Planet\New-planet-api\new-planet-backend\app\middleware\rate_limiter.py", line 33, in dispatch
|
||||
response = await call_next(request)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next
|
||||
raise app_exc from app_exc.__cause__ or app_exc.__context__
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 144, in coro
|
||||
await self.app(scope, receive_or_disconnect, send_no_error)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\cors.py", line 85, in __call__
|
||||
await self.app(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__
|
||||
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
|
||||
raise exc
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
|
||||
await app(scope, receive, sender)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__
|
||||
await self.app(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\routing.py", line 716, in __call__
|
||||
await self.middleware_stack(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\routing.py", line 736, in app
|
||||
await route.handle(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\routing.py", line 290, in handle
|
||||
await self.app(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 119, in app
|
||||
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
|
||||
raise exc
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
|
||||
await app(scope, receive, sender)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 105, in app
|
||||
response = await f(request)
|
||||
^^^^^^^^^^^^^^^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 448, in app
|
||||
content = await serialize_response(
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...<10 lines>...
|
||||
)
|
||||
^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 274, in serialize_response
|
||||
raise ResponseValidationError(
|
||||
...<3 lines>...
|
||||
)
|
||||
fastapi.exceptions.ResponseValidationError: 1 validation error:
|
||||
{'type': 'get_attribute_error', 'loc': ('response', 'tasks'), 'msg': "Error extracting attribute: MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)", 'input': <app.models.schedule.Schedule object at 0x000001BB3C11BE00>, 'ctx': {'error': "MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)"}}
|
||||
|
||||
File "C:\Users\yfili\Desktop\Planet\New-planet-api\new-planet-backend\app\api\v1\schedules.py", line 54, in create_schedule
|
||||
POST /api/v1/schedules
|
||||
2025-12-26 19:37:04 - root - INFO - Shutting down...
|
||||
2025-12-26 19:37:04 - root - INFO - Shutting down...
|
||||
2025-12-26 19:37:13 - root - INFO - Starting up...
|
||||
2025-12-26 19:37:13 - root - INFO - Starting up...
|
||||
2025-12-26 19:38:27 - root - INFO - Shutting down...
|
||||
2025-12-26 19:38:27 - root - INFO - Shutting down...
|
||||
2025-12-26 19:39:43 - root - INFO - Starting up...
|
||||
2025-12-26 19:39:43 - root - INFO - Starting up...
|
||||
2025-12-26 19:40:04 - app.middleware.error_handler - ERROR - Unhandled exception: 1 validation error:
|
||||
{'type': 'get_attribute_error', 'loc': ('response', 'tasks'), 'msg': "Error extracting attribute: MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)", 'input': <app.models.schedule.Schedule object at 0x000002682DC8AFD0>, 'ctx': {'error': "MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)"}}
|
||||
|
||||
File "C:\Users\yfili\Desktop\Planet\New-planet-api\new-planet-backend\app\api\v1\schedules.py", line 54, in create_schedule
|
||||
POST /api/v1/schedules
|
||||
Traceback (most recent call last):
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__
|
||||
await self.app(scope, receive, _send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 191, in __call__
|
||||
with recv_stream, send_stream, collapse_excgroups():
|
||||
~~~~~~~~~~~~~~~~~~^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\contextlib.py", line 162, in __exit__
|
||||
self.gen.throw(value)
|
||||
~~~~~~~~~~~~~~^^^^^^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_utils.py", line 85, in collapse_excgroups
|
||||
raise exc
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__
|
||||
response = await self.dispatch_func(request, call_next)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "C:\Users\yfili\Desktop\Planet\New-planet-api\new-planet-backend\app\middleware\rate_limiter.py", line 33, in dispatch
|
||||
response = await call_next(request)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next
|
||||
raise app_exc from app_exc.__cause__ or app_exc.__context__
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 144, in coro
|
||||
await self.app(scope, receive_or_disconnect, send_no_error)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\cors.py", line 85, in __call__
|
||||
await self.app(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__
|
||||
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
|
||||
raise exc
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
|
||||
await app(scope, receive, sender)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__
|
||||
await self.app(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\routing.py", line 716, in __call__
|
||||
await self.middleware_stack(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\routing.py", line 736, in app
|
||||
await route.handle(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\routing.py", line 290, in handle
|
||||
await self.app(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 119, in app
|
||||
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
|
||||
raise exc
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
|
||||
await app(scope, receive, sender)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 105, in app
|
||||
response = await f(request)
|
||||
^^^^^^^^^^^^^^^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 448, in app
|
||||
content = await serialize_response(
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...<10 lines>...
|
||||
)
|
||||
^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 274, in serialize_response
|
||||
raise ResponseValidationError(
|
||||
...<3 lines>...
|
||||
)
|
||||
fastapi.exceptions.ResponseValidationError: 1 validation error:
|
||||
{'type': 'get_attribute_error', 'loc': ('response', 'tasks'), 'msg': "Error extracting attribute: MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)", 'input': <app.models.schedule.Schedule object at 0x000002682DC8AFD0>, 'ctx': {'error': "MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)"}}
|
||||
|
||||
File "C:\Users\yfili\Desktop\Planet\New-planet-api\new-planet-backend\app\api\v1\schedules.py", line 54, in create_schedule
|
||||
POST /api/v1/schedules
|
||||
2025-12-26 19:40:04 - app.middleware.error_handler - ERROR - Unhandled exception: 1 validation error:
|
||||
{'type': 'get_attribute_error', 'loc': ('response', 'tasks'), 'msg': "Error extracting attribute: MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)", 'input': <app.models.schedule.Schedule object at 0x000002682DC8AFD0>, 'ctx': {'error': "MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)"}}
|
||||
|
||||
File "C:\Users\yfili\Desktop\Planet\New-planet-api\new-planet-backend\app\api\v1\schedules.py", line 54, in create_schedule
|
||||
POST /api/v1/schedules
|
||||
Traceback (most recent call last):
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__
|
||||
await self.app(scope, receive, _send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 191, in __call__
|
||||
with recv_stream, send_stream, collapse_excgroups():
|
||||
~~~~~~~~~~~~~~~~~~^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\contextlib.py", line 162, in __exit__
|
||||
self.gen.throw(value)
|
||||
~~~~~~~~~~~~~~^^^^^^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_utils.py", line 85, in collapse_excgroups
|
||||
raise exc
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__
|
||||
response = await self.dispatch_func(request, call_next)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "C:\Users\yfili\Desktop\Planet\New-planet-api\new-planet-backend\app\middleware\rate_limiter.py", line 33, in dispatch
|
||||
response = await call_next(request)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next
|
||||
raise app_exc from app_exc.__cause__ or app_exc.__context__
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\base.py", line 144, in coro
|
||||
await self.app(scope, receive_or_disconnect, send_no_error)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\cors.py", line 85, in __call__
|
||||
await self.app(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__
|
||||
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
|
||||
raise exc
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
|
||||
await app(scope, receive, sender)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__
|
||||
await self.app(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\routing.py", line 716, in __call__
|
||||
await self.middleware_stack(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\routing.py", line 736, in app
|
||||
await route.handle(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\routing.py", line 290, in handle
|
||||
await self.app(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 119, in app
|
||||
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
|
||||
raise exc
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
|
||||
await app(scope, receive, sender)
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 105, in app
|
||||
response = await f(request)
|
||||
^^^^^^^^^^^^^^^^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 448, in app
|
||||
content = await serialize_response(
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...<10 lines>...
|
||||
)
|
||||
^
|
||||
File "C:\Users\yfili\AppData\Local\Programs\Python\Python313\Lib\site-packages\fastapi\routing.py", line 274, in serialize_response
|
||||
raise ResponseValidationError(
|
||||
...<3 lines>...
|
||||
)
|
||||
fastapi.exceptions.ResponseValidationError: 1 validation error:
|
||||
{'type': 'get_attribute_error', 'loc': ('response', 'tasks'), 'msg': "Error extracting attribute: MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)", 'input': <app.models.schedule.Schedule object at 0x000002682DC8AFD0>, 'ctx': {'error': "MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)"}}
|
||||
|
||||
File "C:\Users\yfili\Desktop\Planet\New-planet-api\new-planet-backend\app\api\v1\schedules.py", line 54, in create_schedule
|
||||
POST /api/v1/schedules
|
||||
2025-12-26 19:43:44 - root - INFO - Shutting down...
|
||||
2025-12-26 19:43:44 - root - INFO - Shutting down...
|
||||
2025-12-26 19:43:48 - root - INFO - Starting up...
|
||||
2025-12-26 19:43:48 - root - INFO - Starting up...
|
||||
2025-12-26 22:22:32 - root - INFO - Shutting down...
|
||||
2025-12-26 22:22:32 - root - INFO - Shutting down...
|
||||
@@ -88,7 +88,7 @@ if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run(
|
||||
"app.main:app",
|
||||
host="127.0.0.1",
|
||||
host="0.0.0.0",
|
||||
port=8000,
|
||||
reload=settings.DEBUG
|
||||
)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
new-planet-backend/app/models/__pycache__/reward.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/models/__pycache__/reward.cpython-313.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
new-planet-backend/app/models/__pycache__/task.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/models/__pycache__/task.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/models/__pycache__/user.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/models/__pycache__/user.cpython-313.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
new-planet-backend/app/schemas/__pycache__/ai.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/schemas/__pycache__/ai.cpython-313.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
new-planet-backend/app/schemas/__pycache__/task.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/schemas/__pycache__/task.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/schemas/__pycache__/token.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/schemas/__pycache__/token.cpython-313.pyc
Normal file
Binary file not shown.
BIN
new-planet-backend/app/schemas/__pycache__/user.cpython-313.pyc
Normal file
BIN
new-planet-backend/app/schemas/__pycache__/user.cpython-313.pyc
Normal file
Binary file not shown.
@@ -4,6 +4,7 @@ from app.services.storage_service import storage_service, StorageService
|
||||
from app.services.gigachat_service import gigachat_service, GigaChatService
|
||||
from app.services.chat_service import chat_service, ChatService
|
||||
from app.services.schedule_generator import schedule_generator, ScheduleGenerator
|
||||
from app.services.ai_agent_client import ai_agent_client, AIAgentClient
|
||||
|
||||
__all__ = [
|
||||
"auth_service",
|
||||
@@ -18,5 +19,7 @@ __all__ = [
|
||||
"ChatService",
|
||||
"schedule_generator",
|
||||
"ScheduleGenerator",
|
||||
"ai_agent_client",
|
||||
"AIAgentClient",
|
||||
]
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
117
new-planet-backend/app/services/ai_agent_client.py
Normal file
117
new-planet-backend/app/services/ai_agent_client.py
Normal file
@@ -0,0 +1,117 @@
|
||||
import aiohttp
|
||||
from typing import Optional, List, Dict, Any
|
||||
from app.core.config import settings
|
||||
|
||||
|
||||
class AIAgentClient:
|
||||
"""
|
||||
Клиент для взаимодействия с внешним AI-agent сервисом.
|
||||
|
||||
Сервис должен быть доступен в Docker сети и предоставлять следующие endpoints:
|
||||
- POST /api/v1/chat - для чата с ИИ
|
||||
- POST /api/v1/schedule/generate - для генерации расписаний
|
||||
|
||||
Примечание: Структура API endpoints может отличаться в зависимости от реализации
|
||||
внешнего сервиса. При необходимости измените пути в методах этого класса.
|
||||
"""
|
||||
|
||||
def __init__(self, base_url: Optional[str] = None):
|
||||
self.base_url = base_url or settings.AI_AGENT_BASE_URL
|
||||
if not self.base_url.endswith('/'):
|
||||
self.base_url = self.base_url.rstrip('/')
|
||||
|
||||
async def chat(
|
||||
self,
|
||||
message: str,
|
||||
conversation_id: Optional[str] = None,
|
||||
context: Optional[List[Dict[str, Any]]] = None
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Отправить сообщение в чат через AI-agent сервис.
|
||||
|
||||
Ожидаемый формат ответа от сервиса:
|
||||
{
|
||||
"response": "текст ответа",
|
||||
"conversation_id": "id беседы",
|
||||
"tokens_used": 100,
|
||||
"model": "модель"
|
||||
}
|
||||
или формат GigaChat API (с полем choices).
|
||||
"""
|
||||
url = f"{self.base_url}/api/v1/chat"
|
||||
|
||||
payload = {
|
||||
"message": message,
|
||||
}
|
||||
|
||||
if conversation_id:
|
||||
payload["conversation_id"] = conversation_id
|
||||
|
||||
if context:
|
||||
payload["context"] = context
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(url, json=payload, timeout=aiohttp.ClientTimeout(total=120)) as response:
|
||||
if response.status != 200:
|
||||
error_text = await response.text()
|
||||
raise Exception(
|
||||
f"AI-agent service error: HTTP {response.status} - {error_text}"
|
||||
)
|
||||
|
||||
result = await response.json()
|
||||
return result
|
||||
|
||||
async def generate_schedule(
|
||||
self,
|
||||
child_age: int,
|
||||
preferences: List[str],
|
||||
date: str,
|
||||
description: Optional[str] = None
|
||||
) -> Dict[str, Any]:
|
||||
"""Сгенерировать расписание через AI-agent сервис"""
|
||||
url = f"{self.base_url}/api/v1/schedule/generate"
|
||||
|
||||
payload = {
|
||||
"child_age": child_age,
|
||||
"preferences": preferences,
|
||||
"date": date
|
||||
}
|
||||
|
||||
if description:
|
||||
payload["description"] = description
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(url, json=payload, timeout=aiohttp.ClientTimeout(total=120)) as response:
|
||||
if response.status != 200:
|
||||
error_text = await response.text()
|
||||
raise Exception(
|
||||
f"AI-agent service error: HTTP {response.status} - {error_text}"
|
||||
)
|
||||
|
||||
result = await response.json()
|
||||
return result
|
||||
|
||||
async def generate_text(
|
||||
self,
|
||||
prompt: str,
|
||||
model: Optional[str] = None
|
||||
) -> str:
|
||||
"""Генерация текста по промпту через AI-agent сервис"""
|
||||
# Для совместимости с текущим интерфейсом используем chat endpoint
|
||||
result = await self.chat(message=prompt)
|
||||
|
||||
# Извлекаем текст ответа
|
||||
# Предполагаем, что ответ имеет структуру ChatResponse
|
||||
response_text = result.get("response", "")
|
||||
if not response_text:
|
||||
# Если структура другая, пытаемся извлечь из choices (как в GigaChat формате)
|
||||
choices = result.get("choices", [])
|
||||
if choices:
|
||||
response_text = choices[0].get("message", {}).get("content", "")
|
||||
|
||||
return response_text
|
||||
|
||||
|
||||
# Создаем экземпляр клиента
|
||||
ai_agent_client = AIAgentClient()
|
||||
|
||||
@@ -7,19 +7,26 @@ import time
|
||||
from urllib.parse import urlencode
|
||||
from typing import Optional, List, Dict, Any
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from app.core.config import settings
|
||||
|
||||
load_dotenv()
|
||||
from app.services.ai_agent_client import ai_agent_client
|
||||
|
||||
class GigaChatService:
|
||||
"""
|
||||
Сервис для работы с GigaChat через внешний AI-agent сервис.
|
||||
Все запросы к GigaChat теперь проходят через внешний сервис.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.access_token: Optional[str] = None
|
||||
self.token_expires_at: Optional[float] = None
|
||||
|
||||
async def _get_token(self) -> str:
|
||||
"""Получить OAuth токен"""
|
||||
"""
|
||||
Получить OAuth токен.
|
||||
|
||||
ВНИМАНИЕ: Этот метод больше не используется, так как все запросы
|
||||
к GigaChat теперь проходят через внешний AI-agent сервис.
|
||||
Метод оставлен для возможной обратной совместимости.
|
||||
"""
|
||||
# Проверяем, не истек ли токен (оставляем запас 60 секунд)
|
||||
if self.access_token and self.token_expires_at:
|
||||
if time.time() < (self.token_expires_at - 60):
|
||||
@@ -110,49 +117,59 @@ class GigaChatService:
|
||||
context: Optional[List[Dict[str, Any]]] = None,
|
||||
model: str = None
|
||||
) -> Dict[str, Any]:
|
||||
"""Отправить сообщение в GigaChat"""
|
||||
token = await self._get_token()
|
||||
model = model or settings.GIGACHAT_MODEL_CHAT or "GigaChat"
|
||||
"""
|
||||
Отправить сообщение в GigaChat через внешний AI-agent сервис.
|
||||
Сохраняет обратную совместимость с форматом ответа GigaChat API.
|
||||
"""
|
||||
try:
|
||||
# Используем внешний AI-agent сервис
|
||||
result = await ai_agent_client.chat(
|
||||
message=message,
|
||||
conversation_id=None, # Если нужен conversation_id, его нужно передавать отдельно
|
||||
context=context
|
||||
)
|
||||
|
||||
messages = context or []
|
||||
messages.append({"role": "user", "content": message})
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json"
|
||||
# Преобразуем ответ AI-agent сервиса в формат, совместимый с GigaChat API
|
||||
# Предполагаем, что ai_agent_client возвращает структуру ChatResponse или аналогичную
|
||||
if "response" in result:
|
||||
# Если ответ в формате ChatResponse, преобразуем в формат GigaChat
|
||||
return {
|
||||
"model": result.get("model", model or settings.GIGACHAT_MODEL_CHAT or "GigaChat"),
|
||||
"choices": [{
|
||||
"message": {
|
||||
"role": "assistant",
|
||||
"content": result["response"]
|
||||
},
|
||||
"finish_reason": "stop"
|
||||
}],
|
||||
"usage": {
|
||||
"total_tokens": result.get("tokens_used", 0),
|
||||
"prompt_tokens": 0,
|
||||
"completion_tokens": result.get("tokens_used", 0)
|
||||
}
|
||||
|
||||
payload = {
|
||||
"model": model,
|
||||
"messages": messages,
|
||||
"temperature": 0.7,
|
||||
"max_tokens": 2000
|
||||
}
|
||||
|
||||
# Отключаем проверку SSL (только для разработки!)
|
||||
# Используем ssl=False для полного отключения проверки сертификата
|
||||
connector = aiohttp.TCPConnector(ssl=False)
|
||||
async with aiohttp.ClientSession(connector=connector) as session:
|
||||
async with session.post(
|
||||
f"{settings.GIGACHAT_BASE_URL}/chat/completions",
|
||||
headers=headers,
|
||||
json=payload
|
||||
) as response:
|
||||
if response.status != 200:
|
||||
error_text = await response.text()
|
||||
raise Exception(f"GigaChat API error: {response.status} - {error_text}")
|
||||
|
||||
result = await response.json()
|
||||
else:
|
||||
# Если ответ уже в формате GigaChat, возвращаем как есть
|
||||
return result
|
||||
except Exception as e:
|
||||
# Если внешний сервис недоступен, пробрасываем ошибку
|
||||
raise Exception(f"AI-agent service error: {str(e)}")
|
||||
|
||||
async def generate_text(
|
||||
self,
|
||||
prompt: str,
|
||||
model: str = None
|
||||
) -> str:
|
||||
"""Генерация текста по промпту"""
|
||||
result = await self.chat(prompt, model=model)
|
||||
return result.get("choices", [{}])[0].get("message", {}).get("content", "")
|
||||
"""
|
||||
Генерация текста по промпту через внешний AI-agent сервис.
|
||||
"""
|
||||
try:
|
||||
# Используем метод generate_text из ai_agent_client
|
||||
response_text = await ai_agent_client.generate_text(prompt=prompt, model=model)
|
||||
return response_text
|
||||
except Exception as e:
|
||||
# Если произошла ошибка, пробрасываем её
|
||||
raise Exception(f"AI-agent service error: {str(e)}")
|
||||
|
||||
|
||||
gigachat_service = GigaChatService()
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import json
|
||||
from typing import List, Dict, Any, Optional
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import selectinload
|
||||
from app.services.gigachat_service import gigachat_service
|
||||
from app.core.config import settings
|
||||
from app.crud import schedule as crud_schedule, task as crud_task
|
||||
from app.schemas.schedule import ScheduleCreate
|
||||
from app.schemas.task import TaskCreate
|
||||
from app.models.schedule import Schedule
|
||||
from datetime import date
|
||||
|
||||
|
||||
@@ -104,11 +107,17 @@ class ScheduleGenerator:
|
||||
|
||||
await crud_task.create(db, task_create.model_dump())
|
||||
|
||||
await db.refresh(db_schedule)
|
||||
# Загружаем расписание с задачами через selectinload для async корректной работы
|
||||
result = await db.execute(
|
||||
select(Schedule)
|
||||
.where(Schedule.id == db_schedule.id)
|
||||
.options(selectinload(Schedule.tasks))
|
||||
)
|
||||
db_schedule_with_tasks = result.scalar_one()
|
||||
|
||||
return {
|
||||
"schedule_id": db_schedule.id,
|
||||
"title": db_schedule.title,
|
||||
"schedule_id": db_schedule_with_tasks.id,
|
||||
"title": db_schedule_with_tasks.title,
|
||||
"tasks": [
|
||||
{
|
||||
"title": task.title,
|
||||
@@ -117,7 +126,7 @@ class ScheduleGenerator:
|
||||
"category": task.category,
|
||||
"order": task.order
|
||||
}
|
||||
for task in db_schedule.tasks
|
||||
for task in db_schedule_with_tasks.tasks
|
||||
]
|
||||
}
|
||||
except json.JSONDecodeError as e:
|
||||
|
||||
@@ -63,4 +63,8 @@ volumes:
|
||||
networks:
|
||||
new-planet-network:
|
||||
driver: bridge
|
||||
# ВАЖНО: Внешний AI-agent сервис (https://git.bro-js.ru/Glevel/New-planet-ai-agent.git)
|
||||
# должен быть запущен в этой же сети для доступа к GigaChat.
|
||||
# Убедитесь, что сервис ai-agent доступен по имени 'ai-agent' в сети new-planet-network.
|
||||
external: false
|
||||
|
||||
|
||||
@@ -1580,3 +1580,15 @@ redis.exceptions.ConnectionError: Error 111 connecting to localhost:6379. Connec
|
||||
2025-12-18 23:00:15 - root - INFO - Starting up...
|
||||
2025-12-18 23:00:15 - root - INFO - Shutting down...
|
||||
2025-12-18 23:00:15 - root - INFO - Shutting down...
|
||||
2025-12-23 19:00:39 - root - INFO - Starting up...
|
||||
2025-12-23 19:00:39 - root - INFO - Starting up...
|
||||
2025-12-23 19:52:34 - root - INFO - Shutting down...
|
||||
2025-12-23 19:52:34 - root - INFO - Shutting down...
|
||||
2025-12-23 19:52:58 - root - INFO - Starting up...
|
||||
2025-12-23 19:52:58 - root - INFO - Starting up...
|
||||
2025-12-23 19:54:27 - root - INFO - Shutting down...
|
||||
2025-12-23 19:54:27 - root - INFO - Shutting down...
|
||||
2025-12-23 19:54:34 - root - INFO - Starting up...
|
||||
2025-12-23 19:54:34 - root - INFO - Starting up...
|
||||
2025-12-23 20:00:23 - root - INFO - Shutting down...
|
||||
2025-12-23 20:00:23 - root - INFO - Shutting down...
|
||||
|
||||
Reference in New Issue
Block a user