Spaces:
Runtime error
Runtime error
# app.py | |
# This is the main file for our FastAPI application. | |
import io | |
import sys | |
from fastapi import FastAPI, HTTPException | |
from pydantic import BaseModel | |
from fastapi.middleware.cors import CORSMiddleware | |
# Initialize the FastAPI app | |
app = FastAPI( | |
title="Python Code Executor API", | |
description="An API to execute Python code securely and return the output.", | |
version="1.0.0", | |
) | |
# --- CORS Middleware --- | |
# This is important to allow your front-end website (running on a different domain) | |
# to communicate with this API. We'll allow all origins for simplicity. | |
app.add_middleware( | |
CORSMiddleware, | |
allow_origins=["*"], # Allows all origins | |
allow_credentials=True, | |
allow_methods=["*"], # Allows all methods (GET, POST, etc.) | |
allow_headers=["*"], # Allows all headers | |
) | |
# --- Request Body Model --- | |
# This Pydantic model defines the structure of the JSON we expect in the request. | |
# It ensures that the incoming data has a "code" field which is a string. | |
class Code(BaseModel): | |
code: str | |
# --- API Endpoint --- | |
# This defines the endpoint at the path "/execute" that accepts POST requests. | |
async def execute_python_code(code_payload: Code): | |
""" | |
Executes the provided Python code and returns its output or any errors. | |
""" | |
# Create a string buffer to capture the output of the print() statements | |
old_stdout = sys.stdout | |
redirected_output = io.StringIO() | |
sys.stdout = redirected_output | |
try: | |
# The exec() function executes the Python code passed as a string. | |
# We pass an empty dictionary for globals and locals for a cleaner scope. | |
exec(code_payload.code, {}, {}) | |
except Exception as e: | |
# If any error occurs during execution, restore stdout and raise an HTTPException. | |
# This will be sent back to the user as a proper error response. | |
sys.stdout = old_stdout | |
raise HTTPException( | |
status_code=400, | |
detail=f"Error executing code: {str(e)}" | |
) | |
finally: | |
# This 'finally' block ensures that we always restore the original stdout, | |
# even if an error occurred. This is crucial for the server's stability. | |
sys.stdout = old_stdout | |
# Get the captured output from the string buffer | |
output = redirected_output.getvalue() | |
# Return the captured output in a JSON response | |
return {"output": output} | |
# A simple root endpoint to confirm the API is running | |
def read_root(): | |
return {"message": "Python Code Executor API is running."} | |