A C# Kestrel web server that serves as a completely dynamic API server. Instead of creating specific C# methods, it automatically discovers and executes Python scripts based on URL paths. The C# layer is completely agnostic and can execute any SQL command generated by Python scripts.
HTTP Request → Dynamic Controller → Python Script Discovery → SQL Generation → Generic SQL Service → Database → Response
/api/get-user/3 automatically executes get-user.py with parameter 3The system automatically maps URL paths to Python scripts:
| URL Path | Python Script | Example |
|---|---|---|
/api/get-users | get-users.py | Get all users |
/api/get-user/123 | get-user.py | Get user with ID 123 |
/api/create-user | create-user.py | Create new user |
/api/update-user/456 | update-user.py | Update user with ID 456 |
/api/delete-user/789 | delete-user.py | Delete user with ID 789 |
/api/search-users | search-users.py | Search users by query |
/api/user-stats | user-stats.py | Get user statistics |
/api/Each Python script receives a standardized request object:
{
"path": "get-user/123",
"method": "GET",
"query": {"param1": "value1"},
"headers": {"content-type": "application/json"},
"body": {"field1": "value1"},
"path_params": ["123"]
}All responses use a consistent 4-field JSON format:
{
"error": "string | empty",
"message": "string",
"data": "object | array | null",
"timestamp": "ISO 8601 datetime"
}Response Examples:
{"error": "", "message": "Users retrieved successfully", "data": [...], "timestamp": "2024-12-14T17:30:45.123Z"}{"error": "Script not found", "message": "Script execution failed", "data": null, "timestamp": "2024-12-14T17:30:45.123Z"}KestrelPythonApi/
├── Controllers/
│ └── DynamicController.cs # Single dynamic controller (no specific methods)
├── Services/
│ ├── PythonService.cs # IronPython integration service
│ └── SqlService.cs # Generic SQL execution service
├── PythonScripts/ # Auto-discovered Python scripts
│ ├── get-users.py # Auto-mapped from /api/get-users
│ ├── get-user.py # Auto-mapped from /api/get-user/*
│ ├── create-user.py # Auto-mapped from /api/create-user
│ ├── update-user.py # Auto-mapped from /api/update-user/*
│ ├── delete-user.py # Auto-mapped from /api/delete-user/*
│ ├── search-users.py # Auto-mapped from /api/search-users
│ └── user-stats.py # Auto-mapped from /api/user-stats
├── Program.cs # Application entry point
├── appsettings.json # Configuration
└── README.md # This file
curl -X GET "http://localhost:5000/api/get-users"
curl -X GET "http://localhost:5000/api/get-user/123"
curl -X POST "http://localhost:5000/api/create-user" \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"email": "john@example.com",
"phone": "123-456-7890"
}'
curl -X POST "http://localhost:5000/api/create-user" \
-F "name=Jane Smith" \
-F "email=jane@example.com" \
-F "phone=098-765-4321"
curl -X PUT "http://localhost:5000/api/update-user/1" \
-H "Content-Type: application/json" \
-d '{
"name": "John Updated",
"email": "john.updated@example.com",
"phone": "111-222-3333"
}'
curl -X DELETE "http://localhost:5000/api/delete-user/1"
curl -X GET "http://localhost:5000/api/search-users?name=john"
curl -X GET "http://localhost:5000/api/search-users?email=example.com"
curl -X GET "http://localhost:5000/api/user-stats"
.py file to PythonScripts/ folder/api/hello-world endpointPythonScripts/hello-world.py:import json
import sys
def process_request(request_data):
return {
"success": True,
"data": {"message": "Hello from Python!"},
"message": "Generated greeting"
}
if __name__ == "__main__":
request_data = json.loads(sys.argv[1]) if len(sys.argv) > 1 else {}
result = process_request(request_data)
print(json.dumps(result))
curl -X GET "http://localhost:5000/api/hello-world"
request_data['path_params'] arrayrequest_data['query'] dictionaryrequest_data['body'] dictionaryimport json
import sys
def process_request(request_data):
"""
Process request and generate SQL command
"""
try:
# Extract data from request
method = request_data.get('method', 'GET')
path_params = request_data.get('path_params', [])
query_params = request_data.get('query', {})
body = request_data.get('body', {})
# Your logic here
sql = "SELECT * FROM table WHERE condition = @param"
parameters = {"@param": "value"}
return {
"success": True,
"sql": sql,
"parameters": parameters,
"operation": "SELECT",
"message": "Generated SQL successfully"
}
except Exception as e:
return {
"success": False,
"error": str(e),
"message": "Failed to generate SQL"
}
if __name__ == "__main__":
# Read request data from command line argument
if len(sys.argv) > 1:
request_data = json.loads(sys.argv[1])
else:
request_data = {}
result = process_request(request_data)
print(json.dumps(result))
Python scripts can generate complex SQL:
Python scripts can control HTTP responses:
# Navigate to project directory
cd KestrelPythonApi
# Restore dependencies
dotnet restore
# Build project
dotnet build
# Run application
dotnet run
The server will start on http://localhost:5000
Open your browser and navigate to http://localhost:5000 to see interactive API documentation.
The application can be configured via appsettings.json:
{
"ConnectionStrings": {
"DefaultConnection": "Data Source=app.db"
},
"PythonScripts": {
"Path": "PythonScripts"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
This architecture provides the ultimate flexibility for API development while maintaining security, performance, and type safety through the generic C# SQL execution layer.