Skip to content

Commit 22ed806

Browse files
Merge pull request haseeb-heaven#2 from haseeb-heaven/master
Added V2 With OpenAI and Vertex AI Google Codey Support
2 parents 379624b + e96dba2 commit 22ed806

File tree

10 files changed

+1016
-2
lines changed

10 files changed

+1016
-2
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
/LangChainDemo.log
1+
*.pyc
2+
*.pyo
3+
*.log
4+
*.json

libs/general_utils.py

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
# general_utils.py
2+
import os
3+
import tempfile
4+
from libs.logger import logger
5+
import subprocess
6+
import traceback
7+
import streamlit as st
8+
from libs.lang_codes import LangCodes
9+
10+
# Import the service_account module
11+
from google.oauth2 import service_account
12+
from google.auth import exceptions
13+
from google.auth.transport import requests
14+
15+
class GeneralUtils:
16+
17+
def execute_code(self,compiler_mode: str):
18+
logger.info(f"Executing code: {st.session_state.generated_code[:100]} in language: {st.session_state.code_language} with Compiler Mode: {compiler_mode}")
19+
20+
try:
21+
if len(st.session_state.generated_code) == 0 or st.session_state.generated_code == "":
22+
st.toast("Generated code is empty. Cannot execute an empty code.", icon="❌")
23+
return
24+
25+
if compiler_mode.lower() == "online":
26+
html_content = self.generate_dynamic_html(st.session_state.code_language, st.session_state.generated_code)
27+
logger.info(f"HTML Template: {html_content[:100]}")
28+
return html_content
29+
30+
else:
31+
output = self.run_code(st.session_state.generated_code,st.session_state.code_language)
32+
logger.info(f"Output execution: {output}")
33+
34+
if "error" in output.lower() or "exception" in output.lower() or "SyntaxError" in output.lower() or "NameError" in output.lower():
35+
36+
logger.error(f"Error in code execution: {output}")
37+
response = st.session_state.sequential_chain({'code_topic': st.session_state.generated_code})
38+
fixed_code = response['code_fix']
39+
st.code(fixed_code, language=st.session_state.code_language.lower())
40+
41+
with st.expander('Message History'):
42+
st.info(st.session_state.memory.buffer)
43+
logger.warning(f"Trying to run fixed code: {fixed_code}")
44+
output = GeneralUtils.run_code(fixed_code, st.session_state.code_language)
45+
logger.warning(f"Fixed code output: {output}")
46+
47+
st.toast("Execution Output:\n" + output, icon="🔥")
48+
logger.info(f"Execution Output: {output}")
49+
50+
except Exception as e:
51+
st.toast("Error in code execution:",icon="❌")
52+
# Output the stack trace
53+
st.toast(traceback.format_exc(), icon="❌")
54+
logger.error(f"Error in code execution: {traceback.format_exc()}")
55+
56+
# Generate Dynamic HTML for JDoodle Compiler iFrame Embedding.
57+
def generate_dynamic_html(self,language, code_prompt):
58+
logger.info("Generating dynamic HTML for language: %s", language)
59+
html_template = """
60+
<!DOCTYPE html>
61+
<html lang="en">
62+
<head>
63+
<meta charset="UTF-8">
64+
<title>Online JDoodle Compiler</title>
65+
</head>
66+
<body>
67+
<div data-pym-src='https://www.jdoodle.com/plugin' data-language="{language}"
68+
data-version-index="0" data-libs="" >{script_code}
69+
</div>
70+
<script src="https://www.jdoodle.com/assets/jdoodle-pym.min.js" type="text/javascript"></script>
71+
</body>
72+
</html>
73+
""".format(language=LangCodes()[language], script_code=code_prompt)
74+
return html_template
75+
76+
def run_code(self,code, language):
77+
logger.info(f"Running code: {code[:100]} in language: {language}")
78+
79+
if language == "Python":
80+
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=True) as file:
81+
file.write(code)
82+
file.flush()
83+
84+
logger.info(f"Input file: {file.name}")
85+
output = subprocess.run(
86+
["python", file.name], capture_output=True, text=True)
87+
logger.info(f"Runner Output execution: {output.stdout + output.stderr}")
88+
return output.stdout + output.stderr
89+
90+
elif language == "C" or language == "C++":
91+
ext = ".c" if language == "C" else ".cpp"
92+
with tempfile.NamedTemporaryFile(mode="w", suffix=ext, delete=True) as src_file:
93+
src_file.write(code)
94+
src_file.flush()
95+
96+
logger.info(f"Input file: {src_file.name}")
97+
98+
with tempfile.NamedTemporaryFile(mode="w", suffix="", delete=True) as exec_file:
99+
compile_output = subprocess.run(
100+
["gcc" if language == "C" else "g++", "-o", exec_file.name, src_file.name], capture_output=True, text=True)
101+
102+
if compile_output.returncode != 0:
103+
return compile_output.stderr
104+
105+
logger.info(f"Output file: {exec_file.name}")
106+
run_output = subprocess.run(
107+
[exec_file.name], capture_output=True, text=True)
108+
logger.info(f"Runner Output execution: {run_output.stdout + run_output.stderr}")
109+
return run_output.stdout + run_output.stderr
110+
111+
elif language == "JavaScript":
112+
with tempfile.NamedTemporaryFile(mode="w", suffix=".js", delete=True) as file:
113+
file.write(code)
114+
file.flush()
115+
116+
logger.info(f"Input file: {file.name}")
117+
output = subprocess.run(
118+
["node", file.name], capture_output=True, text=True)
119+
logger.info(f"Runner Output execution: {output.stdout + output.stderr}")
120+
return output.stdout + output.stderr
121+
122+
elif language == "Java":
123+
with tempfile.NamedTemporaryFile(mode="w", suffix=".java", delete=True) as file:
124+
file.write(code)
125+
file.flush()
126+
classname = "Main" # Assuming the class name is Main, adjust if needed
127+
compile_output = subprocess.run(["javac", file.name], capture_output=True, text=True)
128+
if compile_output.returncode != 0:
129+
return compile_output.stderr
130+
run_output = subprocess.run(["java", "-cp", tempfile.gettempdir(), classname], capture_output=True, text=True)
131+
return run_output.stdout + run_output.stderr
132+
133+
elif language == "Swift":
134+
with tempfile.NamedTemporaryFile(mode="w", suffix=".swift", delete=True) as file:
135+
file.write(code)
136+
file.flush()
137+
output = subprocess.run(["swift", file.name], capture_output=True, text=True)
138+
return output.stdout + output.stderr
139+
140+
elif language == "C#":
141+
with tempfile.NamedTemporaryFile(mode="w", suffix=".cs", delete=True) as file:
142+
file.write(code)
143+
file.flush()
144+
compile_output = subprocess.run(["csc", file.name], capture_output=True, text=True)
145+
if compile_output.returncode != 0:
146+
return compile_output.stderr
147+
exe_name = file.name.replace(".cs", ".exe")
148+
run_output = subprocess.run([exe_name], capture_output=True, text=True)
149+
return run_output.stdout + run_output.stderr
150+
151+
elif language == "Scala":
152+
with tempfile.NamedTemporaryFile(mode="w", suffix=".scala", delete=True) as file:
153+
file.write(code)
154+
file.flush()
155+
output = subprocess.run(["scala", file.name], capture_output=True, text=True)
156+
return output.stdout + output.stderr
157+
158+
elif language == "Ruby":
159+
with tempfile.NamedTemporaryFile(mode="w", suffix=".rb", delete=True) as file:
160+
file.write(code)
161+
file.flush()
162+
output = subprocess.run(["ruby", file.name], capture_output=True, text=True)
163+
return output.stdout + output.stderr
164+
165+
elif language == "Kotlin":
166+
with tempfile.NamedTemporaryFile(mode="w", suffix=".kt", delete=True) as file:
167+
file.write(code)
168+
file.flush()
169+
compile_output = subprocess.run(["kotlinc", file.name, "-include-runtime", "-d", "output.jar"], capture_output=True, text=True)
170+
if compile_output.returncode != 0:
171+
return compile_output.stderr
172+
run_output = subprocess.run(["java", "-jar", "output.jar"], capture_output=True, text=True)
173+
return run_output.stdout + run_output.stderr
174+
175+
elif language == "Go":
176+
with tempfile.NamedTemporaryFile(mode="w", suffix=".go", delete=True) as file:
177+
file.write(code)
178+
file.flush()
179+
compile_output = subprocess.run(["go", "build", "-o", "output.exe", file.name], capture_output=True, text=True)
180+
if compile_output.returncode != 0:
181+
return compile_output.stderr
182+
run_output = subprocess.run(["./output.exe"], capture_output=True, text=True)
183+
return run_output.stdout + run_output.stderr
184+
else:
185+
return "Unsupported language."
186+
187+
def save_code(self, file_name):
188+
try:
189+
# Check for empty file name
190+
if not file_name or len(file_name) == 0:
191+
st.toast("Please enter a valid file name.", icon="❌")
192+
logger.error("Error in code saving: Please enter a valid file name.")
193+
return
194+
195+
file_extension = file_name.split(".")[-1]
196+
logger.info(f"Saving code to file: {file_name} with extension: {file_extension}")
197+
198+
# Create directory if it doesn't exist
199+
if not os.path.exists(file_extension):
200+
os.makedirs(file_extension)
201+
logger.info(f"Directory {file_extension} created successfully")
202+
203+
# Check for empty code
204+
if not st.session_state.generated_code or len(st.session_state.generated_code.strip()) == 0:
205+
st.toast("Generated code is empty. Cannot save an empty file.", icon="❌")
206+
logger.error("Error in code saving: Generated code is empty.")
207+
return
208+
209+
with open(f"{file_extension}/{file_name}", "w") as file:
210+
file.write(st.session_state.generated_code)
211+
212+
st.toast(f"Code saved to file {file_name}", icon="✅")
213+
logger.info(f"Code saved to file {file_name}")
214+
215+
except Exception as e:
216+
st.toast(traceback.format_exc())
217+
logger.error(f"Error in code saving: {traceback.format_exc()}")
218+
219+
220+
221+
# # Initialize Vertex AI
222+
def load_enviroment_variables(self, credentials_file_path, project, region):
223+
"""
224+
Consider running `gcloud config set project` or setting the GOOGLE_CLOUD_PROJECT environment variable
225+
"""
226+
"""Load environment variables"""
227+
if credentials_file_path:
228+
logger.info(f"Loading credentials from {credentials_file_path}")
229+
try:
230+
credentials = service_account.Credentials.from_service_account_file(credentials_file_path)
231+
session = requests.AuthorizedSession(credentials)
232+
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = session.credentials.refresh(requests.Request()).token
233+
except exceptions.GoogleAuthError as e:
234+
logger.error(f"Failed to load the service account key: {e}")
235+
st.toast(f"Failed to load the service account key: {e}", icon="❌")
236+
return False
237+
else:
238+
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = os.getenv("GOOGLE_APPLICATION_CREDENTIALS")
239+
logger.info("Loading credentials from .env file")
240+
241+
242+
if project:
243+
logger.info(f"Setting project to {project}")
244+
os.environ["GOOGLE_CLOUD_PROJECT"] = project
245+
else:
246+
os.environ["GOOGLE_CLOUD_PROJECT"] = os.getenv("GOOGLE_CLOUD_PROJECT")
247+
logger.info("Loading project from .env file")
248+
249+
if region:
250+
logger.info(f"Setting region to {region}")
251+
os.environ["GOOGLE_CLOUD_REGION"] = region
252+
else:
253+
os.environ["GOOGLE_CLOUD_REGION"] = os.getenv("GOOGLE_CLOUD_REGION")
254+
logger.info("Loading region from .env file")
255+
256+
# Create method which takes string and calulate its number of words,letter count and for each 1000 characters in that string it will multiply with $0.0005 and return the cost, cost per whole string and total cost..
257+
def calculate_code_generation_cost(self,string,price=0.0005):
258+
# Calculate number of words
259+
number_of_words = len(string.split())
260+
261+
# Calculate number of letters
262+
number_of_letters = len(string)
263+
264+
# Calculate cost
265+
cost = price * (number_of_letters / 1000)
266+
267+
# Calculate cost per whole string
268+
cost_per_whole_string = price * (len(string) / 1000)
269+
270+
# Calculate total cost
271+
total_cost = cost * number_of_words
272+
273+
# Return the cost, cost per whole string and total cost
274+
return cost, cost_per_whole_string, total_cost
275+
276+
def codey_generation_cost(self,string):
277+
codey_price = 0.0005
278+
return self.calculate_code_generation_cost(string,codey_price)
279+
280+
def gpt_3_generation_cost(self,string):
281+
chatgpt_price = 0.0002
282+
return self.calculate_code_generation_cost(string,chatgpt_price)
283+
284+
def gpt_3_5_turbo_generation_costself(self,string):
285+
chatgpt_price = 0.0080
286+
return self.calculate_code_generation_cost(string,chatgpt_price)
287+
288+
def gpt_4_generation_cost(self,string):
289+
chatgpt_price = 0.06
290+
return self.calculate_code_generation_cost(string,chatgpt_price)
291+
292+
def gpt_text_davinci_generation_cost(self,string):
293+
chatgpt_price = 0.0060
294+
return self.calculate_code_generation_cost(string,chatgpt_price)

libs/lang_codes.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
def LangCodes():
2+
3+
LANGUAGE_CODES = {
4+
'C': 'c',
5+
'C++': 'cpp',
6+
'Java': 'java',
7+
'Ruby': 'ruby',
8+
'Scala': 'scala',
9+
'C#': 'csharp',
10+
'Objective C': 'objc',
11+
'Swift': 'swift',
12+
'JavaScript': 'nodejs',
13+
'Kotlin': 'kotlin',
14+
'Python': 'python3',
15+
'GO Lang': 'go',
16+
}
17+
return LANGUAGE_CODES

libs/logger.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import logging
2+
from logging.handlers import RotatingFileHandler
3+
4+
def initialize_logger(filename):
5+
# Define the logging format
6+
log_format = ("%(asctime)s [%(levelname)s] [%(filename)s:%(lineno)d] [%(funcName)s] - %(message)s")
7+
8+
# Create a rotating file handler that will manage log file sizes and backups
9+
file_handler = RotatingFileHandler(filename, maxBytes=5*1024*1024) # 5MB per file
10+
file_handler.setFormatter(logging.Formatter(log_format))
11+
12+
# Create the logger
13+
logger = logging.getLogger()
14+
logger.setLevel(logging.INFO)
15+
16+
# Check if the logger already has handlers, if not, add the file handler
17+
if not logger.handlers:
18+
logger.addHandler(file_handler)
19+
20+
return logger
21+
22+
logger = initialize_logger("langchain-coder.log")

0 commit comments

Comments
 (0)