fastapi-apcore 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.
- fastapi_apcore-0.1.0/PKG-INFO +476 -0
- fastapi_apcore-0.1.0/README.md +446 -0
- fastapi_apcore-0.1.0/pyproject.toml +73 -0
- fastapi_apcore-0.1.0/setup.cfg +4 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/__init__.py +89 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/cli.py +433 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/client.py +477 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/engine/__init__.py +5 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/engine/config.py +321 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/engine/context.py +106 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/engine/extensions.py +214 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/engine/observability.py +97 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/engine/registry.py +285 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/engine/serializers.py +51 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/engine/shortcuts.py +211 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/engine/tasks.py +53 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/output/__init__.py +29 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/output/registry_writer.py +132 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/output/yaml_writer.py +8 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/py.typed +0 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/scanners/__init__.py +36 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/scanners/base.py +114 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/scanners/native.py +282 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore/scanners/openapi.py +173 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore.egg-info/PKG-INFO +476 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore.egg-info/SOURCES.txt +41 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore.egg-info/dependency_links.txt +1 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore.egg-info/entry_points.txt +2 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore.egg-info/requires.txt +22 -0
- fastapi_apcore-0.1.0/src/fastapi_apcore.egg-info/top_level.txt +1 -0
- fastapi_apcore-0.1.0/tests/test_client.py +125 -0
- fastapi_apcore-0.1.0/tests/test_config.py +211 -0
- fastapi_apcore-0.1.0/tests/test_context.py +323 -0
- fastapi_apcore-0.1.0/tests/test_extensions.py +178 -0
- fastapi_apcore-0.1.0/tests/test_integration.py +112 -0
- fastapi_apcore-0.1.0/tests/test_observability.py +67 -0
- fastapi_apcore-0.1.0/tests/test_public_api.py +77 -0
- fastapi_apcore-0.1.0/tests/test_registry.py +232 -0
- fastapi_apcore-0.1.0/tests/test_scanner.py +244 -0
- fastapi_apcore-0.1.0/tests/test_serializers.py +60 -0
- fastapi_apcore-0.1.0/tests/test_shortcuts.py +125 -0
- fastapi_apcore-0.1.0/tests/test_tasks.py +78 -0
- fastapi_apcore-0.1.0/tests/test_writers.py +68 -0
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fastapi-apcore
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: FastAPI integration for apcore AI-Perceivable Core — exposes FastAPI routes as apcore modules with auto-discovery, schema extraction from Pydantic models, and OpenAPI-based scanning.
|
|
5
|
+
Author-email: aipartnerup <tercel.yi@gmail.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/aipartnerup/
|
|
8
|
+
Project-URL: Repository, https://github.com/aipartnerup/fastapi-apcore
|
|
9
|
+
Keywords: fastapi,apcore,mcp,llm,ai,tools,pydantic,schema,module,cli,auto-discovery,integration
|
|
10
|
+
Requires-Python: >=3.11
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: fastapi>=0.100
|
|
13
|
+
Requires-Dist: apcore>=0.13.0
|
|
14
|
+
Requires-Dist: apcore-toolkit>=0.2.0
|
|
15
|
+
Provides-Extra: mcp
|
|
16
|
+
Requires-Dist: apcore-mcp>=0.10.0; extra == "mcp"
|
|
17
|
+
Provides-Extra: cli
|
|
18
|
+
Requires-Dist: apcore-cli>=0.2.0; extra == "cli"
|
|
19
|
+
Requires-Dist: typer>=0.9; extra == "cli"
|
|
20
|
+
Provides-Extra: all
|
|
21
|
+
Requires-Dist: fastapi-apcore[cli,mcp]; extra == "all"
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: apdev[dev]>=0.2.3; extra == "dev"
|
|
24
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
25
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
|
|
26
|
+
Requires-Dist: httpx>=0.24; extra == "dev"
|
|
27
|
+
Requires-Dist: ruff>=0.1; extra == "dev"
|
|
28
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
29
|
+
Requires-Dist: coverage>=7.0; extra == "dev"
|
|
30
|
+
|
|
31
|
+
# fastapi-apcore
|
|
32
|
+
|
|
33
|
+
FastAPI integration for [apcore](https://github.com/aipartnerup/apcore-python) (AI-Perceivable Core). Expose your FastAPI routes as MCP tools with auto-discovery, Pydantic schema extraction, and built-in observability.
|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- **Route scanning** -- auto-discover FastAPI routes and convert them to apcore modules
|
|
38
|
+
- **Annotation inference** -- `GET` -> readonly+cacheable, `DELETE` -> destructive, `PUT` -> idempotent
|
|
39
|
+
- **Pydantic schema extraction** -- input/output schemas extracted from Pydantic models and OpenAPI spec
|
|
40
|
+
- **Two scanner backends** -- OpenAPI-based (accurate) and native route inspection (fast)
|
|
41
|
+
- **`@module` decorator** -- define standalone AI-callable modules with full schema enforcement
|
|
42
|
+
- **YAML binding** -- zero-code module definitions via external `.binding.yaml` files
|
|
43
|
+
- **MCP server** -- stdio, streamable-http, and SSE transports via `fastapi-apcore serve`
|
|
44
|
+
- **Observability** -- distributed tracing, metrics, structured logging, error history, usage tracking
|
|
45
|
+
- **Input validation** -- validate tool inputs against Pydantic schemas before execution
|
|
46
|
+
- **CLI-first workflow** -- `fastapi-apcore scan` + `fastapi-apcore serve` for zero-intrusion integration
|
|
47
|
+
- **MCP Tool Explorer** -- browser UI for inspecting modules via `--explorer`
|
|
48
|
+
- **JWT authentication** -- protect MCP endpoints with Bearer tokens via `--jwt-secret`
|
|
49
|
+
- **Approval system** -- require approval for destructive operations via `--approval`
|
|
50
|
+
- **AI enhancement** -- enrich module metadata using local SLMs via `--ai-enhance`
|
|
51
|
+
- **Async tasks** -- background task submission, status tracking, and cancellation
|
|
52
|
+
- **Unified entry point** -- `FastAPIApcore` class provides property-based access to all components
|
|
53
|
+
|
|
54
|
+
## Requirements
|
|
55
|
+
|
|
56
|
+
- Python >= 3.11
|
|
57
|
+
- FastAPI >= 0.100
|
|
58
|
+
- apcore >= 0.13.0
|
|
59
|
+
- apcore-toolkit >= 0.2.0
|
|
60
|
+
|
|
61
|
+
## Installation
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Core
|
|
65
|
+
pip install fastapi-apcore
|
|
66
|
+
|
|
67
|
+
# With MCP server support (required for serve/export)
|
|
68
|
+
pip install fastapi-apcore[mcp]
|
|
69
|
+
|
|
70
|
+
# With CLI
|
|
71
|
+
pip install fastapi-apcore[cli]
|
|
72
|
+
|
|
73
|
+
# Everything
|
|
74
|
+
pip install fastapi-apcore[all]
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Quick Start
|
|
78
|
+
|
|
79
|
+
### 1. Add FastAPIApcore to your app
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from contextlib import asynccontextmanager
|
|
83
|
+
from fastapi import FastAPI
|
|
84
|
+
from fastapi_apcore import FastAPIApcore
|
|
85
|
+
|
|
86
|
+
apcore = FastAPIApcore()
|
|
87
|
+
|
|
88
|
+
@asynccontextmanager
|
|
89
|
+
async def lifespan(app: FastAPI):
|
|
90
|
+
apcore.init_app(app) # Auto-scan routes, discover modules, start MCP server
|
|
91
|
+
yield
|
|
92
|
+
|
|
93
|
+
app = FastAPI(lifespan=lifespan)
|
|
94
|
+
|
|
95
|
+
@app.get("/greet/{name}")
|
|
96
|
+
def greet(name: str) -> dict:
|
|
97
|
+
"""Greet a user by name."""
|
|
98
|
+
return {"message": f"Hello, {name}!"}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Or use the **factory pattern**:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from fastapi import FastAPI
|
|
105
|
+
from fastapi_apcore import FastAPIApcore
|
|
106
|
+
|
|
107
|
+
apcore = FastAPIApcore()
|
|
108
|
+
|
|
109
|
+
def create_app() -> FastAPI:
|
|
110
|
+
app = FastAPI()
|
|
111
|
+
# ... add routers ...
|
|
112
|
+
apcore.init_app(app)
|
|
113
|
+
return app
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 2. Scan routes and start MCP server
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# Scan FastAPI routes -> register as apcore modules -> start MCP server
|
|
120
|
+
fastapi-apcore serve myapp.main:app --transport streamable-http --port 9090 --explorer
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
That's it. Your FastAPI routes are now MCP tools.
|
|
124
|
+
|
|
125
|
+
### 3. Connect an MCP client
|
|
126
|
+
|
|
127
|
+
For **Claude Desktop**, add to your config:
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"mcpServers": {
|
|
132
|
+
"my-fastapi-app": {
|
|
133
|
+
"command": "fastapi-apcore",
|
|
134
|
+
"args": ["serve", "myapp.main:app"]
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
For **HTTP transport** (remote access):
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
fastapi-apcore serve myapp.main:app --transport streamable-http --host 0.0.0.0 --port 9090
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Integration Paths
|
|
147
|
+
|
|
148
|
+
fastapi-apcore supports three ways to define AI-perceivable modules:
|
|
149
|
+
|
|
150
|
+
### Route Scanning (zero-intrusion)
|
|
151
|
+
|
|
152
|
+
Scan existing FastAPI routes without modifying any code:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
# Direct registration (in-memory)
|
|
156
|
+
fastapi-apcore scan myapp.main:app
|
|
157
|
+
|
|
158
|
+
# Generate YAML binding files (persistent)
|
|
159
|
+
fastapi-apcore scan myapp.main:app --output yaml --dir ./apcore_modules
|
|
160
|
+
|
|
161
|
+
# Preview without side effects
|
|
162
|
+
fastapi-apcore scan myapp.main:app --dry-run
|
|
163
|
+
|
|
164
|
+
# Filter routes by regex
|
|
165
|
+
fastapi-apcore scan myapp.main:app --include "users\." --exclude "\.delete$"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### `@module` Decorator
|
|
169
|
+
|
|
170
|
+
Define standalone modules with explicit schemas:
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
from fastapi_apcore import FastAPIApcore
|
|
174
|
+
|
|
175
|
+
apcore = FastAPIApcore()
|
|
176
|
+
|
|
177
|
+
@apcore.module(id="math.add", tags=["math"], description="Add two numbers")
|
|
178
|
+
def add(a: int, b: int) -> int:
|
|
179
|
+
return a + b
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### YAML Binding (zero-code)
|
|
183
|
+
|
|
184
|
+
Define modules via external `.binding.yaml` files in `APCORE_MODULE_DIR`:
|
|
185
|
+
|
|
186
|
+
```yaml
|
|
187
|
+
bindings:
|
|
188
|
+
- module_id: users.greet
|
|
189
|
+
target: myapp.views:greet
|
|
190
|
+
description: "Greet a user by name"
|
|
191
|
+
tags: [users]
|
|
192
|
+
input_schema:
|
|
193
|
+
properties:
|
|
194
|
+
name: { type: string }
|
|
195
|
+
required: [name]
|
|
196
|
+
output_schema:
|
|
197
|
+
properties:
|
|
198
|
+
message: { type: string }
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Unified Entry Point
|
|
202
|
+
|
|
203
|
+
The `FastAPIApcore` instance provides property-based access to all components:
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
apcore = FastAPIApcore()
|
|
207
|
+
|
|
208
|
+
# Properties (lazy-loaded singletons)
|
|
209
|
+
apcore.registry # apcore Registry
|
|
210
|
+
apcore.executor # apcore Executor (with extensions)
|
|
211
|
+
apcore.settings # ApcoreSettings
|
|
212
|
+
apcore.metrics_collector # MetricsCollector | None
|
|
213
|
+
apcore.context_factory # FastAPIContextFactory
|
|
214
|
+
apcore.task_manager # AsyncTaskManager
|
|
215
|
+
apcore.extension_manager # ExtensionManager
|
|
216
|
+
|
|
217
|
+
# Module execution
|
|
218
|
+
result = apcore.call("math.add", {"a": 1, "b": 2})
|
|
219
|
+
result = await apcore.call_async("math.add", {"a": 1, "b": 2}, request=request)
|
|
220
|
+
|
|
221
|
+
# Streaming
|
|
222
|
+
async for chunk in apcore.stream("ai.chat", {"prompt": "hello"}, request=request):
|
|
223
|
+
...
|
|
224
|
+
|
|
225
|
+
# With timeout/cancellation
|
|
226
|
+
result = apcore.cancellable_call("slow.task", timeout=30.0)
|
|
227
|
+
|
|
228
|
+
# Module introspection
|
|
229
|
+
apcore.list_modules(tags=["math"])
|
|
230
|
+
apcore.describe("math.add")
|
|
231
|
+
|
|
232
|
+
# Background tasks
|
|
233
|
+
task_id = await apcore.submit_task("batch.process", {"ids": [1, 2, 3]})
|
|
234
|
+
status = apcore.get_task_status(task_id)
|
|
235
|
+
await apcore.cancel_task(task_id)
|
|
236
|
+
|
|
237
|
+
# MCP serving
|
|
238
|
+
apcore.serve(transport="streamable-http", port=9090, explorer=True)
|
|
239
|
+
tools = apcore.to_openai_tools(strict=True)
|
|
240
|
+
|
|
241
|
+
# MCP helpers (inside module execution)
|
|
242
|
+
await FastAPIApcore.report_progress(context, progress=50, total=100)
|
|
243
|
+
response = await FastAPIApcore.elicit(context, "Please confirm")
|
|
244
|
+
|
|
245
|
+
# Singleton access
|
|
246
|
+
apcore = FastAPIApcore.get_instance()
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## `init_app()` Reference
|
|
250
|
+
|
|
251
|
+
`init_app()` performs a complete initialization sequence:
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
apcore.init_app(
|
|
255
|
+
app, # FastAPI application instance
|
|
256
|
+
scan=True, # Auto-scan routes (default: True)
|
|
257
|
+
scan_source="openapi", # Scanner backend: "openapi" or "native"
|
|
258
|
+
include=None, # Regex: only register matching module IDs
|
|
259
|
+
exclude=None, # Regex: skip matching module IDs
|
|
260
|
+
)
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**What `init_app()` does (in order):**
|
|
264
|
+
|
|
265
|
+
1. **Auto-discover** modules from YAML bindings and `APCORE_MODULE_PACKAGES`
|
|
266
|
+
2. **Scan** FastAPI routes and register them as apcore modules
|
|
267
|
+
3. **Enable hot-reload** if `APCORE_HOT_RELOAD=true`
|
|
268
|
+
4. **Start embedded MCP server** if `APCORE_EMBEDDED_SERVER` is configured
|
|
269
|
+
|
|
270
|
+
## Configuration
|
|
271
|
+
|
|
272
|
+
All settings are read from environment variables with the `APCORE_` prefix:
|
|
273
|
+
|
|
274
|
+
### Core Settings
|
|
275
|
+
|
|
276
|
+
| Variable | Default | Description |
|
|
277
|
+
|----------|---------|-------------|
|
|
278
|
+
| `APCORE_MODULE_DIR` | `apcore_modules/` | Directory for YAML binding files |
|
|
279
|
+
| `APCORE_AUTO_DISCOVER` | `true` | Auto-discover modules on startup |
|
|
280
|
+
| `APCORE_BINDING_PATTERN` | `*.binding.yaml` | Glob pattern for binding files |
|
|
281
|
+
| `APCORE_MODULE_PACKAGES` | — | Comma-separated packages to scan for `@module` |
|
|
282
|
+
| `APCORE_VALIDATE_INPUTS` | `false` | Validate inputs before module execution |
|
|
283
|
+
|
|
284
|
+
### MCP Server Settings
|
|
285
|
+
|
|
286
|
+
| Variable | Default | Description |
|
|
287
|
+
|----------|---------|-------------|
|
|
288
|
+
| `APCORE_SERVE_TRANSPORT` | `stdio` | MCP transport: `stdio`, `streamable-http`, `sse` |
|
|
289
|
+
| `APCORE_SERVE_HOST` | `127.0.0.1` | Host for HTTP transport |
|
|
290
|
+
| `APCORE_SERVE_PORT` | `9090` | Port for HTTP transport |
|
|
291
|
+
| `APCORE_SERVER_NAME` | `apcore-mcp` | MCP server name |
|
|
292
|
+
| `APCORE_SERVER_VERSION` | — | MCP server version string |
|
|
293
|
+
| `APCORE_EXPLORER_ENABLED` | `false` | Enable MCP Tool Explorer UI |
|
|
294
|
+
| `APCORE_EXPLORER_PREFIX` | `/explorer` | URL prefix for Explorer |
|
|
295
|
+
| `APCORE_EXPLORER_ALLOW_EXECUTE` | `false` | Allow execution from Explorer |
|
|
296
|
+
|
|
297
|
+
### Authentication & Security
|
|
298
|
+
|
|
299
|
+
| Variable | Default | Description |
|
|
300
|
+
|----------|---------|-------------|
|
|
301
|
+
| `APCORE_JWT_SECRET` | — | JWT secret for MCP authentication |
|
|
302
|
+
| `APCORE_JWT_ALGORITHM` | `HS256` | JWT signing algorithm |
|
|
303
|
+
| `APCORE_JWT_AUDIENCE` | — | Expected JWT audience claim |
|
|
304
|
+
| `APCORE_JWT_ISSUER` | — | Expected JWT issuer claim |
|
|
305
|
+
| `APCORE_ACL_PATH` | — | Path to ACL YAML rules file |
|
|
306
|
+
| `APCORE_MIDDLEWARES` | — | Comma-separated middleware dotted paths |
|
|
307
|
+
|
|
308
|
+
### Observability
|
|
309
|
+
|
|
310
|
+
| Variable | Default | Description |
|
|
311
|
+
|----------|---------|-------------|
|
|
312
|
+
| `APCORE_TRACING` | — | Enable tracing: `true` or JSON config |
|
|
313
|
+
| `APCORE_METRICS` | — | Enable metrics: `true` or JSON config |
|
|
314
|
+
| `APCORE_OBSERVABILITY_LOGGING` | — | Enable structured logging: `true` or JSON config |
|
|
315
|
+
|
|
316
|
+
### Task Management
|
|
317
|
+
|
|
318
|
+
| Variable | Default | Description |
|
|
319
|
+
|----------|---------|-------------|
|
|
320
|
+
| `APCORE_TASK_MAX_CONCURRENT` | `10` | Max concurrent background tasks |
|
|
321
|
+
| `APCORE_TASK_MAX_TASKS` | `1000` | Max total tasks in queue |
|
|
322
|
+
| `APCORE_TASK_CLEANUP_AGE` | `3600` | Max age (seconds) for completed tasks |
|
|
323
|
+
| `APCORE_CANCEL_DEFAULT_TIMEOUT` | — | Default cancellation timeout (seconds) |
|
|
324
|
+
|
|
325
|
+
### Advanced
|
|
326
|
+
|
|
327
|
+
| Variable | Default | Description |
|
|
328
|
+
|----------|---------|-------------|
|
|
329
|
+
| `APCORE_EXECUTOR_CONFIG` | — | JSON string for Executor configuration |
|
|
330
|
+
| `APCORE_CONTEXT_FACTORY` | — | Dotted path to custom ContextFactory class |
|
|
331
|
+
| `APCORE_HOT_RELOAD` | `false` | Watch module files for changes |
|
|
332
|
+
| `APCORE_HOT_RELOAD_PATHS` | — | Comma-separated paths to watch |
|
|
333
|
+
| `APCORE_EMBEDDED_SERVER` | — | Auto-start MCP server on init: `true` or JSON config |
|
|
334
|
+
| `APCORE_OUTPUT_FORMATTER` | — | Dotted path to output formatter function |
|
|
335
|
+
| `APCORE_AI_ENHANCE` | `false` | Enable AI metadata enhancement |
|
|
336
|
+
|
|
337
|
+
See `fastapi_apcore.ApcoreSettings` for the full list of 40 settings.
|
|
338
|
+
|
|
339
|
+
## CLI Reference
|
|
340
|
+
|
|
341
|
+
### `scan` -- Scan FastAPI routes
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
fastapi-apcore scan myapp.main:app [OPTIONS]
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
| Option | Description |
|
|
348
|
+
|--------|-------------|
|
|
349
|
+
| `--source`, `-s` | Scanner backend: `openapi` (default) or `native` |
|
|
350
|
+
| `--output`, `-o` | Output format: `yaml`. Omit for direct registration |
|
|
351
|
+
| `--dir`, `-d` | Output directory (default: `APCORE_MODULE_DIR`) |
|
|
352
|
+
| `--dry-run` | Preview without writing files or registering |
|
|
353
|
+
| `--include` | Regex: only include matching module IDs |
|
|
354
|
+
| `--exclude` | Regex: exclude matching module IDs |
|
|
355
|
+
| `--ai-enhance` | AI-enhance module metadata |
|
|
356
|
+
| `--verify` | Verify written output |
|
|
357
|
+
|
|
358
|
+
### `serve` -- Start MCP server
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
fastapi-apcore serve myapp.main:app [OPTIONS]
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
| Option | Description |
|
|
365
|
+
|--------|-------------|
|
|
366
|
+
| `--transport`, `-t` | Transport: `stdio` (default), `streamable-http`, `sse` |
|
|
367
|
+
| `--host` | Host for HTTP transport (default: `127.0.0.1`) |
|
|
368
|
+
| `--port`, `-p` | Port for HTTP transport (default: `9090`) |
|
|
369
|
+
| `--name` | MCP server name |
|
|
370
|
+
| `--explorer` | Enable MCP Tool Explorer UI |
|
|
371
|
+
| `--jwt-secret` | JWT secret key for authentication |
|
|
372
|
+
| `--approval` | Approval mode: `off`, `elicit`, `auto-approve`, `always-deny` |
|
|
373
|
+
| `--tags` | Comma-separated module tag filter |
|
|
374
|
+
| `--prefix` | Module ID prefix filter |
|
|
375
|
+
| `--validate-inputs` | Validate inputs before execution |
|
|
376
|
+
| `--output-formatter` | Dotted path to output formatter function |
|
|
377
|
+
| `--log-level` | Log level: `DEBUG`, `INFO`, `WARNING`, `ERROR` |
|
|
378
|
+
|
|
379
|
+
### `export` -- Export as OpenAI tools
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
fastapi-apcore export [OPTIONS]
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
| Option | Description |
|
|
386
|
+
|--------|-------------|
|
|
387
|
+
| `--format`, `-f` | Export format (default: `openai-tools`) |
|
|
388
|
+
| `--strict` | Add `strict: true` for Structured Outputs |
|
|
389
|
+
| `--embed-annotations` | Include annotation metadata in descriptions |
|
|
390
|
+
| `--tags` | Comma-separated module tag filter |
|
|
391
|
+
| `--prefix` | Module ID prefix filter |
|
|
392
|
+
|
|
393
|
+
### `tasks` -- Manage async tasks
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
fastapi-apcore tasks list [--status STATUS]
|
|
397
|
+
fastapi-apcore tasks cancel TASK_ID
|
|
398
|
+
fastapi-apcore tasks cleanup [--max-age SECONDS]
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## Scanning
|
|
402
|
+
|
|
403
|
+
Two scanner backends are available:
|
|
404
|
+
|
|
405
|
+
| Backend | Method | Best for |
|
|
406
|
+
|---------|--------|----------|
|
|
407
|
+
| **OpenAPI** (default) | Uses FastAPI's auto-generated OpenAPI spec | Accuracy, handles all FastAPI features |
|
|
408
|
+
| **Native** | Directly inspects `app.routes` | Speed, no OpenAPI generation overhead |
|
|
409
|
+
|
|
410
|
+
```python
|
|
411
|
+
from fastapi_apcore import get_scanner
|
|
412
|
+
|
|
413
|
+
# OpenAPI scanner (default)
|
|
414
|
+
scanner = get_scanner("openapi")
|
|
415
|
+
modules = scanner.scan(app)
|
|
416
|
+
|
|
417
|
+
# Native scanner
|
|
418
|
+
scanner = get_scanner("native")
|
|
419
|
+
modules = scanner.scan(app, include=r"users\.", exclude=r"\.delete$")
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
## Project Structure
|
|
423
|
+
|
|
424
|
+
```
|
|
425
|
+
fastapi_apcore/
|
|
426
|
+
__init__.py # Public API -- all user-facing exports
|
|
427
|
+
client.py # FastAPIApcore -- the main entry point
|
|
428
|
+
cli.py # Typer CLI (scan, serve, export, tasks)
|
|
429
|
+
engine/ # Internal engine (not for direct import)
|
|
430
|
+
config.py # ApcoreSettings -- env-based configuration
|
|
431
|
+
context.py # FastAPIContextFactory -- Request -> Identity
|
|
432
|
+
registry.py # Singleton management (Registry, Executor)
|
|
433
|
+
extensions.py # FastAPIDiscoverer + FastAPIModuleValidator
|
|
434
|
+
observability.py # Tracing/Metrics/Logging auto-setup
|
|
435
|
+
tasks.py # AsyncTaskManager singleton
|
|
436
|
+
shortcuts.py # Convenience functions
|
|
437
|
+
serializers.py # ScannedModule serialization
|
|
438
|
+
scanners/ # Route scanning backends
|
|
439
|
+
base.py # BaseScanner + ScannedModule
|
|
440
|
+
native.py # Direct route inspection
|
|
441
|
+
openapi.py # OpenAPI spec-based scanning
|
|
442
|
+
output/ # Output writers
|
|
443
|
+
registry_writer.py # Direct registry registration
|
|
444
|
+
yaml_writer.py # YAML binding file generation
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
Users only need to interact with two things:
|
|
448
|
+
- **`FastAPIApcore`** -- the unified entry point (import from `fastapi_apcore`)
|
|
449
|
+
- **CLI** -- `fastapi-apcore scan/serve/export/tasks`
|
|
450
|
+
|
|
451
|
+
Everything in `engine/` is internal wiring that `FastAPIApcore` manages automatically.
|
|
452
|
+
|
|
453
|
+
## Integration with apcore Ecosystem
|
|
454
|
+
|
|
455
|
+
fastapi-apcore bridges FastAPI to the apcore protocol:
|
|
456
|
+
|
|
457
|
+
```
|
|
458
|
+
FastAPI App -> FastAPIApcore -> apcore (Registry/Executor) -> apcore-mcp (MCP Server)
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
All apcore types are re-exported for convenience:
|
|
462
|
+
|
|
463
|
+
```python
|
|
464
|
+
from fastapi_apcore import (
|
|
465
|
+
Registry, Executor, Context, Identity, Config,
|
|
466
|
+
ACL, Middleware, ModuleAnnotations, FunctionModule,
|
|
467
|
+
CancelToken, PreflightResult, ModuleError,
|
|
468
|
+
ApprovalHandler, AutoApproveHandler, AlwaysDenyHandler,
|
|
469
|
+
EventEmitter, EventSubscriber, ApCoreEvent,
|
|
470
|
+
module, # @module decorator
|
|
471
|
+
)
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
## License
|
|
475
|
+
|
|
476
|
+
Apache-2.0
|