vsj0702 commited on
Commit
d2d8482
·
verified ·
1 Parent(s): 9fbd263
Files changed (1) hide show
  1. utils.py +81 -88
utils.py CHANGED
@@ -1,17 +1,17 @@
 
1
  import sys
2
  import random
3
- import os
4
- import subprocess
5
- from io import StringIO
6
- import contextlib
7
  import tempfile
 
8
  import requests
 
9
  from datetime import datetime
10
  from typing import Tuple
 
11
 
 
12
  @contextlib.contextmanager
13
  def capture_output():
14
- """Capture stdout and stderr for Python code"""
15
  stdout, stderr = StringIO(), StringIO()
16
  old_out, old_err = sys.stdout, sys.stderr
17
  try:
@@ -20,64 +20,7 @@ def capture_output():
20
  finally:
21
  sys.stdout, sys.stderr = old_out, old_err
22
 
23
- def _execute_with_onecompiler(code: str, stdin: str, language: str, filename: str) -> Tuple[str, str, str]:
24
- keys = [os.environ["ONECOMPILER_API_KEY"], os.environ["ONECOMPILER_API_KEY1"]]
25
- first_key = random.choice(keys)
26
-
27
- result = _call_onecompiler_api(first_key, code, stdin, language, filename)
28
-
29
- if _is_quota_or_invalid(result):
30
- # Fallback: try all keys one-by-one until one works
31
- for key in keys:
32
- if key == first_key:
33
- continue # Already tried this one
34
- result = _call_onecompiler_api(key, code, stdin, language, filename)
35
- if not _is_quota_or_invalid(result):
36
- return result
37
-
38
- return result # Either success, or last failed response
39
-
40
-
41
- def _call_onecompiler_api(key: str, code: str, stdin: str, language: str, filename: str) -> Tuple[str, str, str]:
42
- url = "https://onecompiler-apis.p.rapidapi.com/api/v1/run"
43
- headers = {
44
- "Content-Type": "application/json",
45
- "x-rapidapi-host": "onecompiler-apis.p.rapidapi.com",
46
- "x-rapidapi-key": key
47
- }
48
- payload = {
49
- "language": language.lower(),
50
- "stdin": stdin,
51
- "files": [
52
- {
53
- "name": filename,
54
- "content": code
55
- }
56
- ]
57
- }
58
-
59
- try:
60
- response = requests.post(url, json=payload, headers=headers, timeout=10)
61
- data = response.json()
62
-
63
- if data.get("status") == "failed":
64
- return "", "", f"OneCompiler Error: {data.get('error')}"
65
-
66
- return (
67
- data.get("stdout", "").strip(),
68
- data.get("stderr", "") or "",
69
- data.get("exception", "")
70
- )
71
- except Exception as e:
72
- return "", "", str(e)
73
-
74
-
75
- def _is_quota_or_invalid(result: Tuple[str, str, str]) -> bool:
76
- _, _, error = result
77
- if not error:
78
- return False
79
- return any(token in error.lower() for token in ["quota", "e002", "e003", "invalid", "exhausted"])
80
-
81
  def execute_code(code: str, stdin: str = "", language: str = "cpp") -> Tuple[str, str, str]:
82
  try:
83
  if language == "Python":
@@ -97,19 +40,43 @@ def execute_code(code: str, stdin: str = "", language: str = "cpp") -> Tuple[str
97
  except Exception as e:
98
  return "", "", str(e)
99
 
100
-
101
  def _execute_python(code: str, stdin: str) -> Tuple[str, str, str]:
102
  with capture_output() as (stdout, stderr):
103
  try:
104
  inputs = iter(stdin.splitlines())
105
- input_override = lambda prompt='': next(inputs, '')
106
- local_vars = {"input": input_override}
107
  exec(code, {}, local_vars)
108
  return stdout.getvalue().strip(), stderr.getvalue().strip(), None
109
  except Exception as e:
110
  return stdout.getvalue().strip(), stderr.getvalue().strip(), str(e)
111
 
 
 
 
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  def _run_subprocess(cmd, stdin_input=None) -> Tuple[str, str, str]:
114
  try:
115
  result = subprocess.run(
@@ -123,33 +90,59 @@ def _run_subprocess(cmd, stdin_input=None) -> Tuple[str, str, str]:
123
  except Exception as e:
124
  return "", "", str(e)
125
 
 
 
 
 
126
 
127
- def _execute_c(code: str, stdin: str):
128
- with tempfile.TemporaryDirectory() as tmp:
129
- source_path = os.path.join(tmp, "main.c")
130
- binary_path = os.path.join(tmp, "main.out")
131
- with open(source_path, "w") as f:
132
- f.write(code)
133
- compile_cmd = ["gcc", source_path, "-o", binary_path]
134
- compile_out, compile_err, exc = _run_subprocess(compile_cmd)
135
- if exc or compile_err:
136
- return compile_out, compile_err, exc
137
- return _run_subprocess([binary_path], stdin)
138
 
 
 
 
 
 
 
 
139
 
140
- def _execute_cpp(code: str, stdin: str):
141
- with tempfile.TemporaryDirectory() as tmp:
142
- source_path = os.path.join(tmp, "main.cpp")
143
- binary_path = os.path.join(tmp, "main.out")
144
- with open(source_path, "w") as f:
145
- f.write(code)
146
- compile_cmd = ["g++", source_path, "-o", binary_path]
147
- compile_out, compile_err, exc = _run_subprocess(compile_cmd)
148
- if exc or compile_err:
149
- return compile_out, compile_err, exc
150
- return _run_subprocess([binary_path], stdin)
 
 
 
 
 
 
 
 
 
 
151
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
 
 
153
  def export_session(code: str, output: str, error: str) -> dict:
154
  return {
155
  "timestamp": datetime.now().isoformat(),
 
1
+ import os
2
  import sys
3
  import random
 
 
 
 
4
  import tempfile
5
+ import subprocess
6
  import requests
7
+ from io import StringIO
8
  from datetime import datetime
9
  from typing import Tuple
10
+ import contextlib
11
 
12
+ # --- Utility context manager to capture stdout/stderr (for Python execution) ---
13
  @contextlib.contextmanager
14
  def capture_output():
 
15
  stdout, stderr = StringIO(), StringIO()
16
  old_out, old_err = sys.stdout, sys.stderr
17
  try:
 
20
  finally:
21
  sys.stdout, sys.stderr = old_out, old_err
22
 
23
+ # --- Public API to execute code ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  def execute_code(code: str, stdin: str = "", language: str = "cpp") -> Tuple[str, str, str]:
25
  try:
26
  if language == "Python":
 
40
  except Exception as e:
41
  return "", "", str(e)
42
 
43
+ # --- Python Execution ---
44
  def _execute_python(code: str, stdin: str) -> Tuple[str, str, str]:
45
  with capture_output() as (stdout, stderr):
46
  try:
47
  inputs = iter(stdin.splitlines())
48
+ local_vars = {"input": lambda _: next(inputs, "")}
 
49
  exec(code, {}, local_vars)
50
  return stdout.getvalue().strip(), stderr.getvalue().strip(), None
51
  except Exception as e:
52
  return stdout.getvalue().strip(), stderr.getvalue().strip(), str(e)
53
 
54
+ # --- C Execution ---
55
+ def _execute_c(code: str, stdin: str):
56
+ return _compile_and_run(code, stdin, ext="c", compiler="gcc")
57
 
58
+ # --- C++ Execution ---
59
+ def _execute_cpp(code: str, stdin: str):
60
+ return _compile_and_run(code, stdin, ext="cpp", compiler="g++")
61
+
62
+ # --- Compilation helper ---
63
+ def _compile_and_run(code: str, stdin: str, ext: str, compiler: str):
64
+ with tempfile.TemporaryDirectory() as tmp:
65
+ source = os.path.join(tmp, f"main.{ext}")
66
+ binary = os.path.join(tmp, "main.out")
67
+
68
+ with open(source, "w") as f:
69
+ f.write(code)
70
+
71
+ compile_cmd = [compiler, source, "-o", binary]
72
+ comp_out, comp_err, comp_exc = _run_subprocess(compile_cmd)
73
+
74
+ if comp_exc or comp_err:
75
+ return comp_out, comp_err, comp_exc
76
+
77
+ return _run_subprocess([binary], stdin)
78
+
79
+ # --- Run subprocess and capture output ---
80
  def _run_subprocess(cmd, stdin_input=None) -> Tuple[str, str, str]:
81
  try:
82
  result = subprocess.run(
 
90
  except Exception as e:
91
  return "", "", str(e)
92
 
93
+ # --- Java, JS, C# via OneCompiler API ---
94
+ def _execute_with_onecompiler(code: str, stdin: str, language: str, filename: str) -> Tuple[str, str, str]:
95
+ keys = [os.environ["ONECOMPILER_API_KEY"], os.environ["ONECOMPILER_API_KEY1"]]
96
+ primary_key = random.choice(keys)
97
 
98
+ result = _call_onecompiler_api(primary_key, code, stdin, language, filename)
 
 
 
 
 
 
 
 
 
 
99
 
100
+ if _is_quota_or_invalid(result):
101
+ for key in keys:
102
+ if key == primary_key:
103
+ continue
104
+ result = _call_onecompiler_api(key, code, stdin, language, filename)
105
+ if not _is_quota_or_invalid(result):
106
+ break
107
 
108
+ return result
109
+
110
+ def _call_onecompiler_api(key: str, code: str, stdin: str, language: str, filename: str) -> Tuple[str, str, str]:
111
+ url = "https://onecompiler-apis.p.rapidapi.com/api/v1/run"
112
+ headers = {
113
+ "Content-Type": "application/json",
114
+ "x-rapidapi-host": "onecompiler-apis.p.rapidapi.com",
115
+ "x-rapidapi-key": key,
116
+ }
117
+ payload = {
118
+ "language": language.lower(),
119
+ "stdin": stdin,
120
+ "files": [{"name": filename, "content": code}]
121
+ }
122
+
123
+ try:
124
+ response = requests.post(url, json=payload, headers=headers, timeout=10)
125
+ data = response.json()
126
+
127
+ if data.get("status") == "failed":
128
+ return "", "", f"OneCompiler Error: {data.get('error')}"
129
 
130
+ return (
131
+ data.get("stdout", "").strip(),
132
+ data.get("stderr", "") or "",
133
+ data.get("exception", "")
134
+ )
135
+ except Exception as e:
136
+ return "", "", str(e)
137
+
138
+ def _is_quota_or_invalid(result: Tuple[str, str, str]) -> bool:
139
+ _, _, error = result
140
+ if not error:
141
+ return False
142
+ error = error.lower()
143
+ return any(term in error for term in ["quota", "e002", "e003", "invalid", "exhausted"])
144
 
145
+ # --- Export utility ---
146
  def export_session(code: str, output: str, error: str) -> dict:
147
  return {
148
  "timestamp": datetime.now().isoformat(),