From d4682b14186d45bd4c443f736f6c62ca8135b215 Mon Sep 17 00:00:00 2001 From: xds Date: Thu, 5 Feb 2026 21:10:50 +0300 Subject: [PATCH] feat: Add optional `telegram_id` field to `Generation` and `GenerationRequest` models. --- __pycache__/main.cpython-313.pyc | Bin 7119 -> 7176 bytes api/__pycache__/dependency.cpython-313.pyc | Bin 1421 -> 1741 bytes api/dependency.py | 8 +++++++- api/models/GenerationRequest.py | 1 + .../GenerationRequest.cpython-313.pyc | Bin 2543 -> 2600 bytes .../generation_service.cpython-313.pyc | Bin 17057 -> 18279 bytes api/service/generation_service.py | 19 +++++++++++++++++- main.py | 3 ++- models/Generation.py | 1 + models/__pycache__/Generation.cpython-313.pyc | Bin 2172 -> 2224 bytes 10 files changed, 29 insertions(+), 3 deletions(-) diff --git a/__pycache__/main.cpython-313.pyc b/__pycache__/main.cpython-313.pyc index f3c3640cd8e4738a222c0a03ab60fe8af68f922a..fee451a6a9f688220cb52fded01727339ac80a84 100644 GIT binary patch delta 308 zcmX?a-eJM}nU|M~0SLHnw`6Xd$ScXXW~2IPCYBgiQ|8TIn3CC06cHgodWGcq$L{2TRHQ)@G~A3Vs+MHI4sWStif_vf(68u;Q@(j zFoM`x@-95gM>v^)B1gCxL2Mpo7yiw6`LviAS8nDIjA3NlxH(mbn~~9Oa-nbo>3mp^mA_(FFv)f|H*jjnh>5bSS zUg(9)5rqDP`3L+LLdPyP0|Pa= zOLr~_@P(58Nyov_&+W0BZLp-<>b%A^6D-+gR>~HuqLm(oRgvp4A|awgNG3)!MAQf| z?8FGz`V{M_R+**QBC06J(223icsAl>`#+&?^lHBHeJK%dCH9E(f!+{OyVoGCO?k_>dzzg zCLBwk8Lyu0sl~2XjKl%~X@S(6h@VB)vVf+4@OJ>pkA~5_gN69v0PeThy~I>Z9R(hB zBO?iyc>x_a$&j8$B-4!dSLp4p;qY3^Z8jD?hd*(b9X^62`p%d(9K!4&4E<7o4Tch9l}8?Mxb#C#vdaf)Efmmy)`r3)`cMKz52+HSKsxg~ IjZxI&Up(`?1poj5 delta 601 zcmXw0&1(}u6rb6h%qIJhkD4}V)wD=M*ri1%8&BfVV=sFVT?io^!`Cw+NU3=C%_RE{@8dV`_rB)FJ9jz{o@W!3tIN;HcSgt`735+q zorfP^JFjOvrjZr1kVVA}a>&4m76?bAq!BkZo{`w;(giQ1ksUMS*qGs{j6({Z&hhdb z9l3cF8j%~@kr#7h6+<4Cm#p%zV)#|rqOtr$FQ_AH#@j+2+j#QWINK?s=bKPL165R+ zHxx(7IOz>Wi5O2|1+i33wFQr4%WM>y=vR@tUJiab!7U456%nY(7JCt>YEVMuQ>dZI zndoNLP)vIV{RwPfRF|i$xv7|$iCD%LT?YmtxiI;hHD_;VcL{D2(Dl`AeFGk&fhVX^ z^}dDkp~==%m!TL7=ueZ$xR(kzNd^L1_^2AEYSWM8Z;`l9zeT?s|CafBgMGh}S?~Ml zw11p{iAjKeN;3JbFzSN37pTqk@VeMFSuC!*7GEAs4nB;;D`;bqI#>EdR(QjhyK AsyncIOMotorClient: return request.app.state.mongo_client @@ -16,6 +18,9 @@ def get_mongo_client(request: Request) -> AsyncIOMotorClient: def get_gemini_client(request: Request) -> GoogleAdapter: return request.app.state.gemini_client +def get_bot_client(request: Request) -> Bot: + return request.app.state.bot + # Провайдер DAO (собирается из mongo_client) def get_dao(mongo_client: AsyncIOMotorClient = Depends(get_mongo_client)) -> DAO: # FastAPI кэширует результат Depends в рамках одного запроса, @@ -26,5 +31,6 @@ def get_dao(mongo_client: AsyncIOMotorClient = Depends(get_mongo_client)) -> DAO def get_generation_service( dao: DAO = Depends(get_dao), gemini: GoogleAdapter = Depends(get_gemini_client), + bot: Bot = Depends(get_bot_client), ) -> GenerationService: - return GenerationService(dao, gemini) \ No newline at end of file + return GenerationService(dao, gemini, bot) \ No newline at end of file diff --git a/api/models/GenerationRequest.py b/api/models/GenerationRequest.py index 0b71ce8..06f8a96 100644 --- a/api/models/GenerationRequest.py +++ b/api/models/GenerationRequest.py @@ -13,6 +13,7 @@ class GenerationRequest(BaseModel): aspect_ratio: AspectRatios = AspectRatios.NINESIXTEEN quality: Quality = Quality.ONEK prompt: str + telegram_id: Optional[int] = None assets_list: List[str] diff --git a/api/models/__pycache__/GenerationRequest.cpython-313.pyc b/api/models/__pycache__/GenerationRequest.cpython-313.pyc index 9bddcb99c794c9cdcc63d26d607b6f4473ec101b..ff498b0c63c3f89ea26d6f101def9d416d5f9e61 100644 GIT binary patch delta 595 zcmZ9I%SyvQ6oxxZlQh~`Yg6$CZMD$G`=V$CQQUe(Dy}Lawo!t;z+{RmFQDjF9YGg9 zfNliw4P2;CAd;02ASkHd(m7KFbr#>8b7s!@|CyKYxu(9UYMqCz4|mtTyHb}BI-_f- z+MD&_hMbrSitH>WXXPa9jXCK%_d}jlaA?)5*U?Wj*FmhJwTjJ>VHezb({U`~7)9G5 z7aqNdE_yeT8tZTcyG$_5a3hA{5R=$>!z2XT%T;1IhJl;ut2d9P>4K1=mSIn z{Q!Z%70Q)$?1OXwFbIeNKnBMFoq)s-G`cC>O8g)}&xBT*mnV@$YkD&1 zjc~o#PxY7a4AcP7=g16PWpAo>Cqtk8TRMLo_rtIMHR}3DOO-;kXpP}=o4 zy13~m4*myjf|E%92?w3UcV2Z61T*|D@7}y~&bv49H`91GjIhMN%jU6jeP?VCa>{l| zHJR_ss|xSuwKZ*o*R>FhmIAiUB7v3Ymgg0HZ?o)p{;g!kSS@hGJ_CIu!7O>3F7$FZJ(!Jg1vO${#kAiVzPB*p2S&G@#_h$Xj`QW&oR`rRvG$(<60D`|Wt1Ivw^-P0FGQ#;+xkE6nu54U{+D$YQy{~ZLj7&)EVo{* zi^#D3_R;?F`AdBo*8zxm8b?EVjYLlt+mFX&**3+tuqdge`iJ|DTjF`yoL;cSVnjrt l^m}cs(Cl8NP%Rg8G{>IwOhh5ph5jM&@)2VsJQTztzW}txb4maJ diff --git a/api/service/__pycache__/generation_service.cpython-313.pyc b/api/service/__pycache__/generation_service.cpython-313.pyc index beca295aca605eed4fc5827538d33401e54f0972..07a5cf1b9a32086bd958443a9a1399463c952be9 100644 GIT binary patch delta 3947 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 t2(%qBehjcFQA+ str: @@ -249,6 +252,20 @@ class GenerationService: await self.dao.generations.update_generation(generation) logger.info(f"Generation {generation.id} completed successfully. {len(created_assets)} assets created. Total Time: {generation.execution_time_seconds:.2f}s") + # 6. Send to Telegram if telegram_id is provided + if generation.telegram_id and self.bot: + try: + for asset in created_assets: + if asset.data: + await self.bot.send_photo( + chat_id=generation.telegram_id, + photo=BufferedInputFile(asset.data, filename=f"{asset.name}.jpg"), + caption=f"Generated from prompt: {generation.prompt[:100]}..." + ) + logger.info(f"Sent {len(created_assets)} assets to Telegram ID: {generation.telegram_id}") + except Exception as e: + logger.error(f"Failed to send assets to Telegram ID {generation.telegram_id}: {e}") + async def _simulate_progress(self, generation: Generation): """ diff --git a/main.py b/main.py index 86e4723..7d11a95 100644 --- a/main.py +++ b/main.py @@ -66,7 +66,7 @@ char_repo = CharacterRepo(mongo_client) dao = DAO(mongo_client) # Главный DAO для бота dao = DAO(mongo_client) # Главный DAO для бота gemini = GoogleAdapter(api_key=GEMINI_API_KEY) -generation_service = GenerationService(dao, gemini) +generation_service = GenerationService(dao, gemini, bot) # Dispatcher dp = Dispatcher(storage=MongoStorage(mongo_client, db_name=DB_NAME)) @@ -118,6 +118,7 @@ async def lifespan(app: FastAPI): app.state.mongo_client = mongo_client app.state.mongo_client = mongo_client app.state.gemini_client = gemini + app.state.bot = bot print("✅ DB & DAO initialized") diff --git a/models/Generation.py b/models/Generation.py index 2f1f510..9bd313b 100644 --- a/models/Generation.py +++ b/models/Generation.py @@ -18,6 +18,7 @@ class Generation(BaseModel): status: GenerationStatus = GenerationStatus.RUNNING failed_reason: Optional[str] = None linked_character_id: Optional[str] = None + telegram_id: Optional[int] = None aspect_ratio: AspectRatios quality: Quality prompt: str diff --git a/models/__pycache__/Generation.cpython-313.pyc b/models/__pycache__/Generation.cpython-313.pyc index 036c27fcafa212dcd3d426651eb2ca4185b5a93b..d31ee7023e7984ab0e9d2743c3a7f4dbb4cef236 100644 GIT binary patch delta 499 zcmew(utAXTGcPX}0}y<_)siXBvXQTbi7{ewH&bDKFjEn43~LM@D^N0qJ(yh`MDqh# z9AK6Jki`jRu>o0JAQn)EAW#PzR0lU$RtV1LfvOQkQo{=t<0}%0;RBk&4^<%wR8cPm zHAVm`C=L{ai3vi*B!FTt2MU42VkDIqf`z3Rf<-JDi=<+tfrg60#l@iFGGK9Wuo)6X zvgu5klDD|rQ}a@b5=%1k^Ii%74f31(jMPkzHH#V9wKoz2fr4JdGnIWw=Mh#Mru10u9Q1RIFZ z0TH?&LJvsXVol4*Pb?|Y2MHK}2u=`T2_l$5g!SZkY-)@*Cm&^V;#E{_@SY$sLwTa? mWfs-VZ0u}|j5d>bIn)_lC!2DZ2?{a#Fiw#C$^fFl4g~6GcPX}0}#xf)sp#O@fHci2m^KSK~;zVRfs}O;fIQe0mUL= zf&x%MaiE|uRG}b9EJi|!Ay`O?Az0Xwu}CsT3TUVZTwD|?E)5nJ1DhdUB$LjhDKYs4 zv-4&P79~bTg~`#ZT^fc!vx;iCfH>c_l@&cEB>c9xd