Bustan (بستان — garden) brings NestJS's architecture to Python. Modules that declare what they need and what they expose, providers resolved by a container, and controllers that stay thin.
It is not a router with decorators bolted on. The module graph is the program.
from bustan import Module, Controller, Injectable, Get
@Injectable()
class GreetingService:
def greet(self, name: str) -> str:
return f"Hello, {name}"
@Controller("/hello")
class HelloController:
def __init__(self, greetings: GreetingService) -> None:
self.greetings = greetings
@Get("/{name}")
async def hello(self, name: str) -> dict[str, str]:
return {"message": self.greetings.greet(name)}
@Module(controllers=[HelloController], providers=[GreetingService])
class AppModule:
pass
GreetingService is injected because the constructor asks for it by type. There
is no registry to update and no decorator on the parameter.
Why another framework#
Python has excellent routers. What it has less of is a convention for structure that survives a codebase growing past one file — where a new contributor can tell, from the module graph alone, what depends on what.
That is the gap Bustan aims at, and it is why the module system came before anything else.
Where to start#
| If you want to… | Go to |
|---|---|
| Build something end to end | Tutorial |
| Solve a specific problem | How-to guides |
| Look up a decorator or signature | Reference |
| Understand the design | Explanation |