Spaces:
Runtime error
Runtime error
File size: 27,265 Bytes
95bc5d9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 |
"""
Details : AutoBard-Coder is code genrator for bard. It is used to generate code from bard response.
its using Bard API to interact with bard and refine the results for coding purpose.
The main purpose of this is for research and educational purpose.
This is using unofficial bard api and not affiliated with bard in any way - So use it at your own risk.
This can generate the code from prompt and fix itself unless the code is fixed.
Language : Python
Dependencies : streamlit, bard-coder
Author : HeavenHM.
License : MIT
Date : 21-05-2023
"""
# Import the required libraries
import logging
import sys
import streamlit as st
from os import path
import time
import traceback
from lib.bardcoder_lib import BardCoder
import subprocess
from io import StringIO
import re
from lib.sharegpt_api import sharegpt_get_url
from lib.blacklist_commands import harmful_commands_python, harmful_commands_cpp, harmful_prompts
from PIL import Image
import tokenize
import io
# The input limit of Bard is 4,000 character (As per the Bard API documentation)
# But you can give more input upto 10,000 characters. so we are gonna stick to that.
BARD_FILE_SIZE_LIMIT = 10000
# Function to measure the accuracy of the code
def measure_accuracy(counter):
accuracy = 1 / (counter + 1)
accuracy_percentage = accuracy * 100
st.info(
f"Output has been fixed {counter} times with accuracy {accuracy_percentage:.0f}%")
def show_content(content):
# Open the file and read its contents
with open(content, "r") as f:
markdown_text = f.read()
# Display the Markdown text in the app
st.markdown(markdown_text)
# method to execute the bard coder process
def auto_bard_execute(prompt, code_file='code.txt', code_choices='code_choice', expected_output=None, exec_type='single', rate_limiter_delay=5):
try:
# Additional prompt for class clarification.
# prompt += "\n" + f"Note: The Name the class should be {code_file} if Java language is requested"
# Additional prompt for no input clarification.
prompt += "\n" + "Dont ask the input from user.If input values are provided in code just use them. otherwise, you can hardcode the input values in code."
# Setting the prompt.
prompt_status, error_reason = st.session_state.bard_coder.set_prompt(prompt)
if not prompt_status:
st.error(f"Error no data was recieved from Server, Reason {error_reason}")
st.stop()
# Get the code from the response.
code = st.session_state.bard_coder.get_code()
# Save the code to file
saved_file = st.session_state.bard_coder.save_code(code_file, code)
if saved_file:
st.info(f"Code saved to file {saved_file}")
else:
st.info("Code not saved to file")
return None, None, False
st.info("Executing primary code")
# check for safe code to run.
code = st.session_state.bard_coder.read_file(saved_file)
safe_code = False
code_snippet = None
code_command = None
safe_code_dict = []
if code:
safe_code_dict = is_code_safe(code)
# Get tuple from list of tuples code_safe_dict
safe_code = safe_code_dict[0][0]
code_command = safe_code_dict[0][1]
code_snippet = safe_code_dict[0][2]
if safe_code:
code_output = st.session_state.bard_coder.execute_code(saved_file)
if code_output and code_output != None and code_output.__len__() > 0:
if 'error' in code_output.lower() or 'exception' in code_output.lower():
st.info(f"Error in executing code with type {exec_type}")
return code_output, saved_file, False
# Check if expected output is in code output.
if expected_output and expected_output in code_output:
code_choices_output = [code_output]
return code_output, saved_file, True
else:
if exec_type == 'single':
time.sleep(rate_limiter_delay)
return code_output, saved_file, False
else:
time.sleep(rate_limiter_delay)
else:
return code_output, saved_file, False
# Save all the code choices to file
if exec_type == 'multiple':
st.session_state.bard_coder.save_code_choices(code_choices)
st.info("Executing code choices")
code_choices_output = st.session_state.bard_coder.execute_code_choices()
code_choices_output.append(code_output)
st.info(f"Output: {code_choices_output}")
return code_choices_output, saved_file, False
else:
for safe_codes in safe_code_dict:
if safe_codes[0]: # Skip if code is safe
continue
safe_code = safe_codes[0]
code_command = safe_codes[1]
code_snippet = safe_codes[2]
st.error(f"Error: Cannot execute the code because of illegal command found '{code_command}' in code snippet '{code_snippet}'")
BardCoder.write_log(f"Cannot run the code:\n'{code}'\nbecause of illegal command found '{code_command}' in code snippet '{code_snippet}'")
st.stop()
return None, None, False
except Exception as e:
# show_outputf the stack trace
stack_trace = traceback.format_exc()
st.info(stack_trace)
st.info(str(e))
# method to execute the bard coder process
def auto_bard_setup(prompt, code_file='code.txt', code_choices='code_choice', expected_output=None, exec_type='single', rate_limiter_delay=5):
# Append the codes directory to filename
code_file = path.join("codes", code_file)
test_cases_output = 0 # Test cases for output.
# Start the bard coder process
code_choices_output, saved_file, status = auto_bard_execute(
prompt, code_file, code_choices, expected_output, exec_type)
code_output = None
# Check if file is saved.
if not saved_file:
return code_choices_output, saved_file, status
if status:
st.info(
f"Expected output found in file {saved_file}\nOutput: {code_choices_output}")
else:
st.info(
f"Expected output not found in file {saved_file}\nOutput: {code_choices_output}")
if code_choices_output:
code_output = ''.join(code_choices_output)
if code_output and code_output != None and code_output.__len__() > 0:
# Check for errors like 'error' or 'Error' check case sensitivity and add more error checks.
if code_output is not None:
code_output = "".join(code_output)
else:
code_output = ""
if code_output:
while 'error' in code_output.lower() or 'exception' in code_output.lower():
st.info(
"Error in executing code,Trying to fix the code with error")
# Re-prompt on error.
code = st.session_state.bard_coder.get_code()
prompt = f"I got error while running the code {code_output}.\nPlease fix the code ``\n`{code}\n``` \nand try again.\nHere is error {code_output}\n\n" + \
"Note:The output should only be fixed code and nothing else. No explanation or anything else."
# Start the bard coder process again.
code_output, saved_file, status = auto_bard_execute(
prompt, code_file, code_choices, expected_output, exec_type)
# Sleep for 5 seconds before re-prompting. Dont get Rate limited.
time.sleep(rate_limiter_delay)
test_cases_output += 1
st.info("Code has been fixed for errors")
st.code(code_output, language="python")
# Check for expected output.
if code_output and expected_output and code_output.__len__() > 0:
# While expected output does not contain in code output.
while expected_output not in code_output:
st.info(
f"Expected output {expected_output} not found in code\nOutput: {code_output}")
# Re-prompt on expected output not found.
code = st.session_state.bard_coder.get_code()
prompt = f"I got output {code_output}.\nPlease fix the code ``\n`{code}\n``` \nand try again.\nHere is expected output: {code_output}\n\n" + \
"Note:The output should only be fixed code and nothing else. No explanation or anything else."
# start the bard coder process again.
code_output, saved_file, status = auto_bard_execute(
prompt, code_file, code_choices, expected_output, exec_type)
# Sleep for N seconds before re-prompting. Dont get Rate limited.
time.sleep(rate_limiter_delay)
test_cases_output += 1
st.info("Code has been fixed for expected output")
st.info(code_output)
else:
st.info("Not checking for code expected output")
else:
st.info("Code output is empty for error")
# Print output and information.
measure_accuracy(test_cases_output)
content_file = "response/content.md"
show_content(content_file)
return code_output, saved_file, status
def find_image_files(file_path):
# Create a regular expression for image files
image_regex = re.compile(r"\b\w+\.(png|jpg|jpeg|gif|bmp)", re.IGNORECASE)
# Open the code file
with open(file_path) as f:
# Read the lines
lines = f.readlines()
# Loop through the lines
for line in lines:
# Search for image files in the line
match = image_regex.search(line)
# If there is a match
if match:
# Get the image file name
image_file = match.group()
# Print the image file name
return image_file
return None
def is_prompt_safe(prompt):
if prompt is None:
BardCoder.write_log("Prompt is Empty")
return False
BardCoder.write_log("Checking prompt for safety")
# Extra care for prompt input.
prompt_list = [re.sub(r'[^\w\s]', '', re.sub(r'(\*\*|__)(.*?)(\*\*|__)', r'\2', re.sub(
r'^\W+|\W+$', '', item))).strip() for item in re.split('\n| ', prompt.lower()) if item.strip() != '']
prompt_list = [re.sub(r'\d+', '', i) for i in prompt_list]
BardCoder.write_log(f"Prompt list is {prompt_list}")
# Convert the code to lowercase and split it into a list of words
# Check if any harmful command is in the list of words
for command in harmful_prompts:
if command in prompt_list:
BardCoder.write_log(f"Prompt is not safe because of illegal command found '{command}'")
return False, command
BardCoder.write_log(f"Input Prompt is safe")
return True, None
def tokenize_source_code(source_code):
tokens = []
try:
for token in tokenize.generate_tokens(io.StringIO(source_code).readline):
if token.type not in [tokenize.ENCODING, tokenize.NEWLINE, tokenize.INDENT, tokenize.DEDENT]:
if any(char in token.string for char in ['::', '.', '->', '_']) or token.string.isalnum():
token_str = re.sub(r'\'|\"', '', token.string)
tokens.append(token_str)
except tokenize.TokenError:
if st.session_state.bard_coder:
BardCoder.write_log("Error parsing the tokens")
if tokens:
tokens = list(([token.lower() for token in tokens]))
if st.session_state.bard_coder:
BardCoder.write_log(f"Tokenise was called and Tokens length is {tokens.__len__()}")
return tokens
def is_code_safe(code):
if st.session_state.bard_coder:
BardCoder.write_log("Checking code for safety")
# Combine both lists
harmful_code_commands = harmful_commands_python + harmful_commands_cpp
# Tokenize the code
tokens_list = tokenize_source_code(code)
# Initialize the output dictionary
output_dict = []
# Check if any harmful command is in the list of words
for command in harmful_code_commands:
for token in tokens_list:
if command == token:
output_dict.append((False, command, token))
if output_dict is None or output_dict.__len__() == 0:
output_dict = [(True, None, None)]
if st.session_state.bard_coder:
BardCoder.write_log(f"Output dict is {output_dict}")
return output_dict
def load_css(file_name):
# Open the file and read the content
with open(file_name) as fp:
css = fp.read()
# Use st.components.v1.html to load the CSS file
st.markdown(f'<style>{css}</style>', unsafe_allow_html=True)
def display_logo(logo_file: str, title: str):
# create two columns
col1, col2 = st.columns(2, gap='large')
# use the first column for the image
col1.image(logo_file, width=370)
# use the second column for the title
col2.title(title)
def dsiplay_buttons(is_prompt_valid: bool):
col1, col2, col3 = st.columns(3, gap='large')
with col1: # use the first column
run_button = st.button("Run", key="run-button", use_container_width=True,
disabled=not is_prompt_valid) # place the run button as a regular button
with col2: # use the second column
share_button = st.button("Share", key="share-button", use_container_width=True,
disabled=not is_prompt_valid) # place the share button as a regular button
with col3:
# place the help button as a regular button
help_button = st.button(
"Help", key="help-button", use_container_width=True)
return run_button, share_button, help_button
def init_bard_coder_session(api_key=None, timeout=10):
# Initialize the bard coder session
bard_coder = BardCoder(api_key=api_key, enable_logs=True, timeout=timeout)
return bard_coder
def init_session_state():
# Initialize the session state variables
if "bard_coder" not in st.session_state:
st.session_state.bard_coder = None
if "api_key_initialized" not in st.session_state:
st.session_state.api_key_initialized = False
if "code_output" not in st.session_state:
st.session_state.code_output = ""
if "messages" not in st.session_state:
st.session_state.messages = ""
if "text_area" not in st.session_state:
st.session_state.text_area = ""
if "file_size" not in st.session_state:
st.session_state.file_size = 0
if "file_char_count" not in st.session_state:
st.session_state.file_char_count = 0
if __name__ == "__main__":
try:
BardCoder.write_log("Starting the streamlit App")
# Load the CSS file named style.css
load_css("styles/style.css")
# Upload file data variables
upload_prompt_data, upload_data, uploaded_file = None, None, None
# Initialize the session state variables
BardCoder.write_log("Initializing the session state variables")
init_session_state()
BardCoder.write_log("Session state variables initialized")
# Set the logo and title
logo_file = "resources/logo.png"
title = "Code Interpreter"
display_logo(logo_file, title)
BardCoder.write_log("Logo and title set")
# Use the text_area variable from the session state for input
prompt = st.text_area(placeholder="Enter your prompt here", label="Prompt",label_visibility="hidden", height=300, key="text_area_input")
# check if prompt is changed.
if prompt != st.session_state.text_area:
BardCoder.write_log(f"Prompt changed from '{st.session_state.text_area}' to '{prompt}'")
st.session_state.text_area = prompt
character_count: int = len(st.session_state.text_area)
# Status info message. (Char count and file size)
status_info_msg = f"Characters:{character_count}/{BARD_FILE_SIZE_LIMIT}"
if st.session_state.file_size > 0:
BardCoder.write_log(f"File Char count is {st.session_state.file_char_count}")
character_count += st.session_state.file_char_count
# Update the character count for file size.
status_info_msg = f"Characters:{character_count}/{BARD_FILE_SIZE_LIMIT}"
status_info_msg += " | " + f"File Size is {st.session_state.file_size/1024:.2f}Kb | {st.session_state.file_size/1024/1024:.2f}Mb"
st.info(status_info_msg)
# check the Prompt for safety and file size exceeding 4,000 characters.
prompt_safe = True
if st.session_state.bard_coder:
prompt_safe, command = is_prompt_safe(prompt)
if not prompt_safe:
BardCoder.write_log(f"Error in prompt because of unsafe command found '{command}'")
st.error(f"Error in prompt because of illegal command found '{command}'")
if character_count > BARD_FILE_SIZE_LIMIT or st.session_state.file_char_count > BARD_FILE_SIZE_LIMIT:
st.error(f"Error in prompt The file size limit exceeded {BARD_FILE_SIZE_LIMIT} characters")
# Adding the upload file option
uploaded_file = st.file_uploader("Choose a file")
if uploaded_file is not None:
# To read file as bytes:
bytes_data = uploaded_file.getvalue()
# get the file size
st.session_state.file_size = uploaded_file.size
# To convert to a string based IO:
stringio = StringIO(uploaded_file.getvalue().decode("utf-8"))
# To read file as string:
upload_data = stringio.read()
# Count the number of characters in the file
st.session_state.file_char_count = len(upload_data)
# write the file to uploads directory
with open("uploads/" + uploaded_file.name, "w") as f:
f.write(upload_data)
# Display a success message
st.success("File uploaded successfully.")
# Setting options for the application
with st.expander("Options"):
code_file = st.text_input("Filename for the generated code (without extension):", value="generated_code")
code_choices = st.text_input("Filename for code choices:", value="code_choices")
expected_output = st.text_input("Expected output (leave blank if none):")
exec_type = st.selectbox("Execution type:", ["single", "multiple"], index=0)
timeout_delay = st.number_input("Timeout (in seconds):", value=10)
with st.expander("Settings"):
bard_key_help_text = """
How to obtain Google Bard API key.
1. Visit bard.google.com and open the console with F12
2. Go to Application → Cookies and copy the __Secure-1PSID value
3. This is your API key paste it below.
"""
st.info(bard_key_help_text)
bard_api_key = st.text_input(label="API Key", label_visibility="hidden", type="password", placeholder="Enter your bard API key.")
if bard_api_key and not st.session_state.api_key_initialized:
# how to call write_file static method from BardCoder class
BardCoder.write_log("Starting init API Key")
st.session_state.bard_coder = init_bard_coder_session(bard_api_key,timeout_delay)
if BardCoder.bard_init:
st.session_state.api_key_initialized = True
BardCoder.write_log("Bard Coder initialized successfully")
st.info("Bard Coder initialized successfully")
else:
st.session_state.api_key_initialized = False
BardCoder.write_log("Error initializing Bard Coder")
st.error("Error initializing Bard Coder")
# Setting advanced options for the application
with st.expander("Advanced"):
try:
# button to show logs.
show_logs = st.button("Show Logs", key="show-logs-button", use_container_width=True)
if show_logs:
if st.session_state.bard_coder:
logs_data = st.session_state.bard_coder.read_file(st.session_state.bard_coder.logs_file)
st.code(logs_data, language="python")
except Exception as e:
st.error(f"Error in showing logs {e}")
# button to show content.
try:
show_content_button = st.button("Show Content", key="show-content-button", use_container_width=True)
if show_content_button:
if st.session_state.bard_coder:
content_data = st.session_state.bard_coder.read_file("response/response.md")
st.code(content_data, language="python")
except Exception as e:
st.error(f"Error in showing content {e}")
# button to show response.
try:
show_response_button = st.button("Show Response", key="show-response-button", use_container_width=True)
if show_response_button:
if st.session_state.bard_coder:
response_data = st.session_state.bard_coder.read_file("response/response.json")
st.code(response_data, language="json")
except Exception as e:
st.error(f"Error in showing response {e}")
# Setting the buttons for the application
run_button, share_button, help_button = dsiplay_buttons(prompt_safe and st.session_state.file_char_count < BARD_FILE_SIZE_LIMIT)
# Setting application to run
if run_button:
# Code to execute when the "Run" button is clicked
# Check if API Key is empty
if bard_api_key is None or bard_api_key == "" or bard_api_key.__len__() == 0:
st.error("Error executing code the API key is missing from settings.\nPlease go to settings and add your API key.")
BardCoder.write_log("Error executing code the API key is missing from settings.Please go to settings and add your API key.")
st.stop()
# Clear the previous cache.
st.info("Running the code interpreter...")
subprocess.call(['bash', 'bash_src/clear_cache.sh'])
# Append the uploaded file data to prompt
if upload_data:
prompt += "\n" + f"Here is the file called {uploaded_file.name} at location {'uploads/' + uploaded_file.name} data.\n" + \
f"```\n{upload_data}\n```"
# If graph were requested.
if 'graph' in prompt.lower():
prompt += "\n" + "using Python use Matplotlib save the graph in file called 'graph.png'"
# if Chart were requested
if 'chart' in prompt.lower() or 'plot' in prompt.lower():
prompt += "\n" + "using Python use Plotly save the chart in file called 'chart.png'"
# if Table were requested
if 'table' in prompt.lower():
prompt += "\n" + "using Python use Pandas save the table in file called 'table.md'"
# Refine the prompt for harmful commands.
if prompt_safe:
# Run the auto bard setup process.
log_container = st.empty()
st.session_state.code_output, saved_file, status = auto_bard_setup(prompt, code_file, code_choices,
expected_output, exec_type,timeout_delay)
else:
st.error(f"Cannot execute the prompt because of illegal command found '{command}'")
BardCoder.write_log(f"Cannot execute the prompt: '{prompt}' because of illegal command found '{command}'")
st.stop()
# Check if output is Graph,Chart request.
if 'graph' in prompt.lower() or 'chart' in prompt.lower():
image_file_graph = find_image_files(saved_file)
if image_file_graph:
BardCoder.write_log(f"Graph image file is {image_file_graph} and code file is {saved_file}")
image = Image.open(image_file_graph)
st.image(image, caption='Graph Output')
# Check if output in Table request.
if 'table' in prompt.lower():
table_file = "table.md"
table_file_data = st.session_state.bard_coder.read_file(
table_file)
if table_file_data:
st.markdown(table_file_data)
# Adding Share button
if share_button:
if st.session_state.code_output is None or st.session_state.messages is None:
BardCoder.write_log("ShareGPT: Error Please run the code generator first")
st.error("Error: Please run the code generator first")
else:
gpt_data = prompt
human_data = ""
if st.session_state.messages:
human_data = "Bard Logs: \n" + st.session_state.messages
if st.session_state.code_output:
human_data += "\nOutput:\n" + st.session_state.code_output
human_data += "\n\n[AutoBard-Coder: Repo](https:#github.com/haseeb-heaven/AutoBard-Coder)"
if gpt_data.__len__() > 0 and human_data.__len__() > 0:
sharegpt_url = sharegpt_get_url(gpt_data, human_data)
st.info(f"ShareGPT Url: {sharegpt_url}")
else:
BardCoder.write_log("ShareGPT: Error Please run the code generator first")
st.error("Error: Please run the code generator first")
# Adding Help button
if help_button:
content_file = "README.md"
if st.session_state.bard_coder:
content_data = st.session_state.bard_coder.read_file(content_file)
st.markdown(content_data, unsafe_allow_html=True)
else:
st.error("API key is missing from settings.\nPlease go to settings and add your API key.")
BardCoder.write_log("Help: Error API key is missing from settings.")
except Exception as e:
# show_outputf the stack trace
stack_trace = traceback.format_exc()
st.error("Error: " + str(e))
st.error(stack_trace)
|