Adedoyinjames's picture
Update app.py
08dc6f3 verified
import os
import requests
import random
import threading
import time
import schedule
import tweepy
import gradio as gr
# Secrets from HF Space environment
HF_TOKEN = os.environ['HF_TOKEN']
CONSUMER_KEY = os.environ['CONSUMER_KEY']
CONSUMER_SECRET = os.environ['CONSUMER_SECRET']
ACCESS_TOKEN = os.environ['ACCESS_TOKEN']
ACCESS_SECRET = os.environ['ACCESS_SECRET']
# LLM API setup
API_URL = "https://router.huggingface.co/v1/chat/completions"
headers = {
"Authorization": f"Bearer {HF_TOKEN}",
}
def query(payload):
response = requests.post(API_URL, headers=headers, json=payload)
return response.json()
# Topics for posts
topics = [
"GeoAI as a field and it's application",
"application of Geology with Tech for exploration",
"application of AI in geological exploration",
"Entrepreneurship"
]
# Function to generate a high-quality post using LLM
def generate_post(topic=None):
if topic is None or topic == "Random":
topic = random.choice(topics)
prompt = f"Generate a high-quality, educational, and informative X (Twitter) post under 280 characters showcasing expertise in {topic}. Make it engaging, insightful, and professional. Include relevant hashtags and hashtags shouldn't be more than 2 or not even at all in some post also avoid using - in the post so it looks natural."
response = query({
"messages": [{"role": "user", "content": prompt}],
"model": "deepseek-ai/DeepSeek-V3.2:novita",
"max_tokens": 200,
"temperature": 0.8
})
post_content = response["choices"][0]["message"]["content"].strip()
if len(post_content) > 280:
post_content = post_content[:277] + "..."
return post_content
# Tweepy v2 Client setup
client = tweepy.Client(
consumer_key=CONSUMER_KEY,
consumer_secret=CONSUMER_SECRET,
access_token=ACCESS_TOKEN,
access_token_secret=ACCESS_SECRET
)
# Global queue and scheduler state
post_queue = []
scheduler_running = False
scheduler_thread = None
# Function to post to X
def post_to_x(content):
try:
response = client.create_tweet(text=content)
tweet_id = response.data['id']
return f"Posted! https://x.com/user/status/{tweet_id}"
except Exception as e:
return f"Error: {str(e)}"
# Scheduler job β€” posts one item from queue
def scheduled_post_job():
global post_queue
if post_queue:
content = post_queue.pop(0) # FIFO: first in, first out
result = post_to_x(content)
print(f"[Scheduler] {result}\nContent: {content}")
return result, "\n\n".join(post_queue) if post_queue else "Queue is empty."
else:
print("[Scheduler] Queue is empty.")
return "No post scheduled β€” queue is empty.", "Queue is empty."
# Background scheduler loop
def run_scheduler():
global scheduler_running
schedule.every(2).hours.do(scheduled_post_job)
while scheduler_running:
schedule.run_pending()
time.sleep(30)
# Start scheduler
def start_scheduler():
global scheduler_running, scheduler_thread
if not scheduler_running:
scheduler_running = True
scheduler_thread = threading.Thread(target=run_scheduler, daemon=True)
scheduler_thread.start()
return "Scheduler started! Posts every 2 hours from the queue."
return "Scheduler is already running."
# Stop scheduler
def stop_scheduler():
global scheduler_running
scheduler_running = False
return "Scheduler stopped."
# Clear queue function
def clear_queue():
global post_queue
post_queue.clear()
return "Queue cleared.", "Queue is empty."
# Gradio functions
def generate_new_post(topic):
content = generate_post(topic)
return content, gr.update(visible=True)
def add_to_queue(content):
global post_queue
stripped = content.strip()
if stripped and stripped not in post_queue:
post_queue.append(stripped)
return (
"", # Clear the current post box
gr.update(visible=False), # Hide Add button
"\n\n".join(post_queue) if post_queue else "Queue is empty."
)
# Gradio Interface
with gr.Blocks(title="X Post Generator & Scheduler") as demo:
gr.Markdown("# AI/Tech/Startups X Post Generator & Queue Scheduler")
gr.Markdown("Generate β†’ Review β†’ Add to queue β†’ Start scheduler for automated 2-hour posting.")
with gr.Row():
topic_input = gr.Dropdown(choices=["Random"] + topics, value="Random", label="Topic")
generate_btn = gr.Button("Generate New Post")
current_post = gr.Textbox(label="Generated Post (Review before adding)", lines=6, interactive=False)
add_btn = gr.Button("βž• Add to Queue", visible=False)
queue_display = gr.Textbox(
label="Post Queue (will be posted in order, every 2 hours)",
value="Queue is empty.",
lines=12,
interactive=False
)
with gr.Row():
start_btn = gr.Button("Start Scheduler")
stop_btn = gr.Button("Stop Scheduler")
clear_queue_btn = gr.Button("Clear Queue")
status_box = gr.Textbox(label="Status", value="Ready", interactive=False)
# Event bindings
generate_btn.click(
generate_new_post,
inputs=topic_input,
outputs=[current_post, add_btn]
)
add_btn.click(
add_to_queue,
inputs=current_post,
outputs=[current_post, add_btn, queue_display]
)
start_btn.click(
start_scheduler,
outputs=status_box
)
stop_btn.click(
stop_scheduler,
outputs=status_box
)
clear_queue_btn.click(
clear_queue,
outputs=[status_box, queue_display]
)
demo.launch()