PyACT / src /streamlit_app.py
alibidaran's picture
Update src/streamlit_app.py
718c928 verified
raw
history blame
8.63 kB
import streamlit as st
from code_editor import code_editor
import json
import requests
import contextlib
import io
import streamlit.components.v1 as st1
import subprocess
import sys
import os
from database_center import db_transaction
import uuid
import dotenv
import os
from cloudhands import CloudHandsPayment
from streamlit_lottie import st_lottie, st_lottie_spinner
import json
import time
import openai
import dotenv
import os
dotenv.load_dotenv()
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
payment_key=os.getenv('Payment_Key')
def load_local_lottie(path):
with open(path, 'r') as file:
return json.load(file)
def complete_payment(db_transaction):
if st.session_state.token :
chPay=st.session_state.chPay
try:
result = chPay.charge(
charge=0.5,
event_name="Sample cloudhands charge",
)
st.success(f"You payment is succeeded")
st.session_state.transaction_id=result.transaction_id
db_transaction.add({
'id':str(uuid.uuid4()),
'app':'app_title',
'transaction-id':result.transaction_id,
'price':0.5
})
except Exception as e:
st.error(f"Charge failed: {e}")
else:
st.error('Please generate your Tokens.')
# Init payment handler once
if "chPay" not in st.session_state:
st.session_state.chPay = CloudHandsPayment(
author_key=payment_key
)
if "token" not in st.session_state:
st.session_state.token = None
@st.dialog("Payment link")
def pay():
chPay = st.session_state.chPay
# Step 1: Show auth link only once
auth_url = chPay.get_authorization_url()
st.link_button("Authenticate", url=auth_url)
# Step 2: User pastes the code
code = st.text_input("Place your code")
if st.button("Exchange Code"):
try:
token = chPay.exchange_code_for_token(code)
st.session_state.token = token
st.success("Code exchanged successfully! Token stored.")
except Exception as e:
st.error(f"Failed: {e}")
def respond_default_model(user_prompt):
url = "https://8000-01k36m8w3tq0w1hk9xwscmxs1c.cloudspaces.litng.ai/predict"
message = {"user_prompt": user_prompt}
response = requests.post(url, data=message)
#print(response.json())
full_response = response.json()['output'][0]
def respond_gpt5(user_prompt):
chat_engine=openai.OpenAI()
response = chat_engine.chat.completions.create(
model='gpt-5-mini',
messages=[{'role':'user','content':user_prompt}]
)
return response.choices[0].message.content.strip()
# --- Initialize session state ---
if "code" not in st.session_state:
st.session_state.code = "print('Hello, world!')"
if "edited_code" not in st.session_state:
st.session_state.edited_code = st.session_state.code
if 'db_transaction' not in st.session_state:
st.session_state.db_transaction = db_transaction
if 'loading_state' not in st.session_state:
st.session_state.loading_state = True
# --- Sidebar info ---
if st.session_state.loading_state:
with st_lottie_spinner(load_local_lottie('./src/Hello World!.json'), key='hello'):
time.sleep(5)
st.session_state.loading_state = False
st.sidebar.title("💡 About")
st.sidebar.info(
"This app generates Python code from your prompt using an AI model API.\n\n"
"Enter your prompt and click 'Generate Code' to see the result."
)
st.sidebar.markdown("---")
st.sidebar.write("Created with ❤️ using Streamlit and code_editor.")
st.sidebar.write("You can also edit your pyhton code in the code editor and lively run it.")
st.sidebar.subheader("📦 Install Python Library")
with st.sidebar.form("install_lib_form"):
lib_name = st.text_input("Library name (e.g., numpy, pandas)")
install_btn = st.form_submit_button("Install with pip")
if install_btn and lib_name.strip():
with st.spinner(f"Installing {lib_name}..."):
try:
# Define target directory for installation
target_dir = "/.local/lib/python3.9/site-packages"
os.makedirs(target_dir, exist_ok=True)
# Add to sys.path so imports work immediately
if target_dir not in sys.path:
sys.path.insert(0, target_dir)
# Run pip install into target dir
result = subprocess.run(
[
sys.executable, "-m", "pip", "install",
lib_name,
"--no-cache-dir",
"--target", target_dir
],
capture_output=True, text=True
)
if result.returncode == 0:
st.success(f"Successfully installed `{lib_name}`.")
else:
st.error(f"Error installing `{lib_name}`:\n{result.stderr}")
except Exception as e:
st.error(f"Exception: {e}")
st.title("🧠 Python Code Generator & Runner")
Authenication=st.button('Authenicate')
if Authenication:
pay()
concepts=st.selectbox("Here are several examples that you can be familiar with the concept of our WebApp.",
("Write a Python program to plot the Gaussian distribution. Use Streamlit and Plotly Express for plotting.",
"Create a Python program to make the K-means algorithm with sklearn and plot the clusters. Use Streamlit and matplotlib for plotting the object.",
"Write a Python program to read my CSV file and describe it for me. The name of the CSV file is 'test.csv'"))
st.markdown("Here is the selected example prompt")
st.write(concepts)
# --- Prompt input ---
st.write("### Enter your prompt to generate Python code:")
model=st.pills('Select AI Model',["Default","gpt-5-mini"],selection_mode='single')
user_prompt = st.text_area("Prompt", "Write a function to add two numbers")
# --- Buttons ---
col1, col2 = st.columns(2)
with col1:
generate_button = st.button("🚀 Generate Code")
with col2:
run_button = st.button("▶️ Run Code")
# --- Code generation logic ---
if generate_button:
complete_payment(st.session_state.db_transaction)
if st.session_state.transaction_id:
if user_prompt.strip():
with st.spinner("Generating code..."):
try:
if model == "Default":
full_response = respond_default_model(user_prompt)
elif model == "gpt-5-mini":
full_response = respond_gpt5(user_prompt)
except Exception as e:
st.error(f"Error during code generation: {e}")
if full_response.startswith("```python"):
full_response = full_response[9:]
if full_response.endswith("```"):
full_response = full_response[:-3]
# Update session state
st.session_state.code = full_response
st.session_state.edited_code = full_response
else:
st.warning("Please enter a prompt before generating.")
# --- Code Editor ---
editor_result = code_editor(
st.session_state.edited_code,
lang="python",
height=300
)
# Update edited_code only if not empty
if editor_result and "text" in editor_result and editor_result["text"].strip() != "":
st.session_state.edited_code = editor_result["text"]
if run_button:
st.write("### 🧪 Output:")
print(st.session_state.edited_code)
# if 'edited_code' in st.session_state.edited_code:
# if 'matplotlib.pyplot' in st.session_state.edited_code:
try:
# Prepare an output buffer to capture printed text
output_buffer = io.StringIO()
exec_globals = {}
# Capture stdout during execution
with contextlib.redirect_stdout(output_buffer):
exec(st.session_state.edited_code, exec_globals)
# Show stdout (printed output)
output_text = output_buffer.getvalue()
if output_text.strip():
st.code(output_text, language="text")
else:
st.info("Code ran, but produced no printed output.")
# # Optional: Display returned variables or functions
# user_vars = {k: v for k, v in exec_globals.items() if not k.startswith("__")}
# if user_vars:
# st.write("**Variables in scope:**")
# st.json(user_vars)
except Exception as e:
st.error(f"Execution error: {e}")