habulaj commited on
Commit
c919ade
·
verified ·
1 Parent(s): 29a5240

Update routes/subscription.py

Browse files
Files changed (1) hide show
  1. routes/subscription.py +56 -62
routes/subscription.py CHANGED
@@ -5,6 +5,7 @@ from datetime import datetime
5
  import pytz
6
  import os
7
  import requests
 
8
  import jwt
9
  from fastapi import APIRouter, HTTPException, Request, Header
10
  from pydantic import BaseModel
@@ -474,7 +475,7 @@ def cancel_subscription(data: CancelSubscriptionRequest):
474
  raise HTTPException(status_code=500, detail=str(e))
475
 
476
  @router.post("/check_subscription")
477
- def check_subscription(
478
  data: CheckSubscriptionRequest,
479
  user_token: str = Header(None, alias="User-key")
480
  ):
@@ -486,9 +487,9 @@ def check_subscription(
486
  user_id = verify_token(user_token)
487
 
488
  # 🔹 Buscar o stripe_id do usuário no Supabase
489
- response_user = requests.get(
490
  f"{SUPABASE_URL}/rest/v1/User?id=eq.{user_id}",
491
- headers=SUPABASE_HEADERS
492
  )
493
  user_data = response_user.json()
494
  if not user_data:
@@ -499,46 +500,28 @@ def check_subscription(
499
  raise HTTPException(status_code=404, detail="Stripe customer not found for user")
500
 
501
  # 🔹 Buscar todas as assinaturas do cliente (ativas, canceladas, expiradas, etc.)
502
- subscriptions = stripe.Subscription.list(
 
503
  customer=user_stripe_id,
504
  expand=["data.items"]
505
  )
506
 
507
  logger.info(f"Stripe response data: {subscriptions}")
508
 
509
- if not subscriptions or "data" not in subscriptions or not subscriptions["data"]:
510
  # Se não houver assinaturas para o cliente, desativa as assinaturas associadas ao estilista no banco de dados
511
  logger.info(f"No active subscription found for user {user_id}. Deactivating all subscriptions for stylist {data.stylist_id}.")
512
 
513
  # 🔹 Buscar todas as assinaturas do estilista no banco de dados para este cliente
514
- response_subscriptions = requests.get(
515
  f"{SUPABASE_URL}/rest/v1/Subscriptions?customer_id=eq.{user_id}&stylist_id=eq.{data.stylist_id}",
516
- headers=SUPABASE_HEADERS
517
  )
518
  if response_subscriptions.status_code == 200:
519
  subscriptions_data = response_subscriptions.json()
520
-
521
- # 🔹 Preparar a atualização em lote
522
- update_data = [{"id": sub["id"], "active": False} for sub in subscriptions_data]
523
-
524
- # Atualiza todas as assinaturas do estilista no banco de dados de uma vez
525
- if update_data:
526
- update_response = requests.patch(
527
- f"{SUPABASE_URL}/rest/v1/Subscriptions",
528
- headers=SUPABASE_HEADERS,
529
- json=update_data
530
- )
531
- if update_response.status_code == 200:
532
- logger.info(f"✅ All subscriptions for stylist {data.stylist_id} deactivated successfully.")
533
- else:
534
- logger.error(f"❌ Failed to deactivate subscriptions for stylist {data.stylist_id}.")
535
-
536
- # Retorna as assinaturas desativadas no banco
537
- return {
538
- "status": "inactive",
539
- "message": "No active subscription found for stylist.",
540
- "subscriptions_updated": subscriptions_data
541
- }
542
  else:
543
  logger.error(f"❌ Failed to fetch subscriptions from Supabase for stylist {data.stylist_id} and user {user_id}.")
544
 
@@ -578,17 +561,13 @@ def check_subscription(
578
  "canceled_date": canceled_at_date
579
  }
580
 
581
- response_subscription = requests.post(
582
  f"{SUPABASE_URL}/rest/v1/Subscriptions",
583
- headers=SUPABASE_HEADERS,
584
- json=subscription_data
 
585
  )
586
 
587
- if response_subscription.status_code == 201:
588
- logger.info(f"✅ Subscription updated successfully for user {user_id}")
589
- else:
590
- logger.error(f"❌ Failed to update subscription: {response_subscription.status_code} - {response_subscription.text}")
591
-
592
  # Retorna informações sobre a assinatura sincronizada
593
  return {
594
  "status": status,
@@ -604,38 +583,53 @@ def check_subscription(
604
  logger.info(f"No active subscription found for stylist {data.stylist_id}. Deactivating all subscriptions for this stylist.")
605
 
606
  # 🔹 Buscar todas as assinaturas do estilista no banco de dados
607
- response_subscriptions = requests.get(
608
  f"{SUPABASE_URL}/rest/v1/Subscriptions?stylist_id=eq.{data.stylist_id}",
609
- headers=SUPABASE_HEADERS
610
  )
611
  if response_subscriptions.status_code == 200:
612
  subscriptions_data = response_subscriptions.json()
613
-
614
- # 🔹 Preparar a atualização em lote
615
- update_data = [{"id": sub["id"], "active": False} for sub in subscriptions_data]
616
-
617
- # Atualiza todas as assinaturas do estilista no banco de dados de uma vez
618
- if update_data:
619
- update_response = requests.patch(
620
- f"{SUPABASE_URL}/rest/v1/Subscriptions",
621
- headers=SUPABASE_HEADERS,
622
- json=update_data
623
- )
624
- if update_response.status_code == 200:
625
- logger.info(f"✅ All subscriptions for stylist {data.stylist_id} deactivated successfully.")
626
- else:
627
- logger.error(f"❌ Failed to deactivate subscriptions for stylist {data.stylist_id}.")
628
-
629
- # Retorna as assinaturas desativadas no banco
630
- return {
631
- "status": "inactive",
632
- "message": "No active subscription found for stylist.",
633
- "subscriptions_updated": subscriptions_data
634
- }
635
 
636
  except stripe.error.StripeError as e:
637
  logger.error(f"Stripe error: {str(e)}")
638
  raise HTTPException(status_code=500, detail=f"Stripe error: {str(e)}")
639
  except Exception as e:
640
  logger.error(f"Error checking subscription: {str(e)}")
641
- raise HTTPException(status_code=500, detail="Error checking subscription.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  import pytz
6
  import os
7
  import requests
8
+ import asyncio
9
  import jwt
10
  from fastapi import APIRouter, HTTPException, Request, Header
11
  from pydantic import BaseModel
 
475
  raise HTTPException(status_code=500, detail=str(e))
476
 
477
  @router.post("/check_subscription")
478
+ async def check_subscription(
479
  data: CheckSubscriptionRequest,
480
  user_token: str = Header(None, alias="User-key")
481
  ):
 
487
  user_id = verify_token(user_token)
488
 
489
  # 🔹 Buscar o stripe_id do usuário no Supabase
490
+ response_user = await async_request(
491
  f"{SUPABASE_URL}/rest/v1/User?id=eq.{user_id}",
492
+ SUPABASE_HEADERS
493
  )
494
  user_data = response_user.json()
495
  if not user_data:
 
500
  raise HTTPException(status_code=404, detail="Stripe customer not found for user")
501
 
502
  # 🔹 Buscar todas as assinaturas do cliente (ativas, canceladas, expiradas, etc.)
503
+ subscriptions = await async_stripe_request(
504
+ stripe.Subscription.list,
505
  customer=user_stripe_id,
506
  expand=["data.items"]
507
  )
508
 
509
  logger.info(f"Stripe response data: {subscriptions}")
510
 
511
+ if not subscriptions or not subscriptions["data"]:
512
  # Se não houver assinaturas para o cliente, desativa as assinaturas associadas ao estilista no banco de dados
513
  logger.info(f"No active subscription found for user {user_id}. Deactivating all subscriptions for stylist {data.stylist_id}.")
514
 
515
  # 🔹 Buscar todas as assinaturas do estilista no banco de dados para este cliente
516
+ response_subscriptions = await async_request(
517
  f"{SUPABASE_URL}/rest/v1/Subscriptions?customer_id=eq.{user_id}&stylist_id=eq.{data.stylist_id}",
518
+ SUPABASE_HEADERS
519
  )
520
  if response_subscriptions.status_code == 200:
521
  subscriptions_data = response_subscriptions.json()
522
+ await asyncio.gather(
523
+ *(update_subscription_status(sub['id'], False) for sub in subscriptions_data)
524
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
525
  else:
526
  logger.error(f"❌ Failed to fetch subscriptions from Supabase for stylist {data.stylist_id} and user {user_id}.")
527
 
 
561
  "canceled_date": canceled_at_date
562
  }
563
 
564
+ await async_request(
565
  f"{SUPABASE_URL}/rest/v1/Subscriptions",
566
+ SUPABASE_HEADERS,
567
+ json=subscription_data,
568
+ method='POST'
569
  )
570
 
 
 
 
 
 
571
  # Retorna informações sobre a assinatura sincronizada
572
  return {
573
  "status": status,
 
583
  logger.info(f"No active subscription found for stylist {data.stylist_id}. Deactivating all subscriptions for this stylist.")
584
 
585
  # 🔹 Buscar todas as assinaturas do estilista no banco de dados
586
+ response_subscriptions = await async_request(
587
  f"{SUPABASE_URL}/rest/v1/Subscriptions?stylist_id=eq.{data.stylist_id}",
588
+ SUPABASE_HEADERS
589
  )
590
  if response_subscriptions.status_code == 200:
591
  subscriptions_data = response_subscriptions.json()
592
+ await asyncio.gather(
593
+ *(update_subscription_status(sub['id'], False) for sub in subscriptions_data)
594
+ )
595
+ else:
596
+ logger.error(f"❌ Failed to fetch subscriptions from Supabase for stylist {data.stylist_id}.")
597
+
598
+ return {"status": "inactive", "message": "No active subscription found for stylist."}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
599
 
600
  except stripe.error.StripeError as e:
601
  logger.error(f"Stripe error: {str(e)}")
602
  raise HTTPException(status_code=500, detail=f"Stripe error: {str(e)}")
603
  except Exception as e:
604
  logger.error(f"Error checking subscription: {str(e)}")
605
+ raise HTTPException(status_code=500, detail="Error checking subscription.")
606
+
607
+
608
+ # Função assíncrona para fazer requisições de rede
609
+ async def async_request(url, headers, json=None, method='GET'):
610
+ method_func = requests.post if method == 'POST' else requests.get
611
+ response = method_func(url, headers=headers, json=json)
612
+ return response
613
+
614
+ # Função assíncrona para chamar a Stripe API
615
+ async def async_stripe_request(func, **kwargs):
616
+ loop = asyncio.get_event_loop()
617
+ response = await loop.run_in_executor(None, lambda: func(**kwargs))
618
+ return response
619
+
620
+ # Função assíncrona para atualizar o status de uma assinatura
621
+ async def update_subscription_status(subscription_id, status):
622
+ update_data = {
623
+ "active": status
624
+ }
625
+ subscription_url = f"{SUPABASE_URL}/rest/v1/Subscriptions?id=eq.{subscription_id}"
626
+ update_response = await async_request(
627
+ subscription_url,
628
+ SUPABASE_HEADERS,
629
+ json=update_data,
630
+ method='PATCH'
631
+ )
632
+ if update_response.status_code == 200:
633
+ logger.info(f"✅ Subscription {subscription_id} deactivated successfully.")
634
+ else:
635
+ logger.error(f"❌ Failed to deactivate subscription {subscription_id}.")