Spaces:
Sleeping
Sleeping
| import os | |
| import logging | |
| import sqlite3 | |
| from datetime import datetime | |
| import gradio as gr | |
| from openai import OpenAI | |
| # تنظیم logging | |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | |
| logger = logging.getLogger(__name__) | |
| # تنظیم API Key | |
| logger.info("Starting application setup") | |
| # فقط از environment variable استفاده کن | |
| openrouter_api_key = os.getenv("OPENROUTER_API_KEY") | |
| if not openrouter_api_key: | |
| # اگر environment variable وجود نداشت، از hardcoded استفاده کن | |
| openrouter_api_key = "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" | |
| logger.info("⚠️ Using hardcoded API key") | |
| else: | |
| logger.info("✅ API key loaded from environment variable") | |
| # تنظیم کلاینت OpenAI برای OpenRouter | |
| try: | |
| client = OpenAI( | |
| base_url="https://openrouter.ai/api/v1", | |
| api_key=openrouter_api_key | |
| ) | |
| # تست API Key | |
| test_response = client.chat.completions.create( | |
| model="openai/gpt-oss-20b:free", | |
| messages=[{"role": "user", "content": "test"}], | |
| max_tokens=10, | |
| extra_headers={ | |
| "HTTP-Referer": "https://huggingface.co/spaces", | |
| "X-Title": "Christopher Streamlit App" | |
| } | |
| ) | |
| logger.info("✅ Initialized OpenAI client and API key validated") | |
| except Exception as e: | |
| logger.error(f"❌ Failed to initialize OpenAI client or validate API key: {e}") | |
| raise | |
| # ایجاد دیتابیس | |
| def init_db(): | |
| logger.info("🗄️ Initializing database") | |
| try: | |
| with sqlite3.connect("chris.db") as conn: | |
| cursor = conn.cursor() | |
| cursor.execute('''CREATE TABLE IF NOT EXISTS code_history ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| user_input TEXT NOT NULL, | |
| language TEXT NOT NULL, | |
| generated_code TEXT NOT NULL, | |
| prompt_used TEXT, | |
| timestamp TEXT NOT NULL, | |
| success BOOLEAN DEFAULT 1 | |
| )''') | |
| conn.commit() | |
| logger.info("✅ Database initialized successfully") | |
| except Exception as e: | |
| logger.error(f"❌ Database initialization error: {e}") | |
| raise | |
| # ذخیره در دیتابیس | |
| def save_to_memory(user_input, language, prompt, generated_code, success=True): | |
| logger.info("Saving to database") | |
| try: | |
| with sqlite3.connect("chris.db") as conn: | |
| cursor = conn.cursor() | |
| cursor.execute('''INSERT INTO code_history (user_input, language, generated_code, prompt_used, timestamp, success) | |
| VALUES (?, ?, ?, ?, ?, ?)''', | |
| (user_input, language, generated_code, prompt, datetime.now().isoformat(), success)) | |
| conn.commit() | |
| logger.info("✅ Saved to database") | |
| except Exception as e: | |
| logger.error(f"❌ Database save error: {e}") | |
| # دریافت تاریخچه | |
| def get_history(): | |
| logger.info("Retrieving history from database") | |
| try: | |
| with sqlite3.connect("chris.db") as conn: | |
| cursor = conn.cursor() | |
| cursor.execute("SELECT id, user_input, language, generated_code, prompt_used, timestamp, success FROM code_history ORDER BY timestamp DESC LIMIT 10") | |
| rows = cursor.fetchall() | |
| if not rows: | |
| return "هیچ تاریخچهای موجود نیست." | |
| history_text = "=== آخرین 10 درخواست ===\n\n" | |
| for row in rows: | |
| history_text += f"🆔 شناسه: {row[0]}\n" | |
| history_text += f"📝 درخواست: {row[1]}\n" | |
| history_text += f"💻 زبان: {row[2]}\n" | |
| history_text += f"⏰ زمان: {row[5]}\n" | |
| history_text += f"✅ وضعیت: {'موفق' if row[6] else 'ناموفق'}\n" | |
| history_text += f"📋 کد:\n```{row[2].lower()}\n{row[3][:200]}{'...' if len(row[3]) > 200 else ''}\n```\n" | |
| history_text += "-" * 80 + "\n\n" | |
| return history_text | |
| except Exception as e: | |
| logger.error(f"❌ History retrieval error: {e}") | |
| return f"خطا در دریافت تاریخچه: {e}" | |
| # تولید کد | |
| def generate_code(user_input, language): | |
| logger.info(f"Processing input: {user_input}, language: {language}") | |
| try: | |
| # پرامپت مستقیماً ورودی کاربر با زبان | |
| prompt = f"{user_input} in {language}" | |
| logger.info(f"Generated prompt: {prompt}") | |
| response = client.chat.completions.create( | |
| model="openai/gpt-oss-20b:free", | |
| messages=[ | |
| {"role": "system", "content": f"You are a coding assistant that generates complete and well-explained code in {language}. Always provide clean, working code with comments in Persian when needed."}, | |
| {"role": "user", "content": prompt} | |
| ], | |
| max_tokens=2048, | |
| temperature=0.7, | |
| top_p=0.8, | |
| extra_headers={ | |
| "HTTP-Referer": "https://huggingface.co/spaces", | |
| "X-Title": "Christopher Gradio App" | |
| }, | |
| extra_body={} | |
| ) | |
| code_output = response.choices[0].message.content.strip() | |
| # استخراج کد از خروجی (در صورت وجود بلاک کد) | |
| lines = code_output.split('\n') | |
| code = [] | |
| is_code = False | |
| for line in lines: | |
| if line.startswith("```"): | |
| is_code = not is_code | |
| continue | |
| elif is_code: | |
| code.append(line) | |
| final_code = "\n".join(code).strip() if code else code_output | |
| if not final_code: | |
| logger.warning("Generated code is empty") | |
| final_code = "خطا: کد تولیدشده خالی است" | |
| save_to_memory(user_input, language, prompt, final_code, success=False) | |
| return final_code | |
| logger.info(f"Generated code: {final_code}") | |
| save_to_memory(user_input, language, prompt, final_code) | |
| return final_code | |
| except Exception as e: | |
| logger.error(f"❌ Code generation error: {e}") | |
| error_msg = f"خطا در تولید کد: {e}" | |
| save_to_memory(user_input, language, prompt, error_msg, success=False) | |
| return error_msg | |
| # تابع اصلی برای Gradio | |
| def christopher_interface(user_input, language, show_history): | |
| logger.info(f"Processing input: {user_input}, language: {language}, show_history: {show_history}") | |
| if not user_input.strip(): | |
| return "❌ لطفاً توضیح برنامه را وارد کنید.", "" | |
| try: | |
| # تولید کد | |
| generated_code = generate_code(user_input, language) | |
| # دریافت تاریخچه در صورت درخواست | |
| history = "" | |
| if show_history: | |
| history = get_history() | |
| return generated_code, history | |
| except Exception as e: | |
| logger.error(f"❌ Processing error: {e}") | |
| error_msg = f"خطا: {e}" | |
| history = get_history() if show_history else "" | |
| return error_msg, history | |
| # پاک کردن تاریخچه | |
| def clear_history(): | |
| try: | |
| with sqlite3.connect("chris.db") as conn: | |
| cursor = conn.cursor() | |
| cursor.execute("DELETE FROM code_history") | |
| conn.commit() | |
| logger.info("✅ History cleared") | |
| return "تاریخچه با موفقیت پاک شد." | |
| except Exception as e: | |
| logger.error(f"❌ Clear history error: {e}") | |
| return f"خطا در پاک کردن تاریخچه: {e}" | |
| # ایجاد رابط کاربری Gradio | |
| def create_interface(): | |
| # تم سفارشی | |
| theme = gr.themes.Soft( | |
| primary_hue="blue", | |
| secondary_hue="gray", | |
| neutral_hue="slate", | |
| ) | |
| with gr.Blocks( | |
| theme=theme, | |
| title="کریستوفر - دستیار کدنویسی", | |
| css=""" | |
| .main-header { | |
| text-align: center; | |
| background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); | |
| color: white; | |
| padding: 20px; | |
| border-radius: 10px; | |
| margin-bottom: 20px; | |
| } | |
| .code-output { | |
| direction: ltr; | |
| text-align: left; | |
| } | |
| """ | |
| ) as interface: | |
| # هدر | |
| gr.HTML(""" | |
| <div class="main-header"> | |
| <h1>🤖 کریستوفر - دستیار کدنویسی</h1> | |
| <p>با هوش مصنوعی کد خود را تولید کنید</p> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| # ورودیها | |
| user_input = gr.Textbox( | |
| label="📝 توضیح برنامه به فارسی", | |
| placeholder="مثال: یک برنامه برای محاسبه فاکتوریل عدد بنویس", | |
| lines=3, | |
| rtl=True | |
| ) | |
| with gr.Row(): | |
| language = gr.Dropdown( | |
| choices=["Python", "JavaScript", "Java", "C++", "C#", "Go", "Rust", "PHP"], | |
| value="Python", | |
| label="💻 زبان برنامهنویسی", | |
| interactive=True | |
| ) | |
| show_history = gr.Checkbox( | |
| label="📋 نمایش تاریخچه", | |
| value=False | |
| ) | |
| with gr.Row(): | |
| generate_btn = gr.Button("🚀 تولید کد", variant="primary", size="lg") | |
| clear_btn = gr.Button("🗑️ پاک کردن تاریخچه", variant="secondary") | |
| with gr.Column(scale=3): | |
| # خروجیها | |
| generated_code = gr.Code( | |
| label="💡 کد تولیدشده", | |
| language="python", | |
| lines=20, | |
| elem_classes=["code-output"] | |
| ) | |
| # تاریخچه | |
| with gr.Row(): | |
| history_output = gr.Textbox( | |
| label="📚 تاریخچه درخواستها", | |
| lines=10, | |
| max_lines=15, | |
| visible=False, | |
| rtl=True | |
| ) | |
| # رویدادها | |
| def update_code_language(lang): | |
| return gr.Code(language=lang.lower() if lang.lower() in ["python", "javascript", "java", "cpp", "go", "rust", "php"] else "text") | |
| def handle_generate(user_input, language, show_history): | |
| code, history = christopher_interface(user_input, language, show_history) | |
| return ( | |
| code, | |
| gr.Textbox(value=history, visible=bool(history.strip())), | |
| gr.Code(language=language.lower() if language.lower() in ["python", "javascript", "java", "cpp", "go", "rust", "php"] else "text") | |
| ) | |
| def handle_clear(): | |
| result = clear_history() | |
| return gr.Textbox(value="", visible=False), result | |
| # اتصال رویدادها | |
| language.change( | |
| fn=update_code_language, | |
| inputs=[language], | |
| outputs=[generated_code] | |
| ) | |
| generate_btn.click( | |
| fn=handle_generate, | |
| inputs=[user_input, language, show_history], | |
| outputs=[generated_code, history_output, generated_code] | |
| ) | |
| clear_btn.click( | |
| fn=handle_clear, | |
| outputs=[history_output, gr.Textbox(visible=False)] | |
| ).then( | |
| fn=lambda: "تاریخچه پاک شد", | |
| outputs=gr.Textbox(visible=True) | |
| ) | |
| # نمونهها | |
| gr.Examples( | |
| examples=[ | |
| ["یک برنامه برای محاسبه فاکتوریل عدد بنویس", "Python", False], | |
| ["یک تابع برای مرتب کردن آرایه بنویس", "JavaScript", False], | |
| ["یک کلاس برای مدیریت لیست دانشجو بنویس", "Java", False], | |
| ["یک برنامه برای پیدا کردن اعداد اول بنویس", "C++", False], | |
| ], | |
| inputs=[user_input, language, show_history], | |
| ) | |
| # راهنما | |
| gr.HTML(""" | |
| <div style="margin-top: 20px; padding: 15px; background-color: #808080; border-radius: 10px; border-left: 4px solid #007bff;"> | |
| <h3>🔍 راهنمای استفاده:</h3> | |
| <ul style="text-align: right; direction: rtl;"> | |
| <li>توضیح دقیق و واضح از برنامه مورد نظر خود ارائه دهید</li> | |
| <li>زبان برنامهنویسی مناسب را انتخاب کنید</li> | |
| <li>برای مشاهده درخواستهای قبلی، گزینه "نمایش تاریخچه" را فعال کنید</li> | |
| <li>کد تولیدشده را کپی کرده و در محیط توسعه خود استفاده کنید</li> | |
| </ul> | |
| </div> | |
| """) | |
| return interface | |
| # راهاندازی برنامه | |
| def main(): | |
| try: | |
| # مقداردهی اولیه دیتابیس | |
| init_db() | |
| logger.info("🚀 Christopher Gradio Interface Started") | |
| # ایجاد و راهاندازی رابط کاربری | |
| interface = create_interface() | |
| # راهاندازی سرور | |
| interface.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=True, | |
| show_error=True | |
| ) | |
| except Exception as e: | |
| logger.error(f"❌ Startup error: {e}") | |
| print(f"❌ خطا در راهاندازی: {e}") | |
| if __name__ == "__main__": | |
| main() |