A lightweight, secure, and maintainable framework for executing dynamic Python scripts as internal APIs.
In many enterprise IT environments, teams frequently need lightweight APIs for internal systems, automation, scheduled tasks, diagnostic tools, or ad-hoc scripts. These APIs don’t always justify a full microservice architecture, but they must be:
- Easy to extend
- Secure
- Maintainable
- Fast to deploy
To meet these needs, I built a lightweight Internal API Platform using:
- Python + Flask
- Docker
- Apache Reverse Proxy
- Dynamic execution of
.pyscripts - Namespace separation (
root,api,admin) - IP whitelisting + API Key + Admin Key security
- Centralized logging with trace IDs
- Health check, route listing, and metrics endpoints
This article documents the full architecture and implementation.
✨ 1. Goal: A Fast, Secure, Maintainable Internal API Platform
The platform’s objectives:
✔ Execute Python scripts directly as API endpoints
Examples:
/api/hello.py
/admin/stats.py
/report_json.py
Each script only needs to define:
def main(request):
...
and it becomes a fully functional API.
✔ Namespace-based routing
Automatically maps URL prefixes to folder structures:
| URL Prefix | Folder | Purpose |
|---|---|---|
/xxx.py | /app/xxx.py | General scripts |
/api/xxx.py | /app/api/xxx.py | Internal API |
/admin/xxx.py | /app/admin/xxx.py | Admin / privileged API |
✔ Security
Built-in protection:
- IP Whitelist
- API Key (for /api)
- Admin Key (for /admin)
Example Docker environment variables:
API_TRUSTED_IPS="172.18.0.1,127.0.0.1"
API_KEY="secret123"
ADMIN_API_KEY="admin456"
✔ Unified Enterprise Logging
Every request is logged with:
- Endpoint & namespace
- Client IP
- Query parameters
- Execution time
- Status code
- Trace ID
- Stacktrace for script exceptions
Logs stored at:
/opt/docker/python/app/logs/framework.log
✔ Platform-Level APIs
To support observability and operations:
/_platform/health: health & uptime/_platform/routes: list available endpoints/_platform/metrics: real-time metrics
🧱 2. Architecture Overview
The architecture is simple, containerized, and easy to maintain:
Client → Apache Reverse Proxy → Flask Internal API Platform → Dynamically execute Python scripts
For every *.py call, the platform:
- Resolves the correct script based on URL
- Dynamically imports and executes it
- Returns output (text/JSON/file)
- Logs execution details
- Attaches a trace ID
📂 3. Directory Structure
The platform’s directory layout:
/opt/docker/python/app
├── app.py # Platform dispatcher
├── logs/
│ └── framework.log
├── api/
│ ├── hello.py
│ └── report_json.py
└── admin/
└── stats.py
Scripts placed in these folders automatically become API endpoints.
🧠 4. Core Technology: The Dynamic Dispatcher
At the heart of the platform is Python’s dynamic import mechanism:
spec = importlib.util.spec_from_file_location(module_name, script_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
handler = getattr(module, "handle", None) or getattr(module, "main", None)
result = handler(request)
This enables:
- Zero-config API creation
- Scripts acting as independent endpoints
- Rapid internal tooling and automation
Adding a new script = dropping a .py file into a folder.
🔐 5. Security Layer
The platform implements three security controls:
✔ 1. IP Whitelist
if ALLOWED_IP_SET and client_ip not in ALLOWED_IP_SET:
return make_response("Forbidden (IP not allowed)", 403)
✔ 2. API Key for /api
if area == "api" and API_KEY:
if request.headers.get("X-API-Key") != API_KEY:
return make_response("Forbidden (invalid API key)", 403)
✔ 3. Admin Key for /admin
if area == "admin" and ADMIN_API_KEY:
if request.headers.get("X-Admin-Key") != ADMIN_API_KEY:
return make_response("Forbidden (invalid Admin key)", 403)
This structure prevents accidental exposure of internal tools and ensures security without over-engineering.
📈 6. Platform-Level Endpoints
✔ 1. Health Check
/_platform/health
{
"status": "ok",
"uptime_sec": 1623,
"requests_total": 83,
"errors_total": 1
}
✔ 2. List All Script Endpoints
/_platform/routes
{
"root": ["report.py"],
"api": ["hello.py", "report_json.py"],
"admin": ["stats.py"]
}
✔ 3. Metrics
/_platform/metrics
{
"uptime_sec": 1644,
"requests_total": 95,
"requests_by_area": {
"root": 30,
"api": 50,
"admin": 15
},
"errors_total": 1
}
👨💻 7. Writing API Scripts (Extremely Simple)
Each endpoint is just a .py file.
✔ /api/hello.py
def main(request):
name = request.args.get("name", "Guest")
return {"message": f"Hello, {name}!"}
✔ /admin/stats.py
def main(request):
return {"status": "admin ok"}
✔ /api/download.py (File download)
from flask import send_file
def main(request):
return send_file("/app/data/sample.txt", as_attachment=True)
The platform handles:
- JSON conversion
- Response wrapping
- Error logging
- Trace ID generation
🐳 8. Docker Deployment
Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY app/ /app/
RUN pip install flask gunicorn
CMD ["gunicorn", "-b", "0.0.0.0:5000", "app:app"]
Run Command
docker run -d \
--name pyapp \
--network intranet-net \
-v /opt/docker/python/app:/app \
-e API_TRUSTED_IPS="192.168.1.10,127.0.0.1" \
-e API_KEY="secret123" \
-e ADMIN_API_KEY="admin456" \
mypython:1.0
🔄 9. Apache Reverse Proxy
ProxyPreserveHost On
ProxyPass / http://pyapp:5000/
ProxyPassReverse / http://pyapp:5000/
🎯 Conclusion: A Practical and Enterprise-Ready Internal API Framework
This Internal API Platform provides:
| Capability | Description |
|---|---|
| 🧠 Dynamic Python execution | Every .py file becomes an API automatically |
| 📂 Namespaced routing | root / api / admin |
| 🔐 Security | IP whitelist, API Key, Admin Key |
| 📝 Centralized logging | trace_id, stacktrace, execution time |
| 📈 Observability | health, routes, metrics |
| ⚡ Rapid development | add script → instant endpoint |
| 🧰 IT-friendly | ideal for automation, tools, internal integrations |
This framework is perfect for:
- Internal reporting APIs
- System automation
- Backend tools
- Scheduled tasks
- Lightweight internal microservices