FusionFusion

Getting Started

Install Fusion Framework for Python and write your first API

Installation

pip install fusion-framework

Scaffold a project with Fusion Tool so you get the standard layout (main.py, core/settings.py, sample products module, and environment files):

fusion init --lang python --name my-app --description "My Fusion API"
cd my-app
pip install fusion-framework

Project layout (what fusion init creates)

├── main.py                          # entrypoint — always starts the app here
├── core/
│   └── settings.py
└── src/
    └── modules/
        └── products/
            └── products.py          # sample module — edit / copy this pattern

main.py

The entrypoint imports your modules (so @route classes register), loads settings, registers optional middleware, then starts the server. Keep startup logic here — do not put listen() inside module files:

"""Entry point: register routes, middleware, and start the server."""

import src.modules.products.products  # registers @route classes

from fusion_framework.app import FusionApp
from fusion_framework.config import get_settings, load_settings_module

# Global middleware (optional). Framework ships with none by default.
MIDDLEWARE: list = []


def main() -> None:
    load_settings_module("settings")
    app = FusionApp(get_settings())
    for middleware in MIDDLEWARE:
        app.use(middleware)
    app.listen()


if __name__ == "__main__":
    main()

When you add another module, import it in main.py the same way. See Middleware and Config.

Sample products module

fusion init ships a small products API. You write handlers on a FusionBaseApi subclass and pass Swagger metadata on @route:

from fusion_framework.api import FusionBaseApi
from fusion_framework.route import route
from fusion_framework import status


@route(
    "api/[module]/",
    tags=["swagger"],
    desc="Fusion Framework Api",
    version="v1",
    deprecated=False,
)
class ProductModule(FusionBaseApi):
    """Product management module."""

    def get(self):
        return self.response({"products_id": 12}, status=status.HTTP_SUCCESS)

    def post(self):
        return self.response({"products_id": 12}, status=status.HTTP_201_CREATED)

    def delete(self):
        return self.response({"products_id": 12}, status=status.HTTP_204_NO_CONTENT)

    def patch(self):
        return self.response({"products_id": 12}, status=status.HTTP_SUCCESS)

[module] resolves from the class name (ProductModuleproduct), so this route becomes /api/product/.

Per-route Swagger options on @route:

ArgumentPurpose
tagsOpenAPI tags (grouping in Swagger UI)
descOperation / API description
titleOptional title
versionAPI version metadata
deprecatedMark the route deprecated in OpenAPI

Global Swagger UI settings (path, auth schemes, UI options) live in fusion.<env>.json — see Commands & environments.

Run it

fusion command run:dev

Then open:

Swagger is generated automatically from your @route modules. Use the UI to explore and call the sample products endpoints.

Status codes

Use the status module instead of raw integers:

from fusion_framework import status

status.HTTP_SUCCESS        # 200
status.HTTP_201_CREATED    # 201
status.HTTP_204_NO_CONTENT # 204
status.HTTP_404_NOT_FOUND  # 404
return self.response({"ok": True}, status=status.HTTP_SUCCESS)

Handlers

Implement HTTP methods as usual: get, post, put, patch, delete.

Parameter binding

Arguments are taken from the method signature. The source depends on the parameter name:

  1. If the name matches a path parameter → path
  2. Else if the method is POST / PUT / PATCH and the name appears in the JSON body → body
  3. Else if the name appears in the query string → query
  4. Missing optional parameters (default or annotation) arrive as None
from fusion_framework.api import FusionBaseApi
from fusion_framework.http import HTTPException
from fusion_framework.route import route
from fusion_framework import status


@route("api/[module]/{id}", tags=["items"], desc="Items by id")
class Items(FusionBaseApi):
    def get(self, id: int):
        return self.response({"id": id}, status=status.HTTP_SUCCESS)

    def post(self, id: int, title: str = "untitled"):
        # id ← path, title ← JSON body (optional via default)
        return self.response(
            {"id": id, "title": title},
            status=status.HTTP_201_CREATED,
        )


@route("api/[module]/", tags=["products"], desc="Products list")
class Products(FusionBaseApi):
    def get(self, id: int):
        # GET /api/products/?id=12
        if not id:
            raise HTTPException(400, {"message": "id is required"})
        return self.response({"products_id": id}, status=status.HTTP_SUCCESS)

Remember: put new modules under src/modules/... and import them from main.py. Leave app startup (load_settings_module / FusionApp / listen) only in main.py.

Details: Router.

Responses

Use self.response(body, status=status.HTTP_SUCCESS, **headers) for the response envelope. Dicts and lists are serialized as JSON by the core.

Errors

from fusion_framework.http import HTTPException

raise HTTPException(404, {"detail": "not found"})

Async handlers

@route("/")
class Root(FusionBaseApi):
    def get(self):
        return self.response({"status": "ok"}, status=status.HTTP_SUCCESS)

    async def post(self):
        return self.response({"status": "async ok"}, status=status.HTTP_SUCCESS)

Full guide: Async.

Configuration

Runtime settings come from fusion.<env>.json (FUSION_ENV, default dev). Load them in main.py with load_settings_module / get_settings.

Full guide: Config. Also see Commands & environments.

Middleware

No middleware runs by default. Register your own in main.py (MIDDLEWARE + app.use) or on @route(..., middleware=..., roles=...).

Full guide: Middleware.

Core APIs

SymbolRole
FusionBaseApiRequest view (method, path, body, headers, params, query, state) and response(...)
route(...)Register a module; Swagger metadata + optional middleware / roles
router(path)Alias of route(path) without Swagger metadata
statusHTTP status constants (HTTP_SUCCESS → 200, …)
FusionApp / app.use / listenApp + global middleware — call from main.py
load_settings_module / get_settingsLoad fusion.<env>.json + core/settings.py
HTTPExceptionRaise an HTTP error response

Under the hood, PyO3 bridges to fusion-core for routing, binding, and serialization.

On this page