Skip to content

Commit 5bbc1f8

Browse files
committed
feat: Add initial CHANGELOG.md and expand README.md with detailed usage examples, core module descriptions, and requirements.
1 parent 1d2ecbb commit 5bbc1f8

2 files changed

Lines changed: 146 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
## [0.1.0] - 2026-03-06
6+
7+
Initial release. Extracts shared framework-agnostic logic from `django-apcore`
8+
and `flask-apcore` into a standalone toolkit package.
9+
10+
### Added
11+
12+
- `ScannedModule` dataclass — canonical representation of a scanned endpoint
13+
- `BaseScanner` ABC with `filter_modules()`, `deduplicate_ids()`,
14+
`infer_annotations_from_method()`, and `extract_docstring()` utilities
15+
- `YAMLWriter` — generates `.binding.yaml` files for `apcore.BindingLoader`
16+
- `PythonWriter` — generates `@module`-decorated Python wrapper files
17+
- `RegistryWriter` — registers modules directly into `apcore.Registry`
18+
- `to_markdown()` — generic dict-to-Markdown conversion with depth control
19+
and table heuristics
20+
- `flatten_pydantic_params()` — flattens Pydantic model parameters into
21+
scalar kwargs for MCP tool invocation
22+
- `resolve_target()` — resolves `module.path:qualname` target strings
23+
- `enrich_schema_descriptions()` — merges docstring parameter descriptions
24+
into JSON Schema properties
25+
- `annotations_to_dict()` / `module_to_dict()` — serialization utilities
26+
- OpenAPI utilities: `resolve_ref()`, `resolve_schema()`,
27+
`extract_input_schema()`, `extract_output_schema()`
28+
- Output format factory via `get_writer()`
29+
- 150 tests with 94% code coverage
30+
31+
### Dependencies
32+
33+
- apcore >= 0.9.0
34+
- pydantic >= 2.0
35+
- PyYAML >= 6.0

README.md

Lines changed: 111 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# apcore-toolkit
22

3-
Shared scanner, schema extraction, and output toolkit for apcore Python framework adapters.
3+
Shared scanner, schema extraction, and output toolkit for [apcore](https://github.com/aipartnerup/apcore-python) Python framework adapters.
44

55
Extracts ~1,400 lines of duplicated framework-agnostic logic from `django-apcore` and `flask-apcore` into a standalone Python package.
66

@@ -10,12 +10,118 @@ Extracts ~1,400 lines of duplicated framework-agnostic logic from `django-apcore
1010
pip install apcore-toolkit
1111
```
1212

13+
## Core Modules
14+
15+
| Module | Description |
16+
|--------|-------------|
17+
| `ScannedModule` | Canonical dataclass representing a scanned endpoint |
18+
| `BaseScanner` | Abstract base class for framework scanners with filtering and deduplication |
19+
| `YAMLWriter` | Generates `.binding.yaml` files for `apcore.BindingLoader` |
20+
| `PythonWriter` | Generates `@module`-decorated Python wrapper files |
21+
| `RegistryWriter` | Registers modules directly into an `apcore.Registry` |
22+
| `to_markdown` | Converts arbitrary dicts to Markdown with depth control and table heuristics |
23+
1324
## Usage
1425

26+
### Scanning and Writing
27+
28+
```python
29+
from apcore_toolkit import BaseScanner, ScannedModule, YAMLWriter
30+
31+
class MyScanner(BaseScanner):
32+
def scan(self, **kwargs):
33+
# Scan your framework endpoints and return ScannedModule instances
34+
return [
35+
ScannedModule(
36+
module_id="users.get_user",
37+
description="Get a user by ID",
38+
input_schema={"type": "object", "properties": {"id": {"type": "integer"}}, "required": ["id"]},
39+
output_schema={"type": "object", "properties": {"name": {"type": "string"}}},
40+
tags=["users"],
41+
target="myapp.views:get_user",
42+
)
43+
]
44+
45+
def get_source_name(self):
46+
return "my-framework"
47+
48+
scanner = MyScanner()
49+
modules = scanner.scan()
50+
51+
# Filter and deduplicate
52+
modules = scanner.filter_modules(modules, include=r"^users\.")
53+
modules = scanner.deduplicate_ids(modules)
54+
55+
# Write YAML binding files
56+
writer = YAMLWriter()
57+
writer.write(modules, output_dir="./bindings")
58+
```
59+
60+
### Direct Registry Registration
61+
62+
```python
63+
from apcore import Registry
64+
from apcore_toolkit import RegistryWriter
65+
66+
registry = Registry()
67+
writer = RegistryWriter()
68+
writer.write(modules, registry)
69+
```
70+
71+
### Output Format Factory
72+
1573
```python
16-
from apcore_toolkit import ScannedModule, BaseScanner, YAMLWriter, PythonWriter
17-
from apcore_toolkit import flatten_pydantic_params, resolve_target
18-
from apcore_toolkit.openapi import resolve_ref, extract_input_schema, extract_output_schema
19-
from apcore_toolkit.serializers import module_to_dict, modules_to_dicts
2074
from apcore_toolkit.output import get_writer
75+
76+
writer = get_writer("yaml") # YAMLWriter
77+
writer = get_writer("python") # PythonWriter
78+
writer = get_writer("registry") # RegistryWriter
2179
```
80+
81+
### Pydantic Model Flattening
82+
83+
```python
84+
from apcore_toolkit import flatten_pydantic_params, resolve_target
85+
86+
# Resolve a target string to a callable
87+
func = resolve_target("myapp.views:create_task")
88+
89+
# Flatten Pydantic model params into scalar kwargs for MCP tools
90+
wrapped = flatten_pydantic_params(func)
91+
```
92+
93+
### OpenAPI Schema Extraction
94+
95+
```python
96+
from apcore_toolkit.openapi import extract_input_schema, extract_output_schema
97+
98+
input_schema = extract_input_schema(operation, openapi_doc)
99+
output_schema = extract_output_schema(operation, openapi_doc)
100+
```
101+
102+
### Schema Enrichment
103+
104+
```python
105+
from apcore_toolkit import enrich_schema_descriptions
106+
107+
enriched = enrich_schema_descriptions(schema, {"user_id": "The user ID"})
108+
```
109+
110+
### Markdown Formatting
111+
112+
```python
113+
from apcore_toolkit import to_markdown
114+
115+
md = to_markdown({"name": "Alice", "role": "admin"}, title="User Info")
116+
```
117+
118+
## Requirements
119+
120+
- Python >= 3.11
121+
- apcore >= 0.9.0
122+
- pydantic >= 2.0
123+
- PyYAML >= 6.0
124+
125+
## License
126+
127+
Apache-2.0

0 commit comments

Comments
 (0)