Subscription implementation complete, Renewal system implemented
This commit is contained in:
@@ -157,8 +157,8 @@ class BlogSEOMetadataGenerator:
|
||||
|
||||
# Get structured response from Gemini
|
||||
ai_response = self.gemini_provider(
|
||||
prompt=prompt,
|
||||
schema=schema,
|
||||
prompt,
|
||||
schema,
|
||||
temperature=0.3,
|
||||
max_tokens=2048
|
||||
)
|
||||
@@ -167,6 +167,8 @@ class BlogSEOMetadataGenerator:
|
||||
if not ai_response or not isinstance(ai_response, dict):
|
||||
logger.error("Core metadata generation failed: Invalid response from Gemini")
|
||||
# Return fallback response
|
||||
primary_keywords = ', '.join(keywords_data.get('primary_keywords', ['content']))
|
||||
word_count = len(blog_content.split())
|
||||
return {
|
||||
'seo_title': blog_title,
|
||||
'meta_description': f'Learn about {primary_keywords.split(", ")[0] if primary_keywords else "this topic"}.',
|
||||
@@ -246,8 +248,8 @@ class BlogSEOMetadataGenerator:
|
||||
|
||||
# Get structured response from Gemini
|
||||
ai_response = self.gemini_provider(
|
||||
prompt=prompt,
|
||||
schema=schema,
|
||||
prompt,
|
||||
schema,
|
||||
temperature=0.3,
|
||||
max_tokens=2048
|
||||
)
|
||||
|
||||
@@ -348,6 +348,11 @@ def gemini_structured_json_response(prompt, schema, temperature=0.7, top_p=0.9,
|
||||
try:
|
||||
# Get API key with proper error handling
|
||||
api_key = get_gemini_api_key()
|
||||
logger.info(f"🔑 Gemini API key loaded: {bool(api_key)} (length: {len(api_key) if api_key else 0})")
|
||||
|
||||
if not api_key:
|
||||
raise Exception("GEMINI_API_KEY not found in environment variables")
|
||||
|
||||
client = genai.Client(api_key=api_key)
|
||||
logger.info("✅ Gemini client initialized for structured JSON response")
|
||||
|
||||
@@ -383,11 +388,18 @@ def gemini_structured_json_response(prompt, schema, temperature=0.7, top_p=0.9,
|
||||
system_instruction=system_prompt,
|
||||
)
|
||||
|
||||
response = client.models.generate_content(
|
||||
model="gemini-2.5-flash",
|
||||
contents=prompt,
|
||||
config=generation_config,
|
||||
)
|
||||
logger.info("🚀 Making Gemini API call...")
|
||||
try:
|
||||
response = client.models.generate_content(
|
||||
model="gemini-2.5-flash",
|
||||
contents=prompt,
|
||||
config=generation_config,
|
||||
)
|
||||
logger.info("✅ Gemini API call completed successfully")
|
||||
except Exception as api_error:
|
||||
logger.error(f"❌ Gemini API call failed: {api_error}")
|
||||
logger.error(f"❌ API Error type: {type(api_error).__name__}")
|
||||
raise api_error
|
||||
|
||||
# Check for parsed content first (primary method for structured output)
|
||||
if hasattr(response, 'parsed'):
|
||||
|
||||
@@ -485,4 +485,27 @@ class UsageTrackingService:
|
||||
user_id=user_id,
|
||||
provider=provider,
|
||||
tokens_requested=tokens_requested
|
||||
)
|
||||
)
|
||||
|
||||
async def reset_current_billing_period(self, user_id: str) -> Dict[str, Any]:
|
||||
"""Reset usage status for the current billing period (after plan change)."""
|
||||
try:
|
||||
billing_period = datetime.now().strftime("%Y-%m")
|
||||
summary = self.db.query(UsageSummary).filter(
|
||||
UsageSummary.user_id == user_id,
|
||||
UsageSummary.billing_period == billing_period
|
||||
).first()
|
||||
|
||||
if not summary:
|
||||
# Nothing to reset
|
||||
return {"reset": False, "reason": "no_summary"}
|
||||
|
||||
# Clear LIMIT_REACHED so the user can resume; keep counters intact
|
||||
summary.usage_status = UsageStatus.ACTIVE
|
||||
summary.updated_at = datetime.utcnow()
|
||||
self.db.commit()
|
||||
return {"reset": True}
|
||||
except Exception as e:
|
||||
self.db.rollback()
|
||||
logger.error(f"Error resetting usage status: {e}")
|
||||
return {"reset": False, "error": str(e)}
|
||||
Reference in New Issue
Block a user