A robust, containerized Flask API that allows you to execute Python code remotely to generate Matplotlib graphs. This service is designed for headless environments and includes authentication and basic logging.
- Headless Rendering: Uses Matplotlib's Agg backend to render graphs without a display.
- Secure-ish Execution: Executes user-provided Python code in a restricted scope (see Security Note).
- Authentication: Protects endpoints with API Key authentication.
- Logging: Structured logging for monitoring and debugging.
- Dockerized: Ready for deployment using Docker.
- Tested: Comprehensive test suite using
pytest.
.
├── src/
│ ├── app.py # Main Flask application
│ ├── config.py # Configuration management
│ └── executor.py # Code execution logic
├── tests/ # Unit tests
├── Dockerfile # Container definition
├── Makefile # Convenience commands
└── requirements.txt # Python dependencies
- Python 3.10+
- Pip
-
Clone the repository:
git clone https://github.com/your-username/matplotlib-render-api.git cd matplotlib-render-api -
Install dependencies:
make install # or pip install -r requirements.txt -
Set up environment variables: Create a
.envfile in the root directory:PORT=5150 API_KEY=your-secret-api-key DEBUG=True
make run
# or
export API_KEY=my-secret-key
python -m src.appThe server will start at http://0.0.0.0:5150.
GET /
Returns a simple status message to verify the service is running.
- Response:
200 OK
POST /render-matplotlib
Executes the provided Python code and returns the generated graph as a PNG image.
-
Headers:
Content-Type: application/jsonX-API-Key: <your-api-key>
-
Body:
{ "code": "import numpy as np\nimport matplotlib.pyplot as plt\nx = np.linspace(0, 10, 100)\nplt.plot(x, np.sin(x))\n" } -
Response:
200 OK: Returns the PNG image (MIME typeimage/png).400 Bad Request: Missing code or invalid JSON.401 Unauthorized: Invalid or missing API Key.500 Internal Server Error: Error during code execution (returns error trace).
Build and run the container:
docker build -t matplotlib-api .
docker run -p 5150:5150 -e API_KEY=secret matplotlib-apiRun the test suite using pytest:
make test
# or
export PYTHONPATH=$PYTHONPATH:.
pytestexec() function to execute arbitrary code sent by the client. While basic sandboxing is attempted, it is not secure against malicious attacks.
- Do not expose this API publicly without strict firewalls and trusted clients.
- The current implementation allows imports to facilitate library usage, which increases risk.
- For a truly secure environment, consider running the execution logic inside an isolated ephemeral container (e.g., AWS Lambda, Firecracker microVMs).