django-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.
- django_apcore-0.1.0/.code-forge.json +41 -0
- django_apcore-0.1.0/.github/workflows/ci.yml +31 -0
- django_apcore-0.1.0/.gitignore +17 -0
- django_apcore-0.1.0/.gitmessage +60 -0
- django_apcore-0.1.0/.pre-commit-config.yaml +27 -0
- django_apcore-0.1.0/CHANGELOG.md +90 -0
- django_apcore-0.1.0/PKG-INFO +538 -0
- django_apcore-0.1.0/README.md +498 -0
- django_apcore-0.1.0/docs/django-apcore/prd.md +955 -0
- django_apcore-0.1.0/docs/django-apcore/tech-design.md +886 -0
- django_apcore-0.1.0/docs/django-apcore/upstream-sdk-analysis.md +136 -0
- django_apcore-0.1.0/example/.env.example +15 -0
- django_apcore-0.1.0/example/.gitignore +1 -0
- django_apcore-0.1.0/example/Dockerfile +13 -0
- django_apcore-0.1.0/example/README.md +153 -0
- django_apcore-0.1.0/example/conftest.py +48 -0
- django_apcore-0.1.0/example/db.sqlite3 +0 -0
- django_apcore-0.1.0/example/demo/__init__.py +0 -0
- django_apcore-0.1.0/example/demo/apcore_modules/__init__.py +9 -0
- django_apcore-0.1.0/example/demo/apcore_modules/api.tasks.create.binding.yaml +35 -0
- django_apcore-0.1.0/example/demo/apcore_modules/api.tasks.delete.binding.yaml +23 -0
- django_apcore-0.1.0/example/demo/apcore_modules/api.tasks.get.binding.yaml +29 -0
- django_apcore-0.1.0/example/demo/apcore_modules/api.tasks.list.binding.yaml +27 -0
- django_apcore-0.1.0/example/demo/apcore_modules/api.tasks.update.binding.yaml +38 -0
- django_apcore-0.1.0/example/demo/apcore_modules/task_stats.py +11 -0
- django_apcore-0.1.0/example/demo/api.py +118 -0
- django_apcore-0.1.0/example/demo/settings.py +54 -0
- django_apcore-0.1.0/example/demo/urls.py +7 -0
- django_apcore-0.1.0/example/docker-compose.yml +22 -0
- django_apcore-0.1.0/example/entrypoint.sh +9 -0
- django_apcore-0.1.0/example/manage.py +20 -0
- django_apcore-0.1.0/example/tests/__init__.py +0 -0
- django_apcore-0.1.0/example/tests/test_demo.py +222 -0
- django_apcore-0.1.0/ideas/django-apcore/draft.md +162 -0
- django_apcore-0.1.0/ideas/django-apcore/research/competitive-analysis.md +595 -0
- django_apcore-0.1.0/ideas/django-apcore/research/market-notes.md +72 -0
- django_apcore-0.1.0/ideas/django-apcore/state.json +15 -0
- django_apcore-0.1.0/planning/django-apcore/overview.md +88 -0
- django_apcore-0.1.0/planning/django-apcore/plan.md +178 -0
- django_apcore-0.1.0/planning/django-apcore/state.json +159 -0
- django_apcore-0.1.0/planning/django-apcore/tasks/001-setup.md +298 -0
- django_apcore-0.1.0/planning/django-apcore/tasks/002-settings.md +363 -0
- django_apcore-0.1.0/planning/django-apcore/tasks/003-registry.md +174 -0
- django_apcore-0.1.0/planning/django-apcore/tasks/004-app-config.md +302 -0
- django_apcore-0.1.0/planning/django-apcore/tasks/005-scanner-base.md +417 -0
- django_apcore-0.1.0/planning/django-apcore/tasks/006-output-writers.md +612 -0
- django_apcore-0.1.0/planning/django-apcore/tasks/007-ninja-scanner.md +500 -0
- django_apcore-0.1.0/planning/django-apcore/tasks/008-drf-scanner.md +550 -0
- django_apcore-0.1.0/planning/django-apcore/tasks/009-scan-command.md +475 -0
- django_apcore-0.1.0/planning/django-apcore/tasks/010-serve-command.md +462 -0
- django_apcore-0.1.0/planning/overview.md +23 -0
- django_apcore-0.1.0/pyproject.toml +76 -0
- django_apcore-0.1.0/ruff.toml +14 -0
- django_apcore-0.1.0/src/django_apcore/__init__.py +3 -0
- django_apcore-0.1.0/src/django_apcore/apps.py +92 -0
- django_apcore-0.1.0/src/django_apcore/context.py +98 -0
- django_apcore-0.1.0/src/django_apcore/extensions.py +381 -0
- django_apcore-0.1.0/src/django_apcore/management/__init__.py +0 -0
- django_apcore-0.1.0/src/django_apcore/management/commands/__init__.py +0 -0
- django_apcore-0.1.0/src/django_apcore/management/commands/apcore_export.py +90 -0
- django_apcore-0.1.0/src/django_apcore/management/commands/apcore_scan.py +169 -0
- django_apcore-0.1.0/src/django_apcore/management/commands/apcore_serve.py +344 -0
- django_apcore-0.1.0/src/django_apcore/management/commands/apcore_tasks.py +101 -0
- django_apcore-0.1.0/src/django_apcore/output/__init__.py +31 -0
- django_apcore-0.1.0/src/django_apcore/output/python_writer.py +187 -0
- django_apcore-0.1.0/src/django_apcore/output/yaml_writer.py +101 -0
- django_apcore-0.1.0/src/django_apcore/registry.py +369 -0
- django_apcore-0.1.0/src/django_apcore/scanners/__init__.py +36 -0
- django_apcore-0.1.0/src/django_apcore/scanners/base.py +193 -0
- django_apcore-0.1.0/src/django_apcore/scanners/drf.py +192 -0
- django_apcore-0.1.0/src/django_apcore/scanners/ninja.py +289 -0
- django_apcore-0.1.0/src/django_apcore/settings.py +628 -0
- django_apcore-0.1.0/src/django_apcore/shortcuts.py +317 -0
- django_apcore-0.1.0/src/django_apcore/tasks.py +75 -0
- django_apcore-0.1.0/tests/__init__.py +0 -0
- django_apcore-0.1.0/tests/conftest.py +3 -0
- django_apcore-0.1.0/tests/integration/__init__.py +0 -0
- django_apcore-0.1.0/tests/integration/test_registry_serve.py +108 -0
- django_apcore-0.1.0/tests/settings.py +16 -0
- django_apcore-0.1.0/tests/test_app.py +371 -0
- django_apcore-0.1.0/tests/test_commands.py +356 -0
- django_apcore-0.1.0/tests/test_context.py +207 -0
- django_apcore-0.1.0/tests/test_embedded_server.py +149 -0
- django_apcore-0.1.0/tests/test_example_project.py +165 -0
- django_apcore-0.1.0/tests/test_executor.py +401 -0
- django_apcore-0.1.0/tests/test_explorer.py +292 -0
- django_apcore-0.1.0/tests/test_export_command.py +165 -0
- django_apcore-0.1.0/tests/test_extensions.py +242 -0
- django_apcore-0.1.0/tests/test_init.py +21 -0
- django_apcore-0.1.0/tests/test_python_writer.py +184 -0
- django_apcore-0.1.0/tests/test_registry.py +170 -0
- django_apcore-0.1.0/tests/test_scanner_base.py +415 -0
- django_apcore-0.1.0/tests/test_scanner_drf.py +277 -0
- django_apcore-0.1.0/tests/test_scanner_ninja.py +318 -0
- django_apcore-0.1.0/tests/test_serve_command.py +409 -0
- django_apcore-0.1.0/tests/test_settings.py +709 -0
- django_apcore-0.1.0/tests/test_shortcuts.py +542 -0
- django_apcore-0.1.0/tests/test_tasks.py +191 -0
- django_apcore-0.1.0/tests/test_yaml_writer.py +146 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0",
|
|
3
|
+
"project": "django-apcore",
|
|
4
|
+
"description": "Django App that bridges the apcore (AI-Perceivable Core) protocol to the Django ecosystem",
|
|
5
|
+
"input": {
|
|
6
|
+
"base_path": "docs/django-apcore/",
|
|
7
|
+
"documents": [
|
|
8
|
+
"tech-design.md",
|
|
9
|
+
"prd.md"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"output": {
|
|
13
|
+
"base_path": "planning/",
|
|
14
|
+
"features": [
|
|
15
|
+
{
|
|
16
|
+
"name": "django-apcore",
|
|
17
|
+
"path": "planning/django-apcore/",
|
|
18
|
+
"plan": "planning/django-apcore/plan.md",
|
|
19
|
+
"overview": "planning/django-apcore/overview.md",
|
|
20
|
+
"state": "planning/django-apcore/state.json",
|
|
21
|
+
"tasks_dir": "planning/django-apcore/tasks/"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"settings": {
|
|
26
|
+
"tdd_mode": "strict",
|
|
27
|
+
"granularity": "fine",
|
|
28
|
+
"task_count": 10,
|
|
29
|
+
"estimated_hours_per_task": "2-4",
|
|
30
|
+
"tech_stack": {
|
|
31
|
+
"language": "python",
|
|
32
|
+
"language_version": "3.10+",
|
|
33
|
+
"framework": "django",
|
|
34
|
+
"framework_version": "4.2+",
|
|
35
|
+
"testing": "pytest + pytest-django",
|
|
36
|
+
"linting": "ruff",
|
|
37
|
+
"type_checking": "mypy",
|
|
38
|
+
"build": "hatchling"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
pull_request:
|
|
6
|
+
branches: [main]
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
lint:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: "3.12"
|
|
16
|
+
- run: pip install -e ".[all,dev]"
|
|
17
|
+
- run: ruff check src/ tests/
|
|
18
|
+
|
|
19
|
+
test:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
strategy:
|
|
22
|
+
matrix:
|
|
23
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
24
|
+
django-version: ["4.2", "5.0", "5.1"]
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
- uses: actions/setup-python@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: ${{ matrix.python-version }}
|
|
30
|
+
- run: pip install -e ".[all,dev]" django~=${{ matrix.django-version }}
|
|
31
|
+
- run: pytest tests/ -x --tb=short --ignore=tests/test_example_project.py
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# <type>(<scope>): <subject>
|
|
2
|
+
#
|
|
3
|
+
# <body>
|
|
4
|
+
#
|
|
5
|
+
# <footer>
|
|
6
|
+
|
|
7
|
+
# Type must be one of the following:
|
|
8
|
+
# feat: A new feature
|
|
9
|
+
# fix: A bug fix
|
|
10
|
+
# docs: Documentation only changes
|
|
11
|
+
# style: Changes that do not affect the meaning of the code
|
|
12
|
+
# refactor: A code change that neither fixes a bug nor adds a feature
|
|
13
|
+
# perf: A code change that improves performance
|
|
14
|
+
# test: Adding missing tests or correcting existing tests
|
|
15
|
+
# chore: Changes to the build process or auxiliary tools
|
|
16
|
+
# ci: Changes to CI configuration files and scripts
|
|
17
|
+
|
|
18
|
+
# Scope is optional and can be anything specifying the place of the commit change.
|
|
19
|
+
# Examples: api, core, storage, cli, stdio, etc.
|
|
20
|
+
|
|
21
|
+
# Subject should be:
|
|
22
|
+
# - Use imperative, present tense: "change" not "changed" nor "changes"
|
|
23
|
+
# - Don't capitalize first letter
|
|
24
|
+
# - No dot (.) at the end
|
|
25
|
+
# - Maximum 72 characters
|
|
26
|
+
|
|
27
|
+
# Body should include:
|
|
28
|
+
# - Motivation for the change and contrast with previous behavior
|
|
29
|
+
# - What changed and why
|
|
30
|
+
# - Any breaking changes
|
|
31
|
+
|
|
32
|
+
# Footer should contain:
|
|
33
|
+
# - Breaking changes (start with BREAKING CHANGE:)
|
|
34
|
+
# - Issue references (Closes #123, Fixes #456)
|
|
35
|
+
|
|
36
|
+
# Examples:
|
|
37
|
+
# feat(stdio): add stdio executor for process execution
|
|
38
|
+
#
|
|
39
|
+
# Implement a new stdio executor that allows executing system commands
|
|
40
|
+
# and processes via stdin/stdout communication, similar to MCP stdio
|
|
41
|
+
# transport mode. This enables flexible task execution through shell
|
|
42
|
+
# commands and Python scripts.
|
|
43
|
+
#
|
|
44
|
+
# - Add StdioExecutor class with command execution support
|
|
45
|
+
# - Add system resource monitoring (CPU, memory, disk)
|
|
46
|
+
# - Support async process communication
|
|
47
|
+
# - Add comprehensive error handling and logging
|
|
48
|
+
#
|
|
49
|
+
# Closes #123
|
|
50
|
+
|
|
51
|
+
# refactor(core): extract shared types to core.types module
|
|
52
|
+
#
|
|
53
|
+
# Move common type definitions from various modules to a centralized
|
|
54
|
+
# core.types module to avoid circular dependencies and improve code
|
|
55
|
+
# organization.
|
|
56
|
+
#
|
|
57
|
+
# - Add TaskPreHook and TaskPostHook type aliases
|
|
58
|
+
# - Move TaskStatus enum to core.types
|
|
59
|
+
# - Update imports across affected modules
|
|
60
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
|
|
3
|
+
# apdev hooks
|
|
4
|
+
- repo: local
|
|
5
|
+
hooks:
|
|
6
|
+
- id: check-chars
|
|
7
|
+
name: apdev check-chars
|
|
8
|
+
entry: apdev check-chars
|
|
9
|
+
language: system
|
|
10
|
+
types_or: [text, python]
|
|
11
|
+
|
|
12
|
+
- id: check-imports
|
|
13
|
+
name: apdev check-imports
|
|
14
|
+
entry: apdev check-imports
|
|
15
|
+
language: system
|
|
16
|
+
pass_filenames: false
|
|
17
|
+
always_run: true
|
|
18
|
+
|
|
19
|
+
# Ruff linter and formatter
|
|
20
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
21
|
+
rev: v0.8.4
|
|
22
|
+
hooks:
|
|
23
|
+
- id: ruff
|
|
24
|
+
args: [--fix]
|
|
25
|
+
files: ^(src|tests)/
|
|
26
|
+
- id: ruff-format
|
|
27
|
+
files: ^(src|tests)/
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-02-23
|
|
9
|
+
|
|
10
|
+
Initial public release of django-apcore — a Django app that bridges the apcore protocol to Django, enabling existing REST APIs to be served as MCP tools for AI agents.
|
|
11
|
+
|
|
12
|
+
### Core
|
|
13
|
+
|
|
14
|
+
- Django `AppConfig` with Extension-First startup flow
|
|
15
|
+
- `Registry` and `Executor` singletons via `ExtensionManager.apply()` auto-assembly
|
|
16
|
+
- `ExtensionManager` integration with 5 extension points: discoverer, middleware, acl, span_exporter, module_validator
|
|
17
|
+
- `DjangoDiscoverer` — discovers modules from YAML bindings and `@module`-decorated functions in `INSTALLED_APPS`
|
|
18
|
+
- `DjangoModuleValidator` — validates module IDs against reserved words and length limits
|
|
19
|
+
- Auto-discovery of apcore modules on Django startup
|
|
20
|
+
|
|
21
|
+
### Management Commands
|
|
22
|
+
|
|
23
|
+
- `apcore_serve` — start MCP server (stdio/streamable-http/sse) with metrics, input validation, and tag/prefix filtering
|
|
24
|
+
- `apcore_scan` — scan django-ninja and DRF endpoints to generate apcore module definitions
|
|
25
|
+
- `apcore_export` — export registered modules as OpenAI-compatible tool definitions
|
|
26
|
+
- `apcore_tasks` — list, cancel, and clean up async tasks
|
|
27
|
+
|
|
28
|
+
### Scanners
|
|
29
|
+
|
|
30
|
+
- `NinjaScanner` — scans django-ninja APIs via Pydantic schemas
|
|
31
|
+
- `DRFScanner` — scans DRF APIs via drf-spectacular OpenAPI generation
|
|
32
|
+
- Include/exclude pattern filtering for endpoint selection
|
|
33
|
+
- Deduplication of scanned modules
|
|
34
|
+
|
|
35
|
+
### Output Writers
|
|
36
|
+
|
|
37
|
+
- `YAMLWriter` — generates `*.binding.yaml` module definition files
|
|
38
|
+
- `PythonWriter` — generates Python module files with `@module` decorators
|
|
39
|
+
- Dry-run mode for previewing output without writing files
|
|
40
|
+
|
|
41
|
+
### Shortcuts
|
|
42
|
+
|
|
43
|
+
- `executor_call` / `executor_call_async` — sync and async module execution
|
|
44
|
+
- `executor_stream` — streaming module execution
|
|
45
|
+
- `cancellable_call` / `cancellable_call_async` — execution with `CancelToken` and optional timeout
|
|
46
|
+
- `submit_task` / `get_task_status` / `cancel_task` — async task management
|
|
47
|
+
- `report_progress` — MCP progress reporting
|
|
48
|
+
- `elicit` — MCP user input elicitation
|
|
49
|
+
|
|
50
|
+
### Django Context
|
|
51
|
+
|
|
52
|
+
- `DjangoContextFactory` — creates apcore `Context` from Django `HttpRequest`
|
|
53
|
+
- `Identity` mapping from `request.user` with group-based roles (as `tuple`)
|
|
54
|
+
- W3C TraceContext extraction from `traceparent` HTTP header
|
|
55
|
+
|
|
56
|
+
### Observability
|
|
57
|
+
|
|
58
|
+
- Configurable logging via `APCORE_OBSERVABILITY_LOGGING`
|
|
59
|
+
- Tracing with pluggable span exporters (stdout, in-memory, OTLP)
|
|
60
|
+
- `MetricsCollector` integration for Prometheus `/metrics` endpoint
|
|
61
|
+
- Sampling strategies configurable via `APCORE_TRACING`
|
|
62
|
+
|
|
63
|
+
### Middleware & ACL
|
|
64
|
+
|
|
65
|
+
- Pluggable middleware pipeline via `APCORE_MIDDLEWARES` setting
|
|
66
|
+
- YAML-based ACL loaded from `APCORE_ACL_PATH`
|
|
67
|
+
- Middleware and ACL registered as apcore extensions
|
|
68
|
+
|
|
69
|
+
### Embedded Server
|
|
70
|
+
|
|
71
|
+
- Optional embedded MCP server started alongside Django via `APCORE_EMBEDDED_SERVER`
|
|
72
|
+
- Non-blocking startup with configurable transport and host/port
|
|
73
|
+
|
|
74
|
+
### Configuration
|
|
75
|
+
|
|
76
|
+
- 30+ `APCORE_*` Django settings with type validation and sensible defaults
|
|
77
|
+
- Settings include: module discovery, server transport, middleware pipeline, ACL, tracing, metrics, task management, hot-reload, embedded server, and module filtering
|
|
78
|
+
|
|
79
|
+
### Example Project
|
|
80
|
+
|
|
81
|
+
- Docker Compose demo with web + MCP services
|
|
82
|
+
- Sample apcore modules (hello, math_tools, slow_task)
|
|
83
|
+
- Integration test suite for the example project
|
|
84
|
+
|
|
85
|
+
### Testing
|
|
86
|
+
|
|
87
|
+
- 393 tests across 20 test files
|
|
88
|
+
- Unit tests for all components (settings, extensions, context, registry, shortcuts, tasks, scanners, writers, commands)
|
|
89
|
+
- Integration tests for the full Extension-First pipeline
|
|
90
|
+
- Async test support via pytest-asyncio
|