# 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. @app.post("/execute") 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 @app.get("/") def read_root(): return {"message": "Python Code Executor API is running."}