pancake-framework 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pancake_framework-0.1.0/PKG-INFO +280 -0
- pancake_framework-0.1.0/README.md +240 -0
- pancake_framework-0.1.0/pancake/__init__.py +46 -0
- pancake_framework-0.1.0/pancake/builder/__init__.py +11 -0
- pancake_framework-0.1.0/pancake/builder/build.py +14 -0
- pancake_framework-0.1.0/pancake/builder/load_dlc.py +157 -0
- pancake_framework-0.1.0/pancake/builder/load_src.py +114 -0
- pancake_framework-0.1.0/pancake/builder/safe_import.py +0 -0
- pancake_framework-0.1.0/pancake/cli.py +212 -0
- pancake_framework-0.1.0/pancake/initialize/__init__.py +10 -0
- pancake_framework-0.1.0/pancake/initialize/check_dlc.py +10 -0
- pancake_framework-0.1.0/pancake/initialize/check_env.py +111 -0
- pancake_framework-0.1.0/pancake/initialize/check_struct.py +16 -0
- pancake_framework-0.1.0/pancake/initialize/print_ico.py +12 -0
- pancake_framework-0.1.0/pancake/oven/__init__.py +15 -0
- pancake_framework-0.1.0/pancake/oven/default.py +66 -0
- pancake_framework-0.1.0/pancake/oven/muffin.py +42 -0
- pancake_framework-0.1.0/pancake/oven/pancake.py +47 -0
- pancake_framework-0.1.0/pancake/ovenware/__init__.py +71 -0
- pancake_framework-0.1.0/pancake/ovenware/ai_memory.py +876 -0
- pancake_framework-0.1.0/pancake/ovenware/ai_model.py +509 -0
- pancake_framework-0.1.0/pancake/ovenware/base.py +54 -0
- pancake_framework-0.1.0/pancake/ovenware/broker.py +281 -0
- pancake_framework-0.1.0/pancake/ovenware/cui.py +228 -0
- pancake_framework-0.1.0/pancake/ovenware/embed.py +51 -0
- pancake_framework-0.1.0/pancake/ovenware/external_plugin.py +59 -0
- pancake_framework-0.1.0/pancake/ovenware/gui.py +265 -0
- pancake_framework-0.1.0/pancake/ovenware/inject.py +306 -0
- pancake_framework-0.1.0/pancake/ovenware/langgraph/__init__.py +20 -0
- pancake_framework-0.1.0/pancake/ovenware/langgraph/core.py +366 -0
- pancake_framework-0.1.0/pancake/ovenware/lifecycle.py +190 -0
- pancake_framework-0.1.0/pancake/ovenware/mybatis/__init__.py +83 -0
- pancake_framework-0.1.0/pancake/ovenware/mybatis/config.py +37 -0
- pancake_framework-0.1.0/pancake/ovenware/mybatis/connection.py +78 -0
- pancake_framework-0.1.0/pancake/ovenware/mybatis/mapper.py +509 -0
- pancake_framework-0.1.0/pancake/ovenware/mybatis/sql_parser.py +196 -0
- pancake_framework-0.1.0/pancake/ovenware/mybatis/types.py +44 -0
- pancake_framework-0.1.0/pancake/ovenware/mybatis/wrapper.py +418 -0
- pancake_framework-0.1.0/pancake/ovenware/redis_cache.py +583 -0
- pancake_framework-0.1.0/pancake/ovenware/remote.py +203 -0
- pancake_framework-0.1.0/pancake/ovenware/web.py +352 -0
- pancake_framework-0.1.0/pancake/resource/__init__.py +9 -0
- pancake_framework-0.1.0/pancake/resource/config.py +3 -0
- pancake_framework-0.1.0/pancake/resource/json.py +17 -0
- pancake_framework-0.1.0/pancake/resource/logging.py +20 -0
- pancake_framework-0.1.0/pancake/resource/xml_config.py +167 -0
- pancake_framework-0.1.0/pancake/resource/yml.py +65 -0
- pancake_framework-0.1.0/pancake/run.py +65 -0
- pancake_framework-0.1.0/pancake/settings.py +106 -0
- pancake_framework-0.1.0/pancake/tool/__init__.py +1 -0
- pancake_framework-0.1.0/pancake/tool/progress_show.py +20 -0
- pancake_framework-0.1.0/pyproject.toml +50 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: pancake_framework
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Pancake - Decorator-driven Python web framework with IoC, MyBatis ORM, and AI workflow
|
|
5
|
+
Author: drayee
|
|
6
|
+
Author-email: 1473443474@qq.com
|
|
7
|
+
Requires-Python: >=3.13,<4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Provides-Extra: ai
|
|
10
|
+
Provides-Extra: all
|
|
11
|
+
Provides-Extra: cui
|
|
12
|
+
Provides-Extra: grpc
|
|
13
|
+
Provides-Extra: gui
|
|
14
|
+
Provides-Extra: http
|
|
15
|
+
Provides-Extra: langgraph
|
|
16
|
+
Provides-Extra: redis
|
|
17
|
+
Provides-Extra: websocket
|
|
18
|
+
Requires-Dist: aiohttp (>=3.9.0,<4.0.0) ; extra == "http" or extra == "all"
|
|
19
|
+
Requires-Dist: aiosqlite (>=0.22.1,<0.23.0)
|
|
20
|
+
Requires-Dist: click (>=8.0.0,<9.0.0) ; extra == "cui" or extra == "all"
|
|
21
|
+
Requires-Dist: databases (>=0.9.0,<0.10.0)
|
|
22
|
+
Requires-Dist: fastapi (>=0.136.1,<0.137.0)
|
|
23
|
+
Requires-Dist: flet (>=0.85.0,<0.86.0) ; extra == "gui" or extra == "all"
|
|
24
|
+
Requires-Dist: google-genai (>=1.0.0,<2.0.0) ; extra == "ai" or extra == "all"
|
|
25
|
+
Requires-Dist: grpcio (>=1.60.0,<2.0.0) ; extra == "grpc" or extra == "all"
|
|
26
|
+
Requires-Dist: langgraph (>=1.1.10,<2.0.0) ; extra == "langgraph" or extra == "all"
|
|
27
|
+
Requires-Dist: openai (>=1.0.0,<2.0.0) ; extra == "ai" or extra == "all"
|
|
28
|
+
Requires-Dist: peewee (>=4.0.5,<5.0.0)
|
|
29
|
+
Requires-Dist: psycopg2-binary (>=2.9.0,<3.0.0) ; extra == "ai" or extra == "all"
|
|
30
|
+
Requires-Dist: pymongo (>=4.0.0,<5.0.0) ; extra == "ai" or extra == "all"
|
|
31
|
+
Requires-Dist: python-dotenv (>=1.2.2,<2.0.0)
|
|
32
|
+
Requires-Dist: pyyaml (>=6.0.3,<7.0.0)
|
|
33
|
+
Requires-Dist: redis (>=5.0.0,<6.0.0) ; extra == "redis" or extra == "all"
|
|
34
|
+
Requires-Dist: requests (>=2.33.1,<3.0.0)
|
|
35
|
+
Requires-Dist: tiktoken (>=0.7.0,<0.8.0) ; extra == "ai" or extra == "all"
|
|
36
|
+
Requires-Dist: uvicorn (>=0.46.0,<0.47.0)
|
|
37
|
+
Requires-Dist: websocket-client (>=1.9.0,<2.0.0) ; extra == "websocket" or extra == "all"
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
|
|
40
|
+
# Pancake Framework
|
|
41
|
+
|
|
42
|
+
> A decorator-driven Python web framework with IoC, MyBatis-style ORM, and AI workflow integration.
|
|
43
|
+
|
|
44
|
+
[中文文档](./README_CN.md)
|
|
45
|
+
|
|
46
|
+
## Features
|
|
47
|
+
|
|
48
|
+
- **Decorator-Driven** - Register services, controllers, and mappers with simple decorators
|
|
49
|
+
- **CLI Tool** - `pancake create/run/check/build` commands for project management
|
|
50
|
+
- **Auto Dependency Injection** - `@auto_inject()` automatically resolves parameters from YAML/JSON config
|
|
51
|
+
- **MyBatis Plus ORM** - Async ORM with `BaseMapper` CRUD, `@Select`/`@Insert` SQL annotations, dynamic SQL
|
|
52
|
+
- **FastAPI Web Server** - Built-in `@get_controller`/`@post_controller` decorators
|
|
53
|
+
- **IoC Container** - Singleton, transient, and scoped dependency management
|
|
54
|
+
- **LangGraph Integration** - AI workflow nodes, edges, and state graphs
|
|
55
|
+
- **Message Queue** - In-memory `SimpleBroker` and `RedisBroker` for event-driven architecture
|
|
56
|
+
- **Plugin System** - XML-managed plugin loading with init-order control
|
|
57
|
+
- **Centralized Settings** - All paths and configs managed through `settings.py`, fully user-customizable
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
|
|
61
|
+
### Install
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install pancake
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Create a Project
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pancake create myapp
|
|
71
|
+
cd myapp
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Run
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Using CLI
|
|
78
|
+
pancake run
|
|
79
|
+
|
|
80
|
+
# Or using Python
|
|
81
|
+
python main.py
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The server starts at `http://127.0.0.1:8080` by default.
|
|
85
|
+
|
|
86
|
+
### CLI Commands
|
|
87
|
+
|
|
88
|
+
| Command | Description |
|
|
89
|
+
|---------|-------------|
|
|
90
|
+
| `pancake create <name>` | Create a new project with standard structure |
|
|
91
|
+
| `pancake run` | Run the project |
|
|
92
|
+
| `pancake check` | Check project structure and environment |
|
|
93
|
+
| `pancake build` | Package project as wheel |
|
|
94
|
+
|
|
95
|
+
### Project Structure
|
|
96
|
+
|
|
97
|
+
After `pancake create myapp`:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
myapp/
|
|
101
|
+
├── main.py # Entry point: import pancake; pancake.run()
|
|
102
|
+
├── pancake.xml # Plugin & config management
|
|
103
|
+
├── pyproject.toml # Dependencies
|
|
104
|
+
└── src/
|
|
105
|
+
├── resource/
|
|
106
|
+
│ ├── yaml/ # YAML config files
|
|
107
|
+
│ └── db/ # SQLite database
|
|
108
|
+
├── mapper/ # Data access layer
|
|
109
|
+
└── controller/ # Web controllers
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Usage
|
|
113
|
+
|
|
114
|
+
### Web Controller
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
@get_controller("/hello")
|
|
118
|
+
def hello():
|
|
119
|
+
return {"message": "Hello from Pancake!"}
|
|
120
|
+
|
|
121
|
+
@post_controller("/users")
|
|
122
|
+
async def create_user(name: str, age: int, email: str):
|
|
123
|
+
return {"id": await UserMapper().insert(name=name, age=age, email=email)}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### MyBatis Plus ORM
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
@Mapper
|
|
130
|
+
class UserMapper(BaseMapper):
|
|
131
|
+
@dataclass
|
|
132
|
+
class User:
|
|
133
|
+
id: int = None
|
|
134
|
+
name: str = None
|
|
135
|
+
age: int = None
|
|
136
|
+
|
|
137
|
+
_entity_class = User
|
|
138
|
+
_table_name = "users"
|
|
139
|
+
|
|
140
|
+
@Select("SELECT * FROM users WHERE name = #{name}")
|
|
141
|
+
async def find_by_name(self, name: str) -> list[User]: ...
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Built-in CRUD: `select_by_id`, `select_list`, `select_one`, `select_count`, `insert`, `insert_batch`, `update_by_id`, `delete_by_id`.
|
|
145
|
+
|
|
146
|
+
Chain queries:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from pancake.ovenware.mybatis.wrapper import qw, uw
|
|
150
|
+
|
|
151
|
+
users = await mapper.select(qw().ge("age", 18).like("name", "%Ali%").orderByDesc("age").limit(50))
|
|
152
|
+
await mapper.update(uw().set("name", "Bob").eq("id", 1))
|
|
153
|
+
await mapper.delete(qw().lt("age", 18))
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Auto Dependency Injection
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
@auto_inject()
|
|
160
|
+
def get_config(service_title: str, service_port: int):
|
|
161
|
+
return {"title": service_title, "port": service_port}
|
|
162
|
+
|
|
163
|
+
get_config() # {"title": "My App", "port": 8080}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### IoC Container
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
container.register(UserService, UserService, Scope.SINGLETON)
|
|
170
|
+
service = container.resolve(UserService)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Event-Driven Messaging
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
@event_node(name="order_created", event="order.created")
|
|
177
|
+
async def create_order(item: str, qty: int):
|
|
178
|
+
return {"item": item, "qty": qty, "status": "created"}
|
|
179
|
+
|
|
180
|
+
@on_event("order.created")
|
|
181
|
+
async def notify_inventory(message):
|
|
182
|
+
print(f"Order received: {message}")
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Lifecycle Hooks
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
class MyService(Lifecycle):
|
|
189
|
+
async def on_init(self):
|
|
190
|
+
self.cache = {}
|
|
191
|
+
|
|
192
|
+
async def on_start(self):
|
|
193
|
+
await self.load_data()
|
|
194
|
+
|
|
195
|
+
async def on_stop(self):
|
|
196
|
+
await self.cleanup()
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Configuration
|
|
200
|
+
|
|
201
|
+
### XML Startup Config (`pancake.xml`)
|
|
202
|
+
|
|
203
|
+
```xml
|
|
204
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
205
|
+
<pancake>
|
|
206
|
+
<global>
|
|
207
|
+
<service.title>My App</service.title>
|
|
208
|
+
<service.version>1.0.0</service.version>
|
|
209
|
+
<service.host>0.0.0.0</service.host>
|
|
210
|
+
<service.port>3000</service.port>
|
|
211
|
+
<paths.yaml_dir>config/yml</paths.yaml_dir>
|
|
212
|
+
</global>
|
|
213
|
+
<plugins>
|
|
214
|
+
<plugin name="embed" init-order="0"/>
|
|
215
|
+
<plugin name="mybatis" init-order="1"/>
|
|
216
|
+
<plugin name="web" init-order="2"/>
|
|
217
|
+
<plugin name="langgraph" enabled="false"/>
|
|
218
|
+
</plugins>
|
|
219
|
+
</pancake>
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
- **`<global>`**: Config values merged into YAML config (XML takes priority)
|
|
223
|
+
- **`<plugin name="...">`**: `source` auto-derived as `ovenware.<name>` if omitted
|
|
224
|
+
- **`init-order`**: Lower loads first (default: 0)
|
|
225
|
+
- **`enabled="false"`**: Skip plugin init but still load decorators
|
|
226
|
+
- **`${env:VAR_NAME}`**: Resolved from environment variables
|
|
227
|
+
|
|
228
|
+
### Path Configuration
|
|
229
|
+
|
|
230
|
+
All paths are configurable via `pancake.xml` or YAML:
|
|
231
|
+
|
|
232
|
+
| Key | Default | Description |
|
|
233
|
+
|-----|---------|-------------|
|
|
234
|
+
| `paths.src_dir` | `src` | User code root |
|
|
235
|
+
| `paths.yaml_dir` | `src/resource/yaml` | YAML config directory |
|
|
236
|
+
| `paths.json_dir` | `src/resource/json` | JSON config directory |
|
|
237
|
+
| `paths.mapper_dir` | `src/mapper` | Mapper directory |
|
|
238
|
+
| `paths.controller_dir` | `src/controller` | Controller directory |
|
|
239
|
+
| `paths.db_dir` | `src/resource/db` | Database directory |
|
|
240
|
+
|
|
241
|
+
### Service & Database Config
|
|
242
|
+
|
|
243
|
+
| Key | Default | Description |
|
|
244
|
+
|-----|---------|-------------|
|
|
245
|
+
| `service.title` | `Pancake App` | App name |
|
|
246
|
+
| `service.version` | `1.0.0` | App version |
|
|
247
|
+
| `service.host` | `127.0.0.1` | Bind host |
|
|
248
|
+
| `service.port` | `8080` | Bind port |
|
|
249
|
+
| `mybatis.database.url` | `sqlite:///...` | Database URL |
|
|
250
|
+
| `mybatis.database.min_size` | `1` | Connection pool min |
|
|
251
|
+
| `mybatis.database.max_size` | `5` | Connection pool max |
|
|
252
|
+
|
|
253
|
+
### Environment Variables
|
|
254
|
+
|
|
255
|
+
| Variable | Description |
|
|
256
|
+
|----------|-------------|
|
|
257
|
+
| `LOG_FILE` | Log file path |
|
|
258
|
+
| `EXTERNAL_PLUGIN_DIRS` | External plugin paths (`;` or `:` separated) |
|
|
259
|
+
| `PANCAKE_AUTO_INSTALL` | Auto-install missing dependencies |
|
|
260
|
+
|
|
261
|
+
## Optional Dependencies
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
pip install pancake[langgraph] # LangGraph AI workflow
|
|
265
|
+
pip install pancake[grpc] # gRPC remote calls
|
|
266
|
+
pip install pancake[redis] # Redis message queue
|
|
267
|
+
pip install pancake[all] # All optional deps
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Running Tests
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
pip install pytest pytest-asyncio
|
|
274
|
+
python -m pytest tests/ -v
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## License
|
|
278
|
+
|
|
279
|
+
MIT
|
|
280
|
+
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# Pancake Framework
|
|
2
|
+
|
|
3
|
+
> A decorator-driven Python web framework with IoC, MyBatis-style ORM, and AI workflow integration.
|
|
4
|
+
|
|
5
|
+
[中文文档](./README_CN.md)
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Decorator-Driven** - Register services, controllers, and mappers with simple decorators
|
|
10
|
+
- **CLI Tool** - `pancake create/run/check/build` commands for project management
|
|
11
|
+
- **Auto Dependency Injection** - `@auto_inject()` automatically resolves parameters from YAML/JSON config
|
|
12
|
+
- **MyBatis Plus ORM** - Async ORM with `BaseMapper` CRUD, `@Select`/`@Insert` SQL annotations, dynamic SQL
|
|
13
|
+
- **FastAPI Web Server** - Built-in `@get_controller`/`@post_controller` decorators
|
|
14
|
+
- **IoC Container** - Singleton, transient, and scoped dependency management
|
|
15
|
+
- **LangGraph Integration** - AI workflow nodes, edges, and state graphs
|
|
16
|
+
- **Message Queue** - In-memory `SimpleBroker` and `RedisBroker` for event-driven architecture
|
|
17
|
+
- **Plugin System** - XML-managed plugin loading with init-order control
|
|
18
|
+
- **Centralized Settings** - All paths and configs managed through `settings.py`, fully user-customizable
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install pancake
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Create a Project
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pancake create myapp
|
|
32
|
+
cd myapp
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Run
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Using CLI
|
|
39
|
+
pancake run
|
|
40
|
+
|
|
41
|
+
# Or using Python
|
|
42
|
+
python main.py
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The server starts at `http://127.0.0.1:8080` by default.
|
|
46
|
+
|
|
47
|
+
### CLI Commands
|
|
48
|
+
|
|
49
|
+
| Command | Description |
|
|
50
|
+
|---------|-------------|
|
|
51
|
+
| `pancake create <name>` | Create a new project with standard structure |
|
|
52
|
+
| `pancake run` | Run the project |
|
|
53
|
+
| `pancake check` | Check project structure and environment |
|
|
54
|
+
| `pancake build` | Package project as wheel |
|
|
55
|
+
|
|
56
|
+
### Project Structure
|
|
57
|
+
|
|
58
|
+
After `pancake create myapp`:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
myapp/
|
|
62
|
+
├── main.py # Entry point: import pancake; pancake.run()
|
|
63
|
+
├── pancake.xml # Plugin & config management
|
|
64
|
+
├── pyproject.toml # Dependencies
|
|
65
|
+
└── src/
|
|
66
|
+
├── resource/
|
|
67
|
+
│ ├── yaml/ # YAML config files
|
|
68
|
+
│ └── db/ # SQLite database
|
|
69
|
+
├── mapper/ # Data access layer
|
|
70
|
+
└── controller/ # Web controllers
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Usage
|
|
74
|
+
|
|
75
|
+
### Web Controller
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
@get_controller("/hello")
|
|
79
|
+
def hello():
|
|
80
|
+
return {"message": "Hello from Pancake!"}
|
|
81
|
+
|
|
82
|
+
@post_controller("/users")
|
|
83
|
+
async def create_user(name: str, age: int, email: str):
|
|
84
|
+
return {"id": await UserMapper().insert(name=name, age=age, email=email)}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### MyBatis Plus ORM
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
@Mapper
|
|
91
|
+
class UserMapper(BaseMapper):
|
|
92
|
+
@dataclass
|
|
93
|
+
class User:
|
|
94
|
+
id: int = None
|
|
95
|
+
name: str = None
|
|
96
|
+
age: int = None
|
|
97
|
+
|
|
98
|
+
_entity_class = User
|
|
99
|
+
_table_name = "users"
|
|
100
|
+
|
|
101
|
+
@Select("SELECT * FROM users WHERE name = #{name}")
|
|
102
|
+
async def find_by_name(self, name: str) -> list[User]: ...
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Built-in CRUD: `select_by_id`, `select_list`, `select_one`, `select_count`, `insert`, `insert_batch`, `update_by_id`, `delete_by_id`.
|
|
106
|
+
|
|
107
|
+
Chain queries:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from pancake.ovenware.mybatis.wrapper import qw, uw
|
|
111
|
+
|
|
112
|
+
users = await mapper.select(qw().ge("age", 18).like("name", "%Ali%").orderByDesc("age").limit(50))
|
|
113
|
+
await mapper.update(uw().set("name", "Bob").eq("id", 1))
|
|
114
|
+
await mapper.delete(qw().lt("age", 18))
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Auto Dependency Injection
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
@auto_inject()
|
|
121
|
+
def get_config(service_title: str, service_port: int):
|
|
122
|
+
return {"title": service_title, "port": service_port}
|
|
123
|
+
|
|
124
|
+
get_config() # {"title": "My App", "port": 8080}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### IoC Container
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
container.register(UserService, UserService, Scope.SINGLETON)
|
|
131
|
+
service = container.resolve(UserService)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Event-Driven Messaging
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
@event_node(name="order_created", event="order.created")
|
|
138
|
+
async def create_order(item: str, qty: int):
|
|
139
|
+
return {"item": item, "qty": qty, "status": "created"}
|
|
140
|
+
|
|
141
|
+
@on_event("order.created")
|
|
142
|
+
async def notify_inventory(message):
|
|
143
|
+
print(f"Order received: {message}")
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Lifecycle Hooks
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
class MyService(Lifecycle):
|
|
150
|
+
async def on_init(self):
|
|
151
|
+
self.cache = {}
|
|
152
|
+
|
|
153
|
+
async def on_start(self):
|
|
154
|
+
await self.load_data()
|
|
155
|
+
|
|
156
|
+
async def on_stop(self):
|
|
157
|
+
await self.cleanup()
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Configuration
|
|
161
|
+
|
|
162
|
+
### XML Startup Config (`pancake.xml`)
|
|
163
|
+
|
|
164
|
+
```xml
|
|
165
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
166
|
+
<pancake>
|
|
167
|
+
<global>
|
|
168
|
+
<service.title>My App</service.title>
|
|
169
|
+
<service.version>1.0.0</service.version>
|
|
170
|
+
<service.host>0.0.0.0</service.host>
|
|
171
|
+
<service.port>3000</service.port>
|
|
172
|
+
<paths.yaml_dir>config/yml</paths.yaml_dir>
|
|
173
|
+
</global>
|
|
174
|
+
<plugins>
|
|
175
|
+
<plugin name="embed" init-order="0"/>
|
|
176
|
+
<plugin name="mybatis" init-order="1"/>
|
|
177
|
+
<plugin name="web" init-order="2"/>
|
|
178
|
+
<plugin name="langgraph" enabled="false"/>
|
|
179
|
+
</plugins>
|
|
180
|
+
</pancake>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
- **`<global>`**: Config values merged into YAML config (XML takes priority)
|
|
184
|
+
- **`<plugin name="...">`**: `source` auto-derived as `ovenware.<name>` if omitted
|
|
185
|
+
- **`init-order`**: Lower loads first (default: 0)
|
|
186
|
+
- **`enabled="false"`**: Skip plugin init but still load decorators
|
|
187
|
+
- **`${env:VAR_NAME}`**: Resolved from environment variables
|
|
188
|
+
|
|
189
|
+
### Path Configuration
|
|
190
|
+
|
|
191
|
+
All paths are configurable via `pancake.xml` or YAML:
|
|
192
|
+
|
|
193
|
+
| Key | Default | Description |
|
|
194
|
+
|-----|---------|-------------|
|
|
195
|
+
| `paths.src_dir` | `src` | User code root |
|
|
196
|
+
| `paths.yaml_dir` | `src/resource/yaml` | YAML config directory |
|
|
197
|
+
| `paths.json_dir` | `src/resource/json` | JSON config directory |
|
|
198
|
+
| `paths.mapper_dir` | `src/mapper` | Mapper directory |
|
|
199
|
+
| `paths.controller_dir` | `src/controller` | Controller directory |
|
|
200
|
+
| `paths.db_dir` | `src/resource/db` | Database directory |
|
|
201
|
+
|
|
202
|
+
### Service & Database Config
|
|
203
|
+
|
|
204
|
+
| Key | Default | Description |
|
|
205
|
+
|-----|---------|-------------|
|
|
206
|
+
| `service.title` | `Pancake App` | App name |
|
|
207
|
+
| `service.version` | `1.0.0` | App version |
|
|
208
|
+
| `service.host` | `127.0.0.1` | Bind host |
|
|
209
|
+
| `service.port` | `8080` | Bind port |
|
|
210
|
+
| `mybatis.database.url` | `sqlite:///...` | Database URL |
|
|
211
|
+
| `mybatis.database.min_size` | `1` | Connection pool min |
|
|
212
|
+
| `mybatis.database.max_size` | `5` | Connection pool max |
|
|
213
|
+
|
|
214
|
+
### Environment Variables
|
|
215
|
+
|
|
216
|
+
| Variable | Description |
|
|
217
|
+
|----------|-------------|
|
|
218
|
+
| `LOG_FILE` | Log file path |
|
|
219
|
+
| `EXTERNAL_PLUGIN_DIRS` | External plugin paths (`;` or `:` separated) |
|
|
220
|
+
| `PANCAKE_AUTO_INSTALL` | Auto-install missing dependencies |
|
|
221
|
+
|
|
222
|
+
## Optional Dependencies
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
pip install pancake[langgraph] # LangGraph AI workflow
|
|
226
|
+
pip install pancake[grpc] # gRPC remote calls
|
|
227
|
+
pip install pancake[redis] # Redis message queue
|
|
228
|
+
pip install pancake[all] # All optional deps
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Running Tests
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
pip install pytest pytest-asyncio
|
|
235
|
+
python -m pytest tests/ -v
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
MIT
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
disable_check = []
|
|
5
|
+
|
|
6
|
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
7
|
+
if current_dir not in sys.path:
|
|
8
|
+
sys.path.insert(0, current_dir)
|
|
9
|
+
|
|
10
|
+
_initialized = False
|
|
11
|
+
|
|
12
|
+
def init():
|
|
13
|
+
global _initialized
|
|
14
|
+
if _initialized:
|
|
15
|
+
return
|
|
16
|
+
_initialized = True
|
|
17
|
+
|
|
18
|
+
import initialize
|
|
19
|
+
initialize.print_ico()
|
|
20
|
+
|
|
21
|
+
init_rask = {"check_environment":initialize.check_environment, # 检查环境
|
|
22
|
+
"check_struct":initialize.check_struct, # 检查项目结构完整性
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
# 检查运行环境
|
|
26
|
+
print("检查运行环境")
|
|
27
|
+
import tool
|
|
28
|
+
progress = tool.ProgressBar(len(init_rask), prefix="初始化环境")
|
|
29
|
+
for task in init_rask.keys():
|
|
30
|
+
if task in disable_check:
|
|
31
|
+
continue
|
|
32
|
+
init_rask[task]()
|
|
33
|
+
progress.update(1, f"{task} 完成")
|
|
34
|
+
|
|
35
|
+
progress.finish()
|
|
36
|
+
|
|
37
|
+
# 初始化 dotenv 和 logging
|
|
38
|
+
from resource import config # noqa: F401
|
|
39
|
+
import resource.logging as resource_logging # noqa: F401
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# 延迟导入,避免循环依赖
|
|
43
|
+
def run():
|
|
44
|
+
init()
|
|
45
|
+
from .run import run as _run
|
|
46
|
+
_run()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
import pkgutil
|
|
3
|
+
|
|
4
|
+
# 当前包下的所有模块
|
|
5
|
+
for _, module_name, _ in pkgutil.iter_modules(__path__):
|
|
6
|
+
module = importlib.import_module(f".{module_name}", __name__)
|
|
7
|
+
|
|
8
|
+
for attr_name in dir(module):
|
|
9
|
+
if not attr_name.startswith('_'):
|
|
10
|
+
attr = getattr(module, attr_name)
|
|
11
|
+
globals()[f"{module_name}.{attr_name}"] = attr
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from pancake import oven
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def build():
|
|
5
|
+
|
|
6
|
+
# 构建所有服务实例
|
|
7
|
+
for classes in oven.pancake_dough["Service"]:
|
|
8
|
+
oven.pancake_pie["Service"][str(classes)] = oven.pancake_dough["Service"][classes].build()
|
|
9
|
+
|
|
10
|
+
for build_method_name in oven.muffin_egg["BuildOrder"]:
|
|
11
|
+
oven.muffin_egg["Builder"][build_method_name[0]]()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|