suprimedev commited on
Commit
ab861fb
·
verified ·
1 Parent(s): 89e01fe

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +402 -356
app.py CHANGED
@@ -7,139 +7,154 @@ import io
7
  import subprocess
8
  import importlib.util
9
  import re
10
- from contextlib import redirect_stdout
 
11
 
12
  # Use OpenRouter API (OpenAI-compatible)
13
- OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
 
14
  client = openai.OpenAI(
15
- api_key=OPENROUTER_API_KEY,
16
- base_url="https://openrouter.ai/api/v1"
17
  )
18
 
19
- MODEL_NAME = "openai/gpt-oss-20b:free"
20
 
21
- def detect_required_packages(code):
22
- """Detect required packages from Python code."""
23
- required_packages = set()
24
-
25
- # Regex patterns for detecting imports
26
- import_patterns = [
27
- r'import\s+(\w+)(?:\.\w+)*',
28
- r'from\s+(\w+)(?:\.\w+)*\s+import',
29
- ]
30
-
31
- # Regex patterns for detecting package installation commands (pip install)
32
- pip_patterns = [
33
- r'pip\s+install\s+([^\s]+)',
34
- r'install\s+([^\s]+)'
35
- ]
36
-
37
- # Check for package installations in the code itself
38
- for pattern in pip_patterns:
39
- matches = re.findall(pattern, code, re.IGNORECASE)
40
- for match in matches:
41
- if match and not match.startswith('"'): # Simple filtering
42
- required_packages.add(match.split('==')[0].split('>')[0].split('<')[0])
43
-
44
- # Check for standard imports that might require packages
45
- lines = code.split('\n')
46
- for line in lines:
47
- line = line.strip()
48
- if line.startswith(('import ', 'from ')):
49
- # Extract module name after import/from
50
- for pattern in import_patterns:
51
- matches = re.findall(pattern, line)
52
- for module in matches:
53
- if module and module != '__future__':
54
- # Map common module names to package names
55
- module_map = {
56
- 'cv2': 'opencv-python',
57
- 'sklearn': 'scikit-learn',
58
- 'tf': 'tensorflow',
59
- 'torch': 'torch',
60
- 'numpy': 'numpy',
61
- 'pandas': 'pandas',
62
- 'pillow': 'Pillow',
63
- 'matplotlib': 'matplotlib',
64
- 'seaborn': 'seaborn',
65
- 'onnxruntime': 'onnxruntime',
66
- 'rembg': 'rembg',
67
- 'requests': 'requests'
68
- }
69
- # Add to required packages (or map to corresponding package)
70
- if module in module_map:
71
- required_packages.add(module_map[module])
72
- else:
73
- # Use module name as package name (some cases work this way)
74
- required_packages.add(module)
75
-
76
- # Remove empty strings and standard library modules
77
- std_libs = {
78
- 'os', 'sys', 'io', 'json', 're', 'time', 'math', 'random', 'collections',
79
- 'itertools', 'functools', 'operator', 'string', 'pathlib', 'tempfile',
80
- 'subprocess', 'logging', 'argparse', 'csv', 'xml', 'html', 'base64',
81
- 'hashlib', 'urllib', 'http', 'threading', 'multiprocessing', 'socket',
82
- 'asyncio', 'concurrent', 'abc', 'enum', 'dataclasses', 'typing'
83
- }
84
-
85
- required_packages = required_packages - std_libs
86
-
87
- return list(required_packages)
88
 
89
- def install_package(package_name):
90
- """Install a package using pip if it's not already installed."""
91
- try:
92
- spec = importlib.util.find_spec(package_name)
93
- if spec is None:
94
- print(f"Installing package: {package_name}")
95
- subprocess.check_call([
96
- sys.executable, "-m", "pip", "install", "--quiet", package_name
97
- ])
98
- print(f"✅ {package_name} installed successfully.")
99
- else:
100
- print(f"✅ {package_name} already installed.")
101
- except Exception as e:
102
- print(f"❌ Failed to install {package_name}: {str(e)}")
103
- raise RuntimeError(f"Installation failed for {package_name}: {str(e)}")
104
-
105
- def install_packages_if_needed(packages):
106
- """Install all required packages."""
107
- if not packages:
108
- print("No packages to install.")
109
- return True
110
-
111
- for package in packages:
112
- if package:
113
- try:
114
- install_package(package)
115
- except Exception as e:
116
- print(f"⚠️ Could not install {package}: {e}")
117
- # Continue with other packages even if one fails
118
-
119
- return True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
- def generate_code_with_openrouter(instruction, file_paths):
122
- """
123
- Generate Python code using OpenRouter API.
124
- """
125
- prompt = f"""
 
 
 
126
  You are a Python expert. The user has provided the instruction: "{instruction}"
127
- And input files: {file_paths} (these paths are available in the current working directory).
128
 
129
  Write a complete, self-contained Python script that:
 
130
  1. Reads the input file(s) from the given paths.
131
  2. Performs the requested operation.
132
  3. Saves the output file(s) to a temporary directory (use tempfile.mkdtemp() for a temp dir).
133
- 4. At the very end of the script, print exactly one line: OUTPUT_FILE_PATH: /full/path/to/output/file.ext
134
  (Replace with the actual full path to the generated output file.)
135
 
136
  Use only safe, standard libraries or pre-installed ones. If you need additional packages outside standard libraries,
137
  comment them clearly at the top for proper installation.
138
 
139
  Avoid network calls and file deletion outside temporary directories. Handle errors gracefully.
140
- Do not define main functions or use __name__ == "__main__".
141
  Keep code structure clean.
142
- Start Code With import. and do not use try: in start.
143
  DO NOT USE MULTILINE STRING OR TRIPLE QUOTES INSIDE CODE.
144
  Do not include any markdown formatting or explanations.
145
 
@@ -148,276 +163,307 @@ import os
148
  import tempfile
149
  import zipfile
150
 
151
- input_path = '{file_paths[0]}'
152
- temp_dir = tempfile.mkdtemp()
153
- output_zip_path = os.path.join(temp_dir, 'output.zip')
154
 
155
  try:
156
- with zipfile.ZipFile(output_zip_path, 'w', compression=zipfile.ZIP_DEFLATED) as zipf:
157
- arcname = os.path.basename(input_path)
158
- zipf.write(input_path, arcname=arcname)
159
  except Exception as e:
160
- print(f"Error creating zip: {{e}}")
161
- exit(1)
162
 
163
- print(f"OUTPUT_FILE_PATH: {{output_zip_path}}")
164
 
165
  Generate ONLY the Python code.
166
  """
167
-
168
- try:
169
- response = client.chat.completions.create(
170
- model=MODEL_NAME,
171
- messages=[
172
- {"role": "system", "content": "You are a helpful Python code generator. Respond only with clean, executable Python code."},
173
- {"role": "user", "content": prompt}
174
- ],
175
- max_tokens=1200,
176
- temperature=0.2,
177
- stop=["```"]
178
- )
179
-
180
- generated_code = response.choices[0].message.content.strip()
181
-
182
- # Clean up markdown code blocks
183
- if generated_code.startswith("```python"):
184
- generated_code = generated_code[10:].strip()
185
- if generated_code.endswith("```"):
186
- generated_code = generated_code[:-3].strip()
187
-
188
- return generated_code
189
-
190
- except Exception as api_error:
191
- raise api_error
192
 
193
- def safe_exec_code(code, globals_dict, locals_dict):
194
- """Safely execute code and return output."""
195
- try:
196
- # First try to compile just to catch syntax errors
197
- compiled_code = compile(code, '<string>', 'exec')
198
-
199
- # Run the code
200
- exec(compiled_code, globals_dict, locals_dict)
201
- return True, None
202
- except Exception as e:
203
- return False, str(e)
204
-
205
- def process_request(instruction, files):
206
- if not files:
207
- return "لطفاً حداقل یک فایل آپلود کنید.", None
208
 
209
- file_paths = [file.name for file in files]
210
 
211
- try:
212
- # Generate code using OpenRouter
213
- generated_code = generate_code_with_openrouter(instruction, file_paths)
214
-
215
- if not generated_code or len(generated_code) < 50:
216
- return f"کد مناسبی تولید نشد. پرامپت: {instruction}\nکد تولید شده:\n{generated_code}", None
217
-
218
- print("--- Generated code ---")
219
- print(repr(generated_code)) # Debugging
220
- print("---------------------")
221
-
222
- # Detect required packages
223
- required_packages = detect_required_packages(generated_code)
224
- print("Detected required packages:", required_packages)
225
-
226
- # Install required packages
227
- if required_packages:
228
- try:
229
- install_packages_if_needed(required_packages)
230
- except Exception as install_err:
231
- print(f"Warning: Package installation issues: {install_err}")
232
-
233
- # Create a safe execution environment
234
- safe_globals = {
235
- '__builtins__': {
236
- 'print': print,
237
- 'open': open,
238
- 'range': range,
239
- 'len': len,
240
- 'str': str,
241
- 'int': int,
242
- 'float': float,
243
- 'list': list,
244
- 'dict': dict,
245
- 'tuple': tuple,
246
- 'set': set,
247
- 'bool': bool,
248
- 'type': type,
249
- 'isinstance': isinstance,
250
- 'hasattr': hasattr,
251
- 'getattr': getattr,
252
- 'setattr': setattr,
253
- 'delattr': delattr,
254
- 'abs': abs,
255
- 'all': all,
256
- 'any': any,
257
- 'bin': bin,
258
- 'chr': chr,
259
- 'complex': complex,
260
- 'divmod': divmod,
261
- 'enumerate': enumerate,
262
- 'format': format,
263
- 'hash': hash,
264
- 'hex': hex,
265
- 'id': id,
266
- 'iter': iter,
267
- 'max': max,
268
- 'min': min,
269
- 'next': next,
270
- 'oct': oct,
271
- 'ord': ord,
272
- 'pow': pow,
273
- 'repr': repr,
274
- 'round': round,
275
- 'slice': slice,
276
- 'sorted': sorted,
277
- 'sum': sum,
278
- 'zip': zip,
279
- '__import__': __import__,
280
- '__name__': '__main__', # Fix for __name__ error
281
- 'exit': sys.exit,
282
- 'True': True,
283
- 'False': False,
284
- 'None': None,
285
- },
286
- '__name__': '__main__', # Explicitly set __name__
287
- 'os': os,
288
- 'tempfile': tempfile,
289
- 'sys': sys,
290
- 'subprocess': subprocess,
291
- 'importlib': importlib,
292
- 're': re,
293
- 'json': __import__('json'),
294
- 'time': __import__('time'),
295
- 'math': __import__('math'),
296
- 'random': __import__('random'),
297
- 'collections': __import__('collections'),
298
- 'itertools': __import__('itertools'),
299
- 'functools': __import__('functools'),
300
- 'operator': __import__('operator'),
301
- 'pathlib': __import__('pathlib'),
302
- 'logging': __import__('logging'),
303
- 'argparse': __import__('argparse'),
304
- 'csv': __import__('csv'),
305
- 'base64': __import__('base64'),
306
- 'hashlib': __import__('hashlib'),
307
- 'urllib': __import__('urllib'),
308
- 'http': __import__('http'),
309
- 'socket': __import__('socket'),
310
- 'threading': __import__('threading'),
311
- 'multiprocessing': __import__('multiprocessing'),
312
- 'asyncio': __import__('asyncio'),
313
- 'concurrent': __import__('concurrent'),
314
- 'abc': __import__('abc'),
315
- 'enum': __import__('enum'),
316
- 'dataclasses': __import__('dataclasses'),
317
- 'typing': __import__('typing'),
318
- 'PIL': __import__('PIL', fromlist=['Image']),
319
- 'zipfile': __import__('zipfile'),
320
- 'requests': __import__('requests') if 'requests' in required_packages else None,
321
- }
322
-
323
- # Clean up globals to remove None entries (prevents AttributeError)
324
- safe_globals_clean = {k: v for k, v in safe_globals.items() if v is not None}
325
-
326
- # Wrap original code in try/except for clean execution
327
- wrapped_code = f"""
328
  try:
329
- {generated_code}
 
 
 
 
 
 
330
  except Exception as e:
331
- print(f"ERROR: {{e}}")
332
- import traceback
333
- traceback.print_exc()
334
- sys.exit(1)
335
- """
336
-
337
- print("--- Wrapped code ---")
338
- print(repr(wrapped_code)) # Debugging
339
- print("---------------------")
340
-
341
- # Validate that wrapped code compiles properly
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342
  try:
343
- compile(wrapped_code, '<wrapped_string>', 'exec')
344
- except SyntaxError as se:
345
- return f"Syntax error in wrapped code: {se}\nWrapped code:\n{wrapped_code}", None
346
-
347
- # Capture output
348
- f = io.StringIO()
349
- output_path = None
350
-
351
- with redirect_stdout(f):
352
- try:
353
- # Execute code safely
354
- exec_result, exec_error = safe_exec_code(wrapped_code, safe_globals_clean, {})
355
-
356
- if not exec_result:
357
- return f"Execution failed: {exec_error}\nCode:\n{wrapped_code}", None
358
-
359
- # Get stdout output
360
- stdout_output = f.getvalue()
361
- print("STDOUT OUTPUT:")
362
- print(stdout_output)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
363
 
364
- # Extract output file path
365
- if "OUTPUT_FILE_PATH:" in stdout_output:
366
- output_path = stdout_output.split("OUTPUT_FILE_PATH:")[-1].strip()
367
- output_path = output_path.split('\n')[0].strip()
368
-
369
- except Exception as exec_error:
370
- error_msg = f"Error during execution: {str(exec_error)}"
371
- import traceback
372
- error_msg += "\n" + traceback.format_exc()
373
- return f"{error_msg}\nCode:\n{wrapped_code}", None
 
 
374
 
375
- # Clean up
376
- if output_path and os.path.exists(output_path):
377
- result_text = f"عملیات با موفقیت انجام شد!\nکد تولید شده توسط OpenRouter:\n{wrapped_code}\n\nخروجی stdout:\n{stdout_output}"
378
- return result_text, output_path
379
- else:
380
- return f"فایل خروجی یافت نشد. خروجی:\n{stdout_output}\nکد:\n{wrapped_code}", None
381
-
382
- except Exception as gen_error:
383
- return f"خطا در تولید کد (OpenRouter): {str(gen_error)}\nپرامپت:\n{instruction}", None
384
 
385
  # Gradio Interface
 
386
  with gr.Blocks(title="AI File Processor - Final Robust Version") as demo:
387
- gr.Markdown("""
 
388
  # پردازشگر فایل با هوش مصنوعی (نسخه تمام‌خطا)
 
389
  ## اجرای قابل اعتماد بدون مشکل از `__name__` تا ساختار
390
 
391
  **ورژن نهایی با تمام رفع‌های خطا:**
392
- ✅ رفع تمام تعاریف `__name__`
393
- ✅ رفع مشکلات ساختاری `try/except`
394
- ✅ اجرای امن و خطاگذار
395
- ✅ افزودن نیم‌ساختار `try/except` مناسب
396
- ✅ اعتبارسنجی دقیق پیش از اجرای کد
397
 
398
  **قابلیت‌ها:**
399
- ✅ پشتیبانی از تمام عملیات پیچیده
400
- ✅ تشخیص خودکار پکیج‌های بیشتر
401
- ✅ نصب خودکار تمام ماژول‌های مورد نیاز
402
- ✅ گزارش‌های دقیق خطا
403
 
404
  **نوت:** این ورژن 99% از ارورها را حل کرده و با تمام کدهای تولید شده تست شده است.
405
  """)
406
 
407
- with gr.Row():
408
- instruction_input = gr.Textbox(label="دستور (مثال: بک گراند عکس را حذف کن)", placeholder="دستور خود را بنویسید...", lines=3)
409
- files_input = gr.File(file_count="multiple", label="فایل(ها)")
410
-
411
- process_btn = gr.Button("پردازش با OpenRouter")
412
-
413
- output_text = gr.Textbox(label="نتیجه و کد", lines=15)
414
- output_file = gr.File(label="فایل خروجی (لینک دانلود)")
415
-
416
- process_btn.click(
417
- fn=process_request,
418
- inputs=[instruction_input, files_input],
419
- outputs=[output_text, output_file]
420
- )
 
 
421
 
422
- if __name__ == "__main__":
423
- demo.launch(share=True)
 
7
  import subprocess
8
  import importlib.util
9
  import re
10
+ import textwrap
11
+ from contextlib import redirect\_stdout
12
 
13
  # Use OpenRouter API (OpenAI-compatible)
14
+
15
+ OPENROUTER\_API\_KEY = os.getenv("OPENROUTER\_API\_KEY")
16
  client = openai.OpenAI(
17
+ api\_key=OPENROUTER\_API\_KEY,
18
+ base\_url="[https://openrouter.ai/api/v1](https://openrouter.ai/api/v1)"
19
  )
20
 
21
+ MODEL\_NAME = "openai/gpt-oss-20b\:free"
22
 
23
+ def detect\_required\_packages(code):
24
+ """Detect required packages from Python code."""
25
+ required\_packages = set()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
+ ```
28
+ # Regex patterns for detecting imports
29
+ import_patterns = [
30
+ r'import\s+(\w+)(?:\.\w+)*',
31
+ r'from\s+(\w+)(?:\.\w+)*\s+import',
32
+ ]
33
+
34
+ # Regex patterns for detecting package installation commands (pip install)
35
+ pip_patterns = [
36
+ r'pip\s+install\s+([^\s]+)',
37
+ r'install\s+([^\s]+)'
38
+ ]
39
+
40
+ # Check for package installations in the code itself
41
+ for pattern in pip_patterns:
42
+ matches = re.findall(pattern, code, re.IGNORECASE)
43
+ for match in matches:
44
+ if match and not match.startswith('"'): # Simple filtering
45
+ required_packages.add(match.split('==')[0].split('>')[0].split('<')[0])
46
+
47
+ # Check for standard imports that might require packages
48
+ lines = code.split('\n')
49
+ for line in lines:
50
+ line = line.strip()
51
+ if line.startswith(('import ', 'from ')):
52
+ # Extract module name after import/from
53
+ for pattern in import_patterns:
54
+ matches = re.findall(pattern, line)
55
+ for module in matches:
56
+ if module and module != '__future__':
57
+ # Map common module names to package names
58
+ module_map = {
59
+ 'cv2': 'opencv-python',
60
+ 'sklearn': 'scikit-learn',
61
+ 'tf': 'tensorflow',
62
+ 'torch': 'torch',
63
+ 'numpy': 'numpy',
64
+ 'pandas': 'pandas',
65
+ 'pillow': 'Pillow',
66
+ 'matplotlib': 'matplotlib',
67
+ 'seaborn': 'seaborn',
68
+ 'onnxruntime': 'onnxruntime',
69
+ 'rembg': 'rembg',
70
+ 'requests': 'requests'
71
+ }
72
+ # Add to required packages (or map to corresponding package)
73
+ if module in module_map:
74
+ required_packages.add(module_map[module])
75
+ else:
76
+ # Use module name as package name (some cases work this way)
77
+ required_packages.add(module)
78
+
79
+ # Remove empty strings and standard library modules
80
+ std_libs = {
81
+ 'os', 'sys', 'io', 'json', 're', 'time', 'math', 'random', 'collections',
82
+ 'itertools', 'functools', 'operator', 'string', 'pathlib', 'tempfile',
83
+ 'subprocess', 'logging', 'argparse', 'csv', 'xml', 'html', 'base64',
84
+ 'hashlib', 'urllib', 'http', 'threading', 'multiprocessing', 'socket',
85
+ 'asyncio', 'concurrent', 'abc', 'enum', 'dataclasses', 'typing'
86
+ }
87
+
88
+ required_packages = required_packages - std_libs
89
+
90
+ return list(required_packages)
91
+ ```
92
+
93
+ def install\_package(package\_name):
94
+ """Install a package using pip if it's not already installed."""
95
+ try:
96
+ \# Try to detect by module name for some common packages
97
+ module\_name = package\_name
98
+ \# handle some known cases where package name != import name
99
+ pkg\_to\_module = {
100
+ 'opencv-python': 'cv2',
101
+ 'Pillow': 'PIL',
102
+ 'scikit-learn': 'sklearn'
103
+ }
104
+ module\_name = pkg\_to\_module.get(package\_name, package\_name)
105
+ spec = importlib.util.find\_spec(module\_name)
106
+ if spec is None:
107
+ print(f"Installing package: {package\_name}")
108
+ subprocess.check\_call(\[
109
+ sys.executable, "-m", "pip", "install", "--quiet", package\_name
110
+ ])
111
+ print(f"✅ {package\_name} installed successfully.")
112
+ else:
113
+ print(f"✅ {package\_name} already installed.")
114
+ except Exception as e:
115
+ print(f"❌ Failed to install {package\_name}: {str(e)}")
116
+ raise RuntimeError(f"Installation failed for {package\_name}: {str(e)}")
117
+
118
+ def install\_packages\_if\_needed(packages):
119
+ """Install all required packages."""
120
+ if not packages:
121
+ print("No packages to install.")
122
+ return True
123
+
124
+ ```
125
+ for package in packages:
126
+ if package:
127
+ try:
128
+ install_package(package)
129
+ except Exception as e:
130
+ print(f"⚠️ Could not install {package}: {e}")
131
+ # Continue with other packages even if one fails
132
 
133
+ return True
134
+ ```
135
+
136
+ def generate\_code\_with\_openrouter(instruction, file\_paths):
137
+ """
138
+ Generate Python code using OpenRouter API.
139
+ """
140
+ prompt = f"""
141
  You are a Python expert. The user has provided the instruction: "{instruction}"
142
+ And input files: {file\_paths} (these paths are available in the current working directory).
143
 
144
  Write a complete, self-contained Python script that:
145
+
146
  1. Reads the input file(s) from the given paths.
147
  2. Performs the requested operation.
148
  3. Saves the output file(s) to a temporary directory (use tempfile.mkdtemp() for a temp dir).
149
+ 4. At the very end of the script, print exactly one line: OUTPUT\_FILE\_PATH: /full/path/to/output/file.ext
150
  (Replace with the actual full path to the generated output file.)
151
 
152
  Use only safe, standard libraries or pre-installed ones. If you need additional packages outside standard libraries,
153
  comment them clearly at the top for proper installation.
154
 
155
  Avoid network calls and file deletion outside temporary directories. Handle errors gracefully.
156
+ Do not define main functions or use **name** == "**main**".
157
  Keep code structure clean.
 
158
  DO NOT USE MULTILINE STRING OR TRIPLE QUOTES INSIDE CODE.
159
  Do not include any markdown formatting or explanations.
160
 
 
163
  import tempfile
164
  import zipfile
165
 
166
+ input\_path = '{file\_paths\[0]}'
167
+ temp\_dir = tempfile.mkdtemp()
168
+ output\_zip\_path = os.path.join(temp\_dir, 'output.zip')
169
 
170
  try:
171
+ with zipfile.ZipFile(output\_zip\_path, 'w', compression=zipfile.ZIP\_DEFLATED) as zipf:
172
+ arcname = os.path.basename(input\_path)
173
+ zipf.write(input\_path, arcname=arcname)
174
  except Exception as e:
175
+ print(f"Error creating zip: {{e}}")
176
+ exit(1)
177
 
178
+ print(f"OUTPUT\_FILE\_PATH: {{output\_zip\_path}}")
179
 
180
  Generate ONLY the Python code.
181
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
 
183
+ ````
184
+ try:
185
+ response = client.chat.completions.create(
186
+ model=MODEL_NAME,
187
+ messages=[
188
+ {"role": "system", "content": "You are a helpful Python code generator. Respond only with clean, executable Python code."},
189
+ {"role": "user", "content": prompt}
190
+ ],
191
+ max_tokens=1200,
192
+ temperature=0.2,
193
+ stop=["```"]
194
+ )
 
 
 
195
 
196
+ generated_code = response.choices[0].message.content.strip()
197
 
198
+ # Clean up markdown code blocks
199
+ if generated_code.startswith("```python"):
200
+ generated_code = generated_code[10:].strip()
201
+ if generated_code.endswith("```"):
202
+ generated_code = generated_code[:-3].strip()
203
+
204
+ return generated_code
205
+
206
+ except Exception as api_error:
207
+ raise api_error
208
+ ````
209
+
210
+ def safe\_exec\_code(code, globals\_dict, locals\_dict):
211
+ """Safely execute code and return output."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  try:
213
+ \# First try to compile just to catch syntax errors
214
+ compiled\_code = compile(code, '<string>', 'exec')
215
+
216
+ ```
217
+ # Run the code
218
+ exec(compiled_code, globals_dict, locals_dict)
219
+ return True, None
220
  except Exception as e:
221
+ return False, str(e)
222
+ ```
223
+
224
+ def process\_request(instruction, files):
225
+ if not files:
226
+ return "لطفاً حداقل یک فایل آپلود کنید.", None
227
+
228
+ ```
229
+ file_paths = [file.name for file in files]
230
+
231
+ try:
232
+ # Generate code using OpenRouter
233
+ generated_code = generate_code_with_openrouter(instruction, file_paths)
234
+
235
+ if not generated_code or len(generated_code) < 50:
236
+ return f"کد مناسبی تولید نشد. پرامپت: {instruction}\nکد تولید شده:\n{generated_code}", None
237
+
238
+ print("--- Generated code ---")
239
+ print(repr(generated_code)) # Debugging
240
+ print("---------------------")
241
+
242
+ # Detect required packages
243
+ required_packages = detect_required_packages(generated_code)
244
+ print("Detected required packages:", required_packages)
245
+
246
+ # Install required packages
247
+ if required_packages:
248
  try:
249
+ install_packages_if_needed(required_packages)
250
+ except Exception as install_err:
251
+ print(f"Warning: Package installation issues: {install_err}")
252
+
253
+ # Create a safe execution environment
254
+ # Conditionally import heavy/optional libs only if detected to avoid import errors
255
+ optional_imports = {}
256
+ if 'Pillow' in required_packages or 'PIL' in required_packages:
257
+ try:
258
+ optional_imports['PIL'] = __import__('PIL', fromlist=['Image'])
259
+ except Exception as e:
260
+ optional_imports['PIL'] = None
261
+ print(f"Warning: PIL import failed: {e}")
262
+ if 'requests' in required_packages:
263
+ try:
264
+ optional_imports['requests'] = __import__('requests')
265
+ except Exception as e:
266
+ optional_imports['requests'] = None
267
+ print(f"Warning: requests import failed: {e}")
268
+
269
+ safe_globals = {
270
+ '__builtins__': {
271
+ 'print': print,
272
+ 'open': open,
273
+ 'range': range,
274
+ 'len': len,
275
+ 'str': str,
276
+ 'int': int,
277
+ 'float': float,
278
+ 'list': list,
279
+ 'dict': dict,
280
+ 'tuple': tuple,
281
+ 'set': set,
282
+ 'bool': bool,
283
+ 'type': type,
284
+ 'isinstance': isinstance,
285
+ 'hasattr': hasattr,
286
+ 'getattr': getattr,
287
+ 'setattr': setattr,
288
+ 'delattr': delattr,
289
+ 'abs': abs,
290
+ 'all': all,
291
+ 'any': any,
292
+ 'bin': bin,
293
+ 'chr': chr,
294
+ 'complex': complex,
295
+ 'divmod': divmod,
296
+ 'enumerate': enumerate,
297
+ 'format': format,
298
+ 'hash': hash,
299
+ 'hex': hex,
300
+ 'id': id,
301
+ 'iter': iter,
302
+ 'max': max,
303
+ 'min': min,
304
+ 'next': next,
305
+ 'oct': oct,
306
+ 'ord': ord,
307
+ 'pow': pow,
308
+ 'repr': repr,
309
+ 'round': round,
310
+ 'slice': slice,
311
+ 'sorted': sorted,
312
+ 'sum': sum,
313
+ 'zip': zip,
314
+ '__import__': __import__,
315
+ 'exit': sys.exit,
316
+ 'True': True,
317
+ 'False': False,
318
+ 'None': None,
319
+ },
320
+ '__name__': '__main__', # Explicitly set __name__
321
+ 'os': os,
322
+ 'tempfile': tempfile,
323
+ 'sys': sys,
324
+ 'subprocess': subprocess,
325
+ 'importlib': importlib,
326
+ 're': re,
327
+ 'json': __import__('json'),
328
+ 'time': __import__('time'),
329
+ 'math': __import__('math'),
330
+ 'random': __import__('random'),
331
+ 'collections': __import__('collections'),
332
+ 'itertools': __import__('itertools'),
333
+ 'functools': __import__('functools'),
334
+ 'operator': __import__('operator'),
335
+ 'pathlib': __import__('pathlib'),
336
+ 'logging': __import__('logging'),
337
+ 'argparse': __import__('argparse'),
338
+ 'csv': __import__('csv'),
339
+ 'base64': __import__('base64'),
340
+ 'hashlib': __import__('hashlib'),
341
+ 'urllib': __import__('urllib'),
342
+ 'http': __import__('http'),
343
+ 'socket': __import__('socket'),
344
+ 'threading': __import__('threading'),
345
+ 'multiprocessing': __import__('multiprocessing'),
346
+ 'asyncio': __import__('asyncio'),
347
+ 'concurrent': __import__('concurrent'),
348
+ 'abc': __import__('abc'),
349
+ 'enum': __import__('enum'),
350
+ 'dataclasses': __import__('dataclasses'),
351
+ 'typing': __import__('typing'),
352
+ 'zipfile': __import__('zipfile'),
353
+ }
354
+
355
+ # Add optional imports only if available
356
+ for k, v in optional_imports.items():
357
+ if v is not None:
358
+ safe_globals[k] = v
359
+
360
+ # Clean up globals to remove None entries (prevents AttributeError)
361
+ safe_globals_clean = {k: v for k, v in safe_globals.items() if v is not None}
362
+
363
+ # Prepare wrapped code by properly indenting the generated code inside a try/except block
364
+ # This avoids producing an unindented 'try:' that causes SyntaxError.
365
+ normalized_code = generated_code.replace('\r\n', '\n').rstrip()
366
+ indented_code = textwrap.indent(normalized_code, ' ')
367
+ wrapped_code = (
368
+ "try:\n"
369
+ + indented_code
370
+ + "\nexcept Exception as e:\n"
371
+ " print(f\"ERROR: {e}\")\n"
372
+ " import traceback\n"
373
+ " traceback.print_exc()\n"
374
+ " sys.exit(1)\n"
375
+ )
376
+
377
+ print("--- Wrapped code ---")
378
+ print(repr(wrapped_code)) # Debugging
379
+ print("---------------------")
380
+
381
+ # Validate that wrapped code compiles properly
382
+ try:
383
+ compile(wrapped_code, '<wrapped_string>', 'exec')
384
+ except SyntaxError as se:
385
+ return f"Syntax error in wrapped code: {se}\nWrapped code:\n{wrapped_code}", None
386
+
387
+ # Capture output
388
+ f = io.StringIO()
389
+ output_path = None
390
+
391
+ with redirect_stdout(f):
392
+ try:
393
+ # Execute code safely
394
+ exec_result, exec_error = safe_exec_code(wrapped_code, safe_globals_clean, {})
395
+
396
+ if not exec_result:
397
+ return f"Execution failed: {exec_error}\nCode:\n{wrapped_code}", None
398
+
399
+ # Get stdout output
400
+ stdout_output = f.getvalue()
401
+ print("STDOUT OUTPUT:")
402
+ print(stdout_output)
403
+
404
+ # Extract output file path
405
+ if "OUTPUT_FILE_PATH:" in stdout_output:
406
+ output_path = stdout_output.split("OUTPUT_FILE_PATH:")[-1].strip()
407
+ output_path = output_path.split('\n')[0].strip()
408
 
409
+ except Exception as exec_error:
410
+ error_msg = f"Error during execution: {str(exec_error)}"
411
+ import traceback
412
+ error_msg += "\n" + traceback.format_exc()
413
+ return f"{error_msg}\nCode:\n{wrapped_code}", None
414
+
415
+ # Clean up
416
+ if output_path and os.path.exists(output_path):
417
+ result_text = f"عملیات با موفقیت انجام شد!\nکد تولید شده توسط OpenRouter:\n{wrapped_code}\n\nخروجی stdout:\n{stdout_output}"
418
+ return result_text, output_path
419
+ else:
420
+ return f"فایل خروجی یافت نشد. خروجی:\n{stdout_output}\nکد:\n{wrapped_code}", None
421
 
422
+ except Exception as gen_error:
423
+ return f"خطا در تولید کد (OpenRouter): {str(gen_error)}\nپرامپت:\n{instruction}", None
424
+ ```
 
 
 
 
 
 
425
 
426
  # Gradio Interface
427
+
428
  with gr.Blocks(title="AI File Processor - Final Robust Version") as demo:
429
+ gr.Markdown("""
430
+
431
  # پردازشگر فایل با هوش مصنوعی (نسخه تمام‌خطا)
432
+
433
  ## اجرای قابل اعتماد بدون مشکل از `__name__` تا ساختار
434
 
435
  **ورژن نهایی با تمام رفع‌های خطا:**
436
+ ✅ رفع تمام تعاریف `__name__`
437
+ ✅ رفع مشکلات ساختاری `try/except`
438
+ ✅ اجرای امن و خطاگذار
439
+ ✅ افزودن نیم‌ساختار `try/except` مناسب
440
+ ✅ اعتبارسنجی دقیق پیش از اجرای کد
441
 
442
  **قابلیت‌ها:**
443
+ ✅ پشتیبانی از تمام عملیات پیچیده
444
+ ✅ تشخیص خودکار پکیج‌های بیشتر
445
+ ✅ نصب خودکار تمام ماژول‌های مورد نیاز
446
+ ✅ گزارش‌های دقیق خطا
447
 
448
  **نوت:** این ورژن 99% از ارورها را حل کرده و با تمام کدهای تولید شده تست شده است.
449
  """)
450
 
451
+ ```
452
+ with gr.Row():
453
+ instruction_input = gr.Textbox(label="دستور (مثال: بک گراند عکس را حذف کن)", placeholder="دستور خود را بنویسید...", lines=3)
454
+ files_input = gr.File(file_count="multiple", label="فایل(ها)")
455
+
456
+ process_btn = gr.Button("پردازش با OpenRouter")
457
+
458
+ output_text = gr.Textbox(label="نتیجه و کد", lines=15)
459
+ output_file = gr.File(label="فایل خروجی (لینک دانلود)")
460
+
461
+ process_btn.click(
462
+ fn=process_request,
463
+ inputs=[instruction_input, files_input],
464
+ outputs=[output_text, output_file]
465
+ )
466
+ ```
467
 
468
+ if **name** == "**main**":
469
+ demo.launch(share=True)