22Subscription API handling
33"""
44
5- from typing import Awaitable , Callable , Union , Any , Optional , Tuple , List
5+ from typing import Awaitable , Callable , Any , Optional , Tuple , List , Annotated
66import os
77import asyncio
88from uuid import UUID
99from datetime import datetime
1010
11- from fastapi import APIRouter , Depends , HTTPException , Request
11+ from fastapi import APIRouter , Depends , HTTPException , Request , Query
1212import aiohttp
1313from motor .motor_asyncio import AsyncIOMotorDatabase
1414
2323 SubscriptionImport ,
2424 SubscriptionUpdate ,
2525 SubscriptionCancel ,
26+ SubscriptionAddMinutes ,
27+ SubscriptionEventAny ,
2628 SubscriptionCreateOut ,
2729 SubscriptionImportOut ,
2830 SubscriptionUpdateOut ,
2931 SubscriptionCancelOut ,
32+ SubscriptionAddMinutesOut ,
33+ SubscriptionEventAnyOut ,
34+ SubscriptionEventType ,
3035 Subscription ,
3136 SubscriptionPortalUrlRequest ,
3237 SubscriptionPortalUrlResponse ,
3338 SubscriptionCanceledResponse ,
3439 SubscriptionTrialEndReminder ,
3540 Organization ,
41+ OrgQuotasIn ,
3642 InviteToOrgRequest ,
3743 InviteAddedResponse ,
3844 User ,
@@ -228,15 +234,22 @@ async def send_trial_end_reminder(
228234
229235 return SuccessResponse (success = True )
230236
237+ async def add_sub_minutes (self , add_min : SubscriptionAddMinutes ):
238+ """add extra minutes for subscription"""
239+ org = await self .org_ops .get_org_by_id (add_min .oid )
240+ quotas = OrgQuotasIn (extraExecMinutes = add_min .minutes )
241+ await self .org_ops .update_quotas (
242+ org , quotas , mode = "add" , context = add_min .context
243+ )
244+
245+ await self .add_sub_event ("add-minutes" , add_min , add_min .oid )
246+
247+ return {"updated" : True }
248+
231249 async def add_sub_event (
232250 self ,
233- type_ : str ,
234- event : Union [
235- SubscriptionCreate ,
236- SubscriptionImport ,
237- SubscriptionUpdate ,
238- SubscriptionCancel ,
239- ],
251+ type_ : SubscriptionEventType ,
252+ event : SubscriptionEventAny ,
240253 oid : UUID ,
241254 ) -> None :
242255 """add a subscription event to the db"""
@@ -246,20 +259,22 @@ async def add_sub_event(
246259 data ["oid" ] = oid
247260 await self .subs .insert_one (data )
248261
249- def _get_sub_by_type_from_data (self , data : dict [str , object ]) -> Union [
250- SubscriptionCreateOut ,
251- SubscriptionImportOut ,
252- SubscriptionUpdateOut ,
253- SubscriptionCancelOut ,
254- ]:
262+ def _get_sub_by_type_from_data (
263+ self , data : dict [str , object ]
264+ ) -> SubscriptionEventAnyOut :
255265 """convert dict to propert background job type"""
256266 if data ["type" ] == "create" :
257267 return SubscriptionCreateOut (** data )
258268 if data ["type" ] == "import" :
259269 return SubscriptionImportOut (** data )
260270 if data ["type" ] == "update" :
261271 return SubscriptionUpdateOut (** data )
262- return SubscriptionCancelOut (** data )
272+ if data ["type" ] == "cancel" :
273+ return SubscriptionCancelOut (** data )
274+ if data ["type" ] == "add-minutes" :
275+ return SubscriptionAddMinutesOut (** data )
276+
277+ raise HTTPException (status_code = 500 , detail = "unknown sub event" )
263278
264279 # pylint: disable=too-many-arguments
265280 async def list_sub_events (
@@ -268,19 +283,13 @@ async def list_sub_events(
268283 sub_id : Optional [str ] = None ,
269284 oid : Optional [UUID ] = None ,
270285 plan_id : Optional [str ] = None ,
286+ type_ : Optional [SubscriptionEventType ] = None ,
271287 page_size : int = DEFAULT_PAGE_SIZE ,
272288 page : int = 1 ,
273289 sort_by : Optional [str ] = None ,
274290 sort_direction : Optional [int ] = - 1 ,
275291 ) -> Tuple [
276- List [
277- Union [
278- SubscriptionCreateOut ,
279- SubscriptionImportOut ,
280- SubscriptionUpdateOut ,
281- SubscriptionCancelOut ,
282- ]
283- ],
292+ List [SubscriptionEventAnyOut ],
284293 int ,
285294 ]:
286295 """list subscription events"""
@@ -298,6 +307,8 @@ async def list_sub_events(
298307 query ["planId" ] = plan_id
299308 if oid :
300309 query ["oid" ] = oid
310+ if type_ :
311+ query ["type" ] = type_
301312
302313 aggregate = [{"$match" : query }]
303314
@@ -515,6 +526,15 @@ async def send_trial_end_reminder(
515526 ):
516527 return await ops .send_trial_end_reminder (reminder )
517528
529+ @app .post (
530+ "/subscriptions/add-minutes" ,
531+ tags = ["subscriptions" ],
532+ dependencies = [Depends (superuser_or_shared_secret_dep )],
533+ response_model = UpdatedResponse ,
534+ )
535+ async def add_sub_minutes (add_min : SubscriptionAddMinutes ):
536+ return await ops .add_sub_minutes (add_min )
537+
518538 assert org_ops .router
519539
520540 @app .get (
@@ -540,6 +560,7 @@ async def get_sub_events(
540560 subId : Optional [str ] = None ,
541561 oid : Optional [UUID ] = None ,
542562 planId : Optional [str ] = None ,
563+ type_ : Annotated [Optional [SubscriptionEventType ], Query (alias = "type" )] = None ,
543564 pageSize : int = DEFAULT_PAGE_SIZE ,
544565 page : int = 1 ,
545566 sortBy : Optional [str ] = "timestamp" ,
@@ -551,6 +572,7 @@ async def get_sub_events(
551572 oid = oid ,
552573 plan_id = planId ,
553574 page_size = pageSize ,
575+ type_ = type_ ,
554576 page = page ,
555577 sort_by = sortBy ,
556578 sort_direction = sortDirection ,
0 commit comments