Pancake - Decorator-driven Python web framework with IoC, MyBatis ORM, and AI workflow
Project description
Pancake Framework
A decorator-driven Python web framework with IoC, MyBatis-style ORM, and AI workflow integration.
Features
- Decorator-Driven - Register services, controllers, and mappers with simple decorators
- CLI Tool -
pancake create/run/check/buildcommands for project management - Auto Dependency Injection -
@auto_inject()automatically resolves parameters from YAML/JSON config - MyBatis Plus ORM - Async ORM with
BaseMapperCRUD,@Select/@InsertSQL annotations, dynamic SQL - FastAPI Web Server - Built-in
@get_controller/@post_controllerdecorators - IoC Container - Singleton, transient, and scoped dependency management
- LangGraph Integration - AI workflow nodes, edges, and state graphs
- Message Queue - In-memory
SimpleBrokerandRedisBrokerfor event-driven architecture - Plugin System - XML-managed plugin loading with init-order control
- Centralized Settings - All paths and configs managed through
settings.py, fully user-customizable
Quick Start
Install
pip install pancake
Create a Project
pancake create myapp
cd myapp
Run
# Using CLI
pancake run
# Or using Python
python main.py
The server starts at http://127.0.0.1:8080 by default.
CLI Commands
| Command | Description |
|---|---|
pancake create <name> |
Create a new project with standard structure |
pancake run |
Run the project |
pancake check |
Check project structure and environment |
pancake build |
Package project as wheel |
Project Structure
After pancake create myapp:
myapp/
├── main.py # Entry point: import pancake; pancake.run()
├── pancake.xml # Plugin & config management
├── pyproject.toml # Dependencies
└── src/
├── resource/
│ ├── yaml/ # YAML config files
│ └── db/ # SQLite database
├── mapper/ # Data access layer
└── controller/ # Web controllers
Usage
Web Controller
@get_controller("/hello")
def hello():
return {"message": "Hello from Pancake!"}
@post_controller("/users")
async def create_user(name: str, age: int, email: str):
return {"id": await UserMapper().insert(name=name, age=age, email=email)}
MyBatis Plus ORM
@Mapper
class UserMapper(BaseMapper):
@dataclass
class User:
id: int = None
name: str = None
age: int = None
_entity_class = User
_table_name = "users"
@Select("SELECT * FROM users WHERE name = #{name}")
async def find_by_name(self, name: str) -> list[User]: ...
Built-in CRUD: select_by_id, select_list, select_one, select_count, insert, insert_batch, update_by_id, delete_by_id.
Chain queries:
from pancake.ovenware.mybatis.wrapper import qw, uw
users = await mapper.select(qw().ge("age", 18).like("name", "%Ali%").orderByDesc("age").limit(50))
await mapper.update(uw().set("name", "Bob").eq("id", 1))
await mapper.delete(qw().lt("age", 18))
Auto Dependency Injection
@auto_inject()
def get_config(service_title: str, service_port: int):
return {"title": service_title, "port": service_port}
get_config() # {"title": "My App", "port": 8080}
IoC Container
container.register(UserService, UserService, Scope.SINGLETON)
service = container.resolve(UserService)
Event-Driven Messaging
@event_node(name="order_created", event="order.created")
async def create_order(item: str, qty: int):
return {"item": item, "qty": qty, "status": "created"}
@on_event("order.created")
async def notify_inventory(message):
print(f"Order received: {message}")
Lifecycle Hooks
class MyService(Lifecycle):
async def on_init(self):
self.cache = {}
async def on_start(self):
await self.load_data()
async def on_stop(self):
await self.cleanup()
Configuration
XML Startup Config (pancake.xml)
<?xml version="1.0" encoding="UTF-8"?>
<pancake>
<global>
<service.title>My App</service.title>
<service.version>1.0.0</service.version>
<service.host>0.0.0.0</service.host>
<service.port>3000</service.port>
<paths.yaml_dir>config/yml</paths.yaml_dir>
</global>
<plugins>
<plugin name="embed" init-order="0"/>
<plugin name="mybatis" init-order="1"/>
<plugin name="web" init-order="2"/>
<plugin name="langgraph" enabled="false"/>
</plugins>
</pancake>
<global>: Config values merged into YAML config (XML takes priority)<plugin name="...">:sourceauto-derived asovenware.<name>if omittedinit-order: Lower loads first (default: 0)enabled="false": Skip plugin init but still load decorators${env:VAR_NAME}: Resolved from environment variables
Path Configuration
All paths are configurable via pancake.xml or YAML:
| Key | Default | Description |
|---|---|---|
paths.src_dir |
src |
User code root |
paths.yaml_dir |
src/resource/yaml |
YAML config directory |
paths.json_dir |
src/resource/json |
JSON config directory |
paths.mapper_dir |
src/mapper |
Mapper directory |
paths.controller_dir |
src/controller |
Controller directory |
paths.db_dir |
src/resource/db |
Database directory |
Service & Database Config
| Key | Default | Description |
|---|---|---|
service.title |
Pancake App |
App name |
service.version |
1.0.0 |
App version |
service.host |
127.0.0.1 |
Bind host |
service.port |
8080 |
Bind port |
mybatis.database.url |
sqlite:///... |
Database URL |
mybatis.database.min_size |
1 |
Connection pool min |
mybatis.database.max_size |
5 |
Connection pool max |
Environment Variables
| Variable | Description |
|---|---|
LOG_FILE |
Log file path |
EXTERNAL_PLUGIN_DIRS |
External plugin paths (; or : separated) |
PANCAKE_AUTO_INSTALL |
Auto-install missing dependencies |
Optional Dependencies
pip install pancake[langgraph] # LangGraph AI workflow
pip install pancake[grpc] # gRPC remote calls
pip install pancake[redis] # Redis message queue
pip install pancake[all] # All optional deps
Running Tests
pip install pytest pytest-asyncio
python -m pytest tests/ -v
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pancake_framework-0.1.0.tar.gz.
File metadata
- Download URL: pancake_framework-0.1.0.tar.gz
- Upload date:
- Size: 62.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
09a66474771d5ab5ae09f81bea07b1567f4904d22356efce27aebdbe5134bce4
|
|
| MD5 |
20f3348d2b52f4c02066f140685707e6
|
|
| BLAKE2b-256 |
e8cc67d0d587135eaa63d5a50f9ab627f0fc35859400b971c446dbd36f783d0f
|
File details
Details for the file pancake_framework-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pancake_framework-0.1.0-py3-none-any.whl
- Upload date:
- Size: 81.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb90dd55218e596cc489c3159f96cfb646927c631b0a2e88d95ee7d37b4cb789
|
|
| MD5 |
0cc14bb590dce3cf1223c6847ef8389c
|
|
| BLAKE2b-256 |
8fbcd3a4c7fc291b8c0c45797bffca597704b661c43c8f90fc57b60304fb0d5e
|