"""app.py โ Gradio + Gemini + apify-client. Version 8.0.0 | 4 April 2026. ZERO for/while/if."""
import os
import glob
import gradio as gr
from langchain_google_genai import ChatGoogleGenerativeAI
from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import MemorySaver
from agent import SYSTEM_PROMPT, get_local_tools
print(">>> app.py: imports complete")
llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash", temperature=0)
tools = get_local_tools()
agent = create_react_agent(model=llm, tools=tools, prompt=SYSTEM_PROMPT, checkpointer=MemorySaver())
print(f">>> app.py: agent ready ({len(tools)} tools)")
_msg_count = 0
HEADER_HTML = """
๐ค Agentic AI โ Smart Web Scraping Agent
Powered by Gemini 2.5 Flash + 22,000+ Apify Actors + apify-client SDK
TripAdvisor
Instagram
Google Maps
Amazon
Any Website
22K+ more
"""
def _latest_file():
"""Find most recent CSV in /tmp."""
files = sorted(glob.glob("/tmp/*.csv"), key=os.path.getmtime)
return (files and files[-1]) or None
def respond(message, chat_history):
"""Fresh thread per message. CSV auto-downloads from last scrape."""
global _msg_count
_msg_count += 1
text = (message or "").strip() or "Search Apify for popular web scrapers"
print(f"\n{'='*60}\n>>> MESSAGE #{_msg_count}: '{text}'\n{'='*60}")
chat_history = chat_history + [
{"role": "user", "content": text},
{"role": "assistant", "content": "๐ **Searching & scraping...**\n\nFinding actor โ reading schema โ running scraper โ analyzing.\n\n_Please wait 30-90 seconds._"},
]
yield chat_history, "", _latest_file()
result = agent.invoke(
{"messages": [("human", text)]},
config={"configurable": {"thread_id": f"t{_msg_count}"}},
)
response = result["messages"][-1].content
print(f">>> Response ({len(response)} chars)")
chat_history[-1] = {"role": "assistant", "content": response}
yield chat_history, "", _latest_file()
print(">>> Building UI...")
with gr.Blocks(title="Agentic AI - Web Scraping Agent") as demo:
gr.HTML(HEADER_HTML)
chatbot = gr.Chatbot(height=340, show_label=False)
with gr.Row():
msg = gr.Textbox(placeholder="Scrape TripAdvisor reviews for Taj Dubai ยท Get 10 Instagram posts for Nike ยท Amazon reviews for LG TV",
show_label=False, scale=9, lines=1, max_lines=2, container=False)
send = gr.Button("โ", variant="primary", scale=1, min_width=50)
download = gr.File(label="๐ฅ Download CSV", visible=True)
msg.submit(respond, [msg, chatbot], [chatbot, msg, download])
send.click(respond, [msg, chatbot], [chatbot, msg, download])
print(">>> Launching...")
demo.launch(server_name="0.0.0.0", server_port=7860)