Lilya Converter¶
Convert web framework codebases into Lilya with deterministic rules, explicit diagnostics, and reproducible reports.
Documentation: https://lilya-converter.dymmond.com 📚
Source Code: https://github.com/dymmond/lilya-converter 💻
The official supported version is always the latest released.
Installation¶
Optional framework extras:
pip install "lilya-converter[fastapi]"
pip install "lilya-converter[flask]"
pip install "lilya-converter[django]"
pip install "lilya-converter[litestar]"
pip install "lilya-converter[starlette]"
Install with all framework extras:
Start Here¶
Framework Support Matrix¶
| Source | Key | Status | Notes |
|---|---|---|---|
| FastAPI | fastapi |
Stable | Default source and backwards-compatible CLI behavior |
| Flask | flask |
Stable | Blueprint and route conversion |
| Django | django |
Stable | URLConf conversion and management-command path remapping |
| Litestar | litestar |
Stable | Decorator and route_handlers conversion |
| Starlette | starlette |
Stable | Route/Mount conversion |
What You Get¶
- Multi-framework adapter architecture.
- Deterministic conversion output.
- Rule-level diagnostics and reports.
- Dry-run and unified diff previews.
- Verification checks after conversion.
Quick Command Preview¶
# Analyze
# lilya-converter analyze ./fastapi_project --json
# lilya-converter analyze ./django_project --source django --output ./reports/scan.json
# Convert with preview
# lilya-converter convert ./litestar_project ./lilya_project --source litestar --dry-run --diff
# Persist reports
# lilya-converter convert ./starlette_project ./lilya_project --source starlette --report ./reports/convert.json
# lilya-converter verify ./lilya_project --source django --report ./reports/verify.json
# Mapping introspection
# lilya-converter map rules --source flask
# lilya-converter map applied ./reports/convert.json
Conversion Preview¶
FastAPI input¶
from fastapi import APIRouter, FastAPI
from fastapi.responses import ORJSONResponse, PlainTextResponse
app = FastAPI(openapi_url=None)
router = APIRouter()
@router.api_route(
"/payload",
methods=["PATCH"],
response_class=ORJSONResponse,
response_model=dict,
responses={404: {"description": "missing"}},
status_code=201,
)
async def payload():
return {"value": 1}
@router.trace("/trace", include_in_schema=False)
async def trace_route():
return PlainTextResponse("trace")
app.include_router(router)
Lilya output¶
from lilya.apps import Lilya as FastAPI
from lilya.responses import PlainText as PlainTextResponse
from lilya.routing import Router as APIRouter
app = FastAPI(enable_openapi=False)
router = APIRouter()
@router.route("/payload", methods=["PATCH"])
async def payload():
return {"value": 1}
@router.route("/trace", include_in_schema=False, methods=["TRACE"])
async def trace_route():
return PlainTextResponse("trace")
app.include(path="", app=router)
Flask input¶
from flask import Blueprint, Flask
app = Flask(__name__)
api = Blueprint("api", __name__, url_prefix="/api")
@api.route("/items", endpoint="list_items", strict_slashes=False)
def list_items():
return {"items": []}
app.register_blueprint(api)
Flask Lilya output¶
from lilya.apps import Lilya as Flask
from lilya.routing import Router as Blueprint
app = Flask()
api = Blueprint()
@api.route('/api/items', name='list_items', methods=['GET'])
def list_items():
return {'items': []}
app.include(path='/', app=api)
Django URLConf input¶
from django.urls import include, path
from .views import health
urlpatterns = [
path("", health, name="health"),
path("api/", include("api.urls")),
]
Django Lilya output¶
from lilya.apps import Lilya
from lilya.routing import Include, Path
from .views import health
urlpatterns = [Path('/', health, name='health'), Include(path='/api/', app='api.urls')]
app = Lilya(routes=urlpatterns)
Litestar input¶
from litestar import Litestar, Router, get
@get("/health")
async def health() -> dict[str, bool]:
return {"ok": True}
@get("")
async def list_items() -> dict[str, list[str]]:
return {"items": []}
api = Router(path="/api", route_handlers=[list_items])
app = Litestar(route_handlers=[health, api])
Litestar Lilya output¶
from lilya.apps import Lilya as Litestar
from lilya.routing import Router, Path, Include
async def health() -> dict[str, bool]:
return {'ok': True}
async def list_items() -> dict[str, list[str]]:
return {'items': []}
api = Router(routes=[Path('/', list_items, methods=['GET'])])
app = Litestar(routes=[Path('/health', health, methods=['GET']), Include(path='/api', app=api)])
Starlette input¶
from starlette.applications import Starlette
from starlette.routing import Mount, Route
async def homepage(request):
return None
async def users(request):
return None
api = Starlette(routes=[Route("/users", users)])
routes = [Route("", homepage), Mount("/api", app=api)]
app = Starlette(debug=True, routes=routes)
app.mount("", app=api)
app.add_route("", route=homepage, methods=["GET"])
Starlette Lilya output¶
from lilya.apps import Lilya as Starlette
from lilya.routing import Include as Mount, Path as Route
async def homepage(request):
return None
async def users(request):
return None
api = Starlette(routes=[Route('/users', users)])
routes = [Route('/', homepage), Mount('/api', app=api)]
app = Starlette(debug=True, routes=routes)
app.include(path='/', app=api)
app.add_route(path='/', handler=homepage, methods=['GET'])
