instagram / app.py
s143a's picture
Upload 2 files
8217fb3 verified
Raw
History Blame Contribute Delete
20.6 kB
# from flask import Flask, request, jsonify
# from flask_cors import CORS
# import requests
# import json
# from datetime import datetime
# from google.oauth2 import service_account
# from googleapiclient.discovery import build
# app = Flask(__name__)
# CORS(app)
# # ========================
# # CONFIGURATION
# # ========================
# import os
# from dotenv import load_dotenv
# load_dotenv()
# GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
# GOOGLE_CREDENTIALS_FILE = os.getenv("GOOGLE_CREDENTIALS_FILE")
# SPREADSHEET_ID = os.getenv("SPREADSHEET_ID")
# # ========================
# # GOOGLE SHEETS
# # ========================
# def get_sheets_service():
# SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
# creds = service_account.Credentials.from_service_account_file(
# GOOGLE_CREDENTIALS_FILE, scopes=SCOPES)
# service = build('sheets', 'v4', credentials=creds)
# return service
# def save_to_sheet(topic, caption, hashtags, reel_script, metadata):
# try:
# service = get_sheets_service()
# sheet = service.spreadsheets()
# timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# values = [[
# timestamp,
# topic,
# metadata.get('duration', 'N/A'),
# metadata.get('level', 'N/A'),
# metadata.get('tone', 'N/A'),
# metadata.get('language', 'N/A'),
# metadata.get('series_info', 'Single'),
# caption,
# hashtags,
# reel_script
# ]]
# body = {'values': values}
# sheet.values().append(
# spreadsheetId=SPREADSHEET_ID,
# range='Sheet1!A:J',
# valueInputOption='RAW',
# body=body
# ).execute()
# return True
# except Exception as e:
# print(f"Sheet Error: {e}")
# return False
# # ========================
# # GEMINI AI
# # ========================
# def call_gemini_api(prompt, retry_count=0, max_retries=3):
# import time
# url = f"https://generativelanguage.googleapis.com/v1/models/gemini-2.5-flash:generateContent?key={GEMINI_API_KEY}"
# headers = {"Content-Type": "application/json"}
# data = {
# "contents": [{
# "parts": [{"text": prompt}]
# }]
# }
# # Progressive delay: 3s, 10s, 30s
# delays = [3, 10, 30]
# if retry_count > 0:
# wait_time = delays[min(retry_count - 1, 2)]
# print(f"⏳ Rate limit hit. Waiting {wait_time}s before retry {retry_count}/{max_retries}...")
# time.sleep(wait_time)
# else:
# time.sleep(3) # Base delay between requests
# response = requests.post(url, headers=headers, json=data)
# if response.status_code == 200:
# result = response.json()
# return result['candidates'][0]['content']['parts'][0]['text'].strip()
# elif response.status_code == 429:
# if retry_count < max_retries:
# return call_gemini_api(prompt, retry_count + 1, max_retries)
# else:
# raise Exception("Rate limit exceeded after retries. Please wait 1-2 minutes and try again!")
# else:
# raise Exception(f"API Error: {response.status_code}")
# def generate_instagram_content(topic, duration, level, tone, language, series_config):
# import time
# # Tone descriptions
# tone_styles = {
# 'professional': 'professional and corporate tone',
# 'funny': 'humorous, witty, and entertaining tone with jokes',
# 'inspiring': 'motivational, uplifting, and inspiring tone',
# 'serious': 'serious, educational, and informative tone',
# 'casual': 'casual, friendly, and conversational tone',
# 'storytelling': 'narrative storytelling style with engaging flow'
# }
# # Language instructions
# language_styles = {
# 'hinglish': 'Mix of Hindi and English (Hinglish). Use both languages naturally',
# 'hindi': 'Pure Hindi language only. No English words',
# 'english': 'Pure English language only. No Hindi words'
# }
# # Content level descriptions
# level_descriptions = {
# 'basic': 'simple, easy-to-understand for beginners',
# 'intermediate': 'moderate depth with some technical terms',
# 'advanced': 'in-depth, expert-level with advanced concepts'
# }
# tone_desc = tone_styles.get(tone, 'inspiring tone')
# lang_desc = language_styles.get(language, 'Hinglish')
# level_desc = level_descriptions.get(level, 'intermediate')
# # Calculate scenes
# scenes = calculate_scenes(duration)
# # Series context
# series_context = ""
# if series_config['enabled']:
# current = series_config['currentPart']
# total = series_config['totalParts']
# previous = series_config.get('previousContent', '')
# if current == 1:
# series_context = f"\n\nSERIES INFO: This is PART 1/{total} of a series. End with a hook/cliffhanger for next part!"
# elif current == total:
# series_context = f"\n\nSERIES INFO: FINAL PART {current}/{total}. Provide conclusion referencing previous parts.\nPrevious: {previous[:400]}"
# else:
# series_context = f"\n\nSERIES INFO: PART {current}/{total}. Continue from previous part.\nPrevious: {previous[:400]}"
# # CAPTION
# caption_prompt = f"""Create Instagram caption for: {topic}
# REQUIREMENTS:
# - Tone: {tone_desc}
# - Language: {lang_desc}
# - Level: {level_desc}
# - 2-3 lines, engaging
# - Use emojis
# - Call-to-action
# {f'- Mention Part {series_config["currentPart"]}/{series_config["totalParts"]}' if series_config['enabled'] else ''}
# ONLY return caption, nothing else."""
# print(f"Generating caption: {topic}")
# caption = call_gemini_api(caption_prompt)
# # HASHTAGS
# hashtags_prompt = f"""Generate 12-15 Instagram hashtags for: {topic}
# Style: {tone}
# Language: {language}
# Level: {level}
# Return ONLY hashtags with # in one line."""
# print("Generating hashtags...")
# hashtags = call_gemini_api(hashtags_prompt)
# # REEL SCRIPT
# reel_prompt = f"""Create {duration}-second Instagram Reel script for: {topic}
# STYLE:
# - Tone: {tone_desc}
# - Language: {lang_desc}
# - Level: {level_desc}
# STRUCTURE ({scenes['total_duration']} seconds total):
# [Hook] - Opening (2-3s)
# {chr(10).join([f'[Scene {i+1}] - Description ({scenes["scene_duration"]}s)' for i in range(scenes["num_scenes"])])}
# [CTA] - Call to action (3-5s)
# {series_context}
# FORMAT EXACTLY as shown above. Make it viral!"""
# print("Generating reel script...")
# reel_script = call_gemini_api(reel_prompt)
# return caption, hashtags, reel_script
# def calculate_scenes(duration):
# available_time = duration - 8
# if duration <= 20:
# num_scenes = 2
# elif duration <= 45:
# num_scenes = 3
# elif duration <= 75:
# num_scenes = 4
# elif duration <= 120:
# num_scenes = 5
# else:
# num_scenes = 6
# scene_duration = available_time // num_scenes
# return {
# 'num_scenes': num_scenes,
# 'scene_duration': scene_duration,
# 'total_duration': duration
# }
# # ========================
# # API ROUTES
# # ========================
# @app.route('/')
# def home():
# return """
# 🎨 Instagram AI Content Generator ULTIMATE
# ⚡ Powered by Sai Tech
# Features:
# - Bulk content generation
# - Custom tone, language, level
# - Multi-part series
# - PDF/ZIP export
# Status: Running ✅
# """
# @app.route('/generate', methods=['POST'])
# def generate():
# try:
# data = request.json
# topic = data.get('topic', '').strip()
# duration = data.get('duration', 30)
# level = data.get('level', 'intermediate')
# tone = data.get('tone', 'inspiring')
# language = data.get('language', 'hinglish')
# series_config = data.get('series', {'enabled': False})
# if not topic:
# return jsonify({
# 'success': False,
# 'error': 'Topic required!'
# }), 400
# print(f"\n{'='*60}")
# print(f"⚡ SAI TECH - Processing Request")
# print(f"{'='*60}")
# print(f" Topic: {topic}")
# print(f" Duration: {duration}s")
# print(f" Level: {level}")
# print(f" Tone: {tone}")
# print(f" Language: {language}")
# if series_config['enabled']:
# print(f" Series: Part {series_config['currentPart']}/{series_config['totalParts']}")
# print(f"{'='*60}\n")
# # Generate content
# caption, hashtags, reel_script = generate_instagram_content(
# topic, duration, level, tone, language, series_config
# )
# # Metadata
# metadata = {
# 'duration': f"{duration}s",
# 'level': level,
# 'tone': tone,
# 'language': language,
# 'series_info': f"Part {series_config['currentPart']}/{series_config['totalParts']}" if series_config['enabled'] else "Single"
# }
# # Save to sheets
# save_to_sheet(topic, caption, hashtags, reel_script, metadata)
# print("✅ Content generated successfully!\n")
# return jsonify({
# 'success': True,
# 'topic': topic,
# 'caption': caption,
# 'hashtags': hashtags,
# 'reel_script': reel_script,
# 'metadata': metadata
# })
# except Exception as e:
# print(f"\n❌ Error: {str(e)}\n")
# return jsonify({
# 'success': False,
# 'error': str(e)
# }), 500
# if __name__ == '__main__':
# print("=" * 70)
# print("⚡ SAI TECH - Instagram AI Content Generator ULTIMATE")
# print("=" * 70)
# print("📍 Server: http://localhost:5000")
# print("🌐 Open index.html in browser")
# print("=" * 70)
# print("\n🔥 ULTIMATE Features:")
# print(" ✅ Bulk topic generation")
# print(" ✅ Custom tone (Professional/Funny/Inspiring/etc)")
# print(" ✅ Language selection (Hindi/English/Hinglish)")
# print(" ✅ Content levels (Basic/Intermediate/Advanced)")
# print(" ✅ Multi-part series with auto-continuation")
# print(" ✅ PDF/ZIP download with Sai Tech watermark")
# print(" ✅ Auto Google Sheets backup")
# print("=" * 70)
# print("\n💡 Example Bulk Topics:")
# print(" motivation, fitness, cooking, travel, photography")
# print("=" * 70)
# app.run(debug=True, port=5000)
# from flask import Flask, request, jsonify
# from flask_cors import CORS
# import requests
# import json
# import time
# import os
# from datetime import datetime
# from dotenv import load_dotenv
# from google.oauth2 import service_account
# from googleapiclient.discovery import build
# app = Flask(__name__)
# CORS(app)
# load_dotenv()
# GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
# GOOGLE_CREDENTIALS_FILE = os.getenv("GOOGLE_CREDENTIALS_FILE")
# SPREADSHEET_ID = os.getenv("SPREADSHEET_ID")
# CACHE = {}
# LAST_CALL_TIME = 0
# MIN_INTERVAL = 2
# def get_sheets_service():
# SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
# creds = service_account.Credentials.from_service_account_file(
# GOOGLE_CREDENTIALS_FILE, scopes=SCOPES
# )
# return build('sheets', 'v4', credentials=creds)
# def save_to_sheet(topic, caption, hashtags, reel_script, metadata):
# try:
# service = get_sheets_service()
# sheet = service.spreadsheets()
# timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# values = [[
# timestamp, topic,
# metadata.get("duration"),
# metadata.get("level"),
# metadata.get("tone"),
# metadata.get("language"),
# metadata.get("series_info"),
# caption, hashtags, reel_script
# ]]
# sheet.values().append(
# spreadsheetId=SPREADSHEET_ID,
# range="Sheet1!A:J",
# valueInputOption="RAW",
# body={"values": values}
# ).execute()
# return True
# except Exception as e:
# print("Sheet Error:", e)
# return False
# def call_gemini_api(prompt, retry=0):
# global LAST_CALL_TIME
# if prompt in CACHE:
# return CACHE[prompt]
# now = time.time()
# wait = MIN_INTERVAL - (now - LAST_CALL_TIME)
# if wait > 0:
# time.sleep(wait)
# url = f"https://generativelanguage.googleapis.com/v1/models/gemini-2.5-flash:generateContent?key={GEMINI_API_KEY}"
# headers = {"Content-Type": "application/json"}
# data = {"contents": [{"parts": [{"text": prompt}]}]}
# response = requests.post(url, headers=headers, json=data)
# LAST_CALL_TIME = time.time()
# if response.status_code == 200:
# text = response.json()["candidates"][0]["content"]["parts"][0]["text"].strip()
# CACHE[prompt] = text
# return text
# if response.status_code == 429 and retry < 3:
# time.sleep(5 * (retry + 1))
# return call_gemini_api(prompt, retry + 1)
# raise Exception(f"Gemini API Error: {response.status_code}")
# def generate_instagram_content(topic, duration, level, tone, language, series):
# series_context = ""
# if series.get("enabled"):
# current = series.get("currentPart", 1)
# total = series.get("totalParts", 1)
# prev = series.get("previousContent", "")[:300]
# if current == 1:
# series_context = f"PART 1/{total}. End with hook."
# elif current == total:
# series_context = f"FINAL PART {current}/{total}. Previous: {prev}"
# else:
# series_context = f"PART {current}/{total}. Continue. Previous: {prev}"
# prompt = f'''
# Create Instagram content for topic: {topic}
# Return ONLY valid JSON:
# {{
# "caption": "...",
# "hashtags": "...",
# "reel_script": "..."
# }}
# Tone: {tone}
# Language: {language}
# Level: {level}
# Duration: {duration}s
# {series_context}
# '''
# response = call_gemini_api(prompt)
# try:
# data = json.loads(response)
# return data["caption"], data["hashtags"], data["reel_script"]
# except Exception:
# raise Exception("Invalid JSON from AI")
# @app.route("/")
# def home():
# return "Sai Tech AI Generator Running 🚀"
# @app.route("/generate", methods=["POST"])
# def generate():
# try:
# data = request.json
# topic = data.get("topic", "").strip()
# duration = data.get("duration", 30)
# level = data.get("level", "intermediate")
# tone = data.get("tone", "inspiring")
# language = data.get("language", "hinglish")
# series = data.get("series", {"enabled": False})
# if not topic:
# return jsonify({"success": False, "error": "Topic required"}), 400
# caption, hashtags, reel_script = generate_instagram_content(
# topic, duration, level, tone, language, series
# )
# metadata = {
# "duration": f"{duration}s",
# "level": level,
# "tone": tone,
# "language": language,
# "series_info": f"Part {series.get('currentPart',1)}/{series.get('totalParts',1)}"
# }
# save_to_sheet(topic, caption, hashtags, reel_script, metadata)
# return jsonify({
# "success": True,
# "caption": caption,
# "hashtags": hashtags,
# "reel_script": reel_script
# })
# except Exception as e:
# return jsonify({"success": False, "error": str(e)}), 500
# if __name__ == "__main__":
# app.run(debug=True, port=5000)
import os
import time
import requests
import gradio as gr
from datetime import datetime
from google.oauth2 import service_account
from googleapiclient.discovery import build
# ========================
# ENV VARIABLES
# ========================
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
GOOGLE_CREDENTIALS_FILE = os.getenv("GOOGLE_CREDENTIALS_FILE")
SPREADSHEET_ID = os.getenv("SPREADSHEET_ID")
# ========================
# GOOGLE SHEETS
# ========================
def get_sheets_service():
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
creds = service_account.Credentials.from_service_account_file(
GOOGLE_CREDENTIALS_FILE, scopes=SCOPES)
return build('sheets', 'v4', credentials=creds)
def save_to_sheet(topic, caption, hashtags, reel_script, metadata):
try:
service = get_sheets_service()
sheet = service.spreadsheets()
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
values = [[
timestamp,
topic,
metadata.get('duration'),
metadata.get('level'),
metadata.get('tone'),
metadata.get('language'),
metadata.get('series_info'),
caption,
hashtags,
reel_script
]]
sheet.values().append(
spreadsheetId=SPREADSHEET_ID,
range='Sheet1!A:J',
valueInputOption='RAW',
body={'values': values}
).execute()
except Exception as e:
print("Sheet Error:", e)
# ========================
# GEMINI CALL
# ========================
def call_gemini(prompt):
url = f"https://generativelanguage.googleapis.com/v1/models/gemini-2.5-flash:generateContent?key={GEMINI_API_KEY}"
data = {
"contents": [{"parts": [{"text": prompt}]}]
}
time.sleep(2)
res = requests.post(url, json=data)
if res.status_code != 200:
raise Exception(f"Gemini Error: {res.status_code}")
return res.json()['candidates'][0]['content']['parts'][0]['text'].strip()
# ========================
# MAIN GENERATOR
# ========================
def generate_content(topic, duration, level, tone, language):
caption = call_gemini(f"Write short Instagram caption about {topic} in {language} with {tone} tone.")
hashtags = call_gemini(f"Give 15 hashtags for {topic}.")
reel = call_gemini(f"Write {duration} sec Instagram reel script about {topic}.")
metadata = {
"duration": f"{duration}s",
"level": level,
"tone": tone,
"language": language,
"series_info": "Single"
}
save_to_sheet(topic, caption, hashtags, reel, metadata)
return caption, hashtags, reel
# ========================
# GRADIO UI
# ========================
with gr.Blocks(title="Instagram AI Generator") as app:
gr.Markdown("# 🚀 Instagram AI Content Generator")
gr.Markdown("Generate captions, hashtags & reel scripts using AI")
topic = gr.Textbox(label="Topic")
duration = gr.Slider(10, 120, value=30, step=5, label="Reel Duration (sec)")
level = gr.Dropdown(["basic", "intermediate", "advanced"], value="intermediate", label="Level")
tone = gr.Dropdown(["professional", "funny", "inspiring", "casual"], value="inspiring", label="Tone")
language = gr.Dropdown(["english", "hindi", "hinglish"], value="hinglish", label="Language")
btn = gr.Button("Generate")
caption_out = gr.Textbox(label="Caption")
hashtag_out = gr.Textbox(label="Hashtags")
reel_out = gr.Textbox(label="Reel Script", lines=8)
btn.click(
generate_content,
inputs=[topic, duration, level, tone, language],
outputs=[caption_out, hashtag_out, reel_out]
)
app.launch()