pico-boot 0.1.0.post0__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.
- pico_boot-0.1.0.post0/.coveragerc +17 -0
- pico_boot-0.1.0.post0/.github/workflows/ci.yml +101 -0
- pico_boot-0.1.0.post0/.github/workflows/docs.yml +104 -0
- pico_boot-0.1.0.post0/.github/workflows/publish-to-pypi.yml +35 -0
- pico_boot-0.1.0.post0/CHANGELOG.md +27 -0
- pico_boot-0.1.0.post0/LICENSE +21 -0
- pico_boot-0.1.0.post0/MANIFEST.in +18 -0
- pico_boot-0.1.0.post0/PKG-INFO +387 -0
- pico_boot-0.1.0.post0/README.md +334 -0
- pico_boot-0.1.0.post0/docs/README.md +130 -0
- pico_boot-0.1.0.post0/docs/api-reference.md +213 -0
- pico_boot-0.1.0.post0/docs/architecture.md +306 -0
- pico_boot-0.1.0.post0/docs/configuration.md +238 -0
- pico_boot-0.1.0.post0/docs/creating-plugins.md +514 -0
- pico_boot-0.1.0.post0/docs/ecosystem.md +284 -0
- pico_boot-0.1.0.post0/docs/faq.md +352 -0
- pico_boot-0.1.0.post0/docs/getting-started.md +565 -0
- pico_boot-0.1.0.post0/docs/javascripts/extra.js +10 -0
- pico_boot-0.1.0.post0/docs/plugins.md +277 -0
- pico_boot-0.1.0.post0/docs/requirements.txt +4 -0
- pico_boot-0.1.0.post0/docs/stylesheets/extra.css +53 -0
- pico_boot-0.1.0.post0/docs/troubleshooting.md +478 -0
- pico_boot-0.1.0.post0/manage.sh +65 -0
- pico_boot-0.1.0.post0/mkdocs.yml +139 -0
- pico_boot-0.1.0.post0/pyproject.toml +71 -0
- pico_boot-0.1.0.post0/setup.cfg +4 -0
- pico_boot-0.1.0.post0/src/pico_boot/__init__.py +121 -0
- pico_boot-0.1.0.post0/src/pico_boot/_version.py +1 -0
- pico_boot-0.1.0.post0/src/pico_boot.egg-info/PKG-INFO +387 -0
- pico_boot-0.1.0.post0/src/pico_boot.egg-info/SOURCES.txt +40 -0
- pico_boot-0.1.0.post0/src/pico_boot.egg-info/dependency_links.txt +1 -0
- pico_boot-0.1.0.post0/src/pico_boot.egg-info/requires.txt +9 -0
- pico_boot-0.1.0.post0/src/pico_boot.egg-info/top_level.txt +1 -0
- pico_boot-0.1.0.post0/tests/__init__.py +1 -0
- pico_boot-0.1.0.post0/tests/conftest.py +73 -0
- pico_boot-0.1.0.post0/tests/test_boot_integration.py +33 -0
- pico_boot-0.1.0.post0/tests/test_exports.py +81 -0
- pico_boot-0.1.0.post0/tests/test_init.py +465 -0
- pico_boot-0.1.0.post0/tests/test_integration.py +352 -0
- pico_boot-0.1.0.post0/tests/test_module_utils.py +146 -0
- pico_boot-0.1.0.post0/tests/test_plugin_discovery.py +190 -0
- pico_boot-0.1.0.post0/tox.ini +24 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[run]
|
|
2
|
+
branch = True
|
|
3
|
+
source =
|
|
4
|
+
pico_boot
|
|
5
|
+
omit =
|
|
6
|
+
*/_version.py
|
|
7
|
+
|
|
8
|
+
[paths]
|
|
9
|
+
pico_boot =
|
|
10
|
+
src/pico_boot
|
|
11
|
+
.tox/*/lib/*/site-packages/pico_boot
|
|
12
|
+
.tox/*/site-packages/pico_boot
|
|
13
|
+
*/site-packages/pico_boot
|
|
14
|
+
|
|
15
|
+
[report]
|
|
16
|
+
show_missing = True
|
|
17
|
+
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
name: CI & Coverage
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
tests:
|
|
11
|
+
name: Tests (Python ${{ matrix.python-version }})
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
python-version: [ "3.11", "3.12", "3.13", "3.14" ]
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout
|
|
20
|
+
uses: actions/checkout@v4
|
|
21
|
+
with:
|
|
22
|
+
fetch-depth: 0
|
|
23
|
+
|
|
24
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
25
|
+
uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: ${{ matrix.python-version }}
|
|
28
|
+
cache: pip
|
|
29
|
+
|
|
30
|
+
- name: Install tox
|
|
31
|
+
run: |
|
|
32
|
+
python -m pip install --upgrade pip
|
|
33
|
+
pip install tox
|
|
34
|
+
|
|
35
|
+
- name: Run tests with coverage (writes to repo root)
|
|
36
|
+
shell: bash
|
|
37
|
+
run: |
|
|
38
|
+
set -euxo pipefail
|
|
39
|
+
tox -e cov
|
|
40
|
+
# Rename to per-version file for artifact + merge job
|
|
41
|
+
mv .coverage .coverage.${{ matrix.python-version }}
|
|
42
|
+
ls -la .coverage.${{ matrix.python-version }}
|
|
43
|
+
|
|
44
|
+
- name: Upload .coverage artifact
|
|
45
|
+
uses: actions/upload-artifact@v4
|
|
46
|
+
with:
|
|
47
|
+
name: coverage-${{ matrix.python-version }}
|
|
48
|
+
path: .coverage.${{ matrix.python-version }}
|
|
49
|
+
include-hidden-files: true
|
|
50
|
+
if-no-files-found: error
|
|
51
|
+
|
|
52
|
+
coverage-merge:
|
|
53
|
+
name: Merge coverage
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
needs: tests
|
|
56
|
+
steps:
|
|
57
|
+
- name: Checkout (for repo context)
|
|
58
|
+
uses: actions/checkout@v4
|
|
59
|
+
|
|
60
|
+
- name: Download all coverage artifacts
|
|
61
|
+
uses: actions/download-artifact@v4
|
|
62
|
+
with:
|
|
63
|
+
path: coverage-reports
|
|
64
|
+
|
|
65
|
+
- name: Combine coverage and generate reports
|
|
66
|
+
shell: bash
|
|
67
|
+
run: |
|
|
68
|
+
set -euxo pipefail
|
|
69
|
+
python -m pip install coverage
|
|
70
|
+
files=$(find coverage-reports -type f -name ".coverage.*" -print)
|
|
71
|
+
if [ -z "$files" ]; then
|
|
72
|
+
echo "No coverage data files found"; exit 1
|
|
73
|
+
fi
|
|
74
|
+
coverage combine $files
|
|
75
|
+
coverage report -m --rcfile=.coveragerc
|
|
76
|
+
coverage xml -o coverage.xml --rcfile=.coveragerc
|
|
77
|
+
coverage html -d htmlcov --rcfile=.coveragerc
|
|
78
|
+
|
|
79
|
+
- name: Upload combined coverage XML
|
|
80
|
+
uses: actions/upload-artifact@v4
|
|
81
|
+
with:
|
|
82
|
+
name: coverage-xml
|
|
83
|
+
path: coverage.xml
|
|
84
|
+
if-no-files-found: error
|
|
85
|
+
|
|
86
|
+
- name: Upload HTML coverage report
|
|
87
|
+
uses: actions/upload-artifact@v4
|
|
88
|
+
with:
|
|
89
|
+
name: coverage-html
|
|
90
|
+
path: htmlcov
|
|
91
|
+
if-no-files-found: error
|
|
92
|
+
|
|
93
|
+
- name: Upload to Codecov
|
|
94
|
+
if: always() && !cancelled()
|
|
95
|
+
uses: codecov/codecov-action@v5
|
|
96
|
+
continue-on-error: true
|
|
97
|
+
with:
|
|
98
|
+
files: coverage.xml
|
|
99
|
+
fail_ci_if_error: false
|
|
100
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
101
|
+
slug: dperezcabrera/pico-boot
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
name: Deploy Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, master ]
|
|
6
|
+
paths:
|
|
7
|
+
- 'docs/**'
|
|
8
|
+
- 'mkdocs.yml'
|
|
9
|
+
- '.github/workflows/docs.yml'
|
|
10
|
+
pull_request:
|
|
11
|
+
branches: [ main, master ]
|
|
12
|
+
paths:
|
|
13
|
+
- 'docs/**'
|
|
14
|
+
- 'mkdocs.yml'
|
|
15
|
+
workflow_dispatch:
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
actions: read
|
|
19
|
+
contents: write
|
|
20
|
+
pages: write
|
|
21
|
+
id-token: write
|
|
22
|
+
|
|
23
|
+
concurrency:
|
|
24
|
+
group: "pages"
|
|
25
|
+
cancel-in-progress: false
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
validate:
|
|
29
|
+
if: github.event_name == 'pull_request'
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
with:
|
|
34
|
+
fetch-depth: 0
|
|
35
|
+
|
|
36
|
+
- uses: actions/setup-python@v5
|
|
37
|
+
with:
|
|
38
|
+
python-version: '3.11'
|
|
39
|
+
cache: 'pip'
|
|
40
|
+
|
|
41
|
+
- name: Install dependencies
|
|
42
|
+
run: |
|
|
43
|
+
pip install --upgrade pip
|
|
44
|
+
pip install -r docs/requirements.txt
|
|
45
|
+
|
|
46
|
+
- name: Validate documentation build
|
|
47
|
+
run: mkdocs build --strict
|
|
48
|
+
|
|
49
|
+
- name: Check for broken links (best-effort)
|
|
50
|
+
run: |
|
|
51
|
+
pip install linkchecker
|
|
52
|
+
python -m http.server --directory site 8000 &
|
|
53
|
+
sleep 3
|
|
54
|
+
linkchecker http://127.0.0.1:8000 --check-extern || true
|
|
55
|
+
|
|
56
|
+
deploy:
|
|
57
|
+
if: github.event_name != 'pull_request'
|
|
58
|
+
runs-on: ubuntu-latest
|
|
59
|
+
environment:
|
|
60
|
+
name: github-pages
|
|
61
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
62
|
+
|
|
63
|
+
steps:
|
|
64
|
+
- uses: actions/checkout@v4
|
|
65
|
+
with:
|
|
66
|
+
fetch-depth: 0
|
|
67
|
+
|
|
68
|
+
- uses: actions/setup-python@v5
|
|
69
|
+
with:
|
|
70
|
+
python-version: '3.11'
|
|
71
|
+
cache: 'pip'
|
|
72
|
+
|
|
73
|
+
- name: Install dependencies
|
|
74
|
+
run: |
|
|
75
|
+
pip install --upgrade pip
|
|
76
|
+
pip install -r docs/requirements.txt
|
|
77
|
+
|
|
78
|
+
- name: Build documentation
|
|
79
|
+
run: |
|
|
80
|
+
mkdocs build --strict --verbose
|
|
81
|
+
echo "Built on $(date -u)" > site/build-info.txt
|
|
82
|
+
echo "Commit: ${{ github.sha }}" >> site/build-info.txt
|
|
83
|
+
|
|
84
|
+
- name: Upload artifact
|
|
85
|
+
uses: actions/upload-pages-artifact@v4
|
|
86
|
+
with:
|
|
87
|
+
path: './site'
|
|
88
|
+
|
|
89
|
+
- name: Deploy to GitHub Pages
|
|
90
|
+
id: deployment
|
|
91
|
+
uses: actions/deploy-pages@v4
|
|
92
|
+
|
|
93
|
+
- name: Comment on commit (optional)
|
|
94
|
+
if: success()
|
|
95
|
+
uses: actions/github-script@v7
|
|
96
|
+
with:
|
|
97
|
+
script: |
|
|
98
|
+
github.rest.repos.createCommitComment({
|
|
99
|
+
owner: context.repo.owner,
|
|
100
|
+
repo: context.repo.repo,
|
|
101
|
+
commit_sha: context.sha,
|
|
102
|
+
body: `✅ Documentation deployed successfully!\n\n📚 View at: ${'${{ steps.deployment.outputs.page_url }}'}`
|
|
103
|
+
})
|
|
104
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Publish Python Package to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
deploy:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
id-token: write
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
with:
|
|
17
|
+
fetch-depth: 0
|
|
18
|
+
|
|
19
|
+
- name: Set up Python
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: '3.x'
|
|
23
|
+
|
|
24
|
+
- name: Install build deps
|
|
25
|
+
run: python -m pip install --upgrade pip build
|
|
26
|
+
|
|
27
|
+
- name: Build package
|
|
28
|
+
run: python -m build
|
|
29
|
+
|
|
30
|
+
- name: Publish to PyPI
|
|
31
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
32
|
+
with:
|
|
33
|
+
skip-existing: true
|
|
34
|
+
verify-metadata: true
|
|
35
|
+
attestations: false
|
|
@@ -0,0 +1,27 @@
|
|
|
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.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## [0.1.0] - 2025-02-04
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Initial release of Pico-Boot
|
|
14
|
+
- Plugin auto-discovery via `pico_boot.modules` entry points
|
|
15
|
+
- Automatic configuration file loading (YAML/JSON)
|
|
16
|
+
- Environment variable configuration support
|
|
17
|
+
- Custom scanner harvesting from modules
|
|
18
|
+
- `PICO_BOOT_AUTO_PLUGINS` environment variable to control auto-discovery
|
|
19
|
+
- `PICO_BOOT_CONFIG_FILE` environment variable for custom config path
|
|
20
|
+
- Full documentation with MkDocs Material
|
|
21
|
+
- GitHub Actions workflows (CI, docs, PyPI publish)
|
|
22
|
+
|
|
23
|
+
### Compatibility
|
|
24
|
+
- Python 3.11 - 3.14
|
|
25
|
+
- pico-ioc >= 2.1.3
|
|
26
|
+
|
|
27
|
+
[0.1.0]: https://github.com/dperezcabrera/pico-boot/releases/tag/v0.1.0
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 David Perez
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
include README.md
|
|
2
|
+
include LICENSE
|
|
3
|
+
|
|
4
|
+
recursive-include src *.py
|
|
5
|
+
|
|
6
|
+
recursive-include tests *.py
|
|
7
|
+
|
|
8
|
+
exclude .gitignore
|
|
9
|
+
exclude Dockerfile*
|
|
10
|
+
exclude docker-compose*.yml
|
|
11
|
+
exclude Makefile
|
|
12
|
+
|
|
13
|
+
prune build
|
|
14
|
+
prune dist
|
|
15
|
+
prune .tox
|
|
16
|
+
prune .pytest_cache
|
|
17
|
+
prune __pycache__
|
|
18
|
+
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pico-boot
|
|
3
|
+
Version: 0.1.0.post0
|
|
4
|
+
Summary: Pico-IOC integration layer for ecosystem modules. Auto-discovers DI modules via entry points.
|
|
5
|
+
Author-email: David Perez Cabrera <dperezcabrera@gmail.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2025 David Perez
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/dperezcabrera/pico-boot
|
|
29
|
+
Project-URL: Repository, https://github.com/dperezcabrera/pico-boot
|
|
30
|
+
Project-URL: Issue Tracker, https://github.com/dperezcabrera/pico-boot/issues
|
|
31
|
+
Keywords: ioc,di,dependency injection,boot,inversion of control,asyncio,plugins,bootstrap
|
|
32
|
+
Classifier: Development Status :: 4 - Beta
|
|
33
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
34
|
+
Classifier: Programming Language :: Python :: 3
|
|
35
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
40
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
41
|
+
Classifier: Operating System :: OS Independent
|
|
42
|
+
Requires-Python: >=3.11
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
License-File: LICENSE
|
|
45
|
+
Requires-Dist: pico-ioc>=2.2.0
|
|
46
|
+
Provides-Extra: async
|
|
47
|
+
Requires-Dist: asyncpg>=0.29.0; extra == "async"
|
|
48
|
+
Provides-Extra: test
|
|
49
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
50
|
+
Requires-Dist: pytest-asyncio>=0.23.5; extra == "test"
|
|
51
|
+
Requires-Dist: pytest-cov>=5; extra == "test"
|
|
52
|
+
Dynamic: license-file
|
|
53
|
+
|
|
54
|
+
# Pico-Boot
|
|
55
|
+
|
|
56
|
+
[](https://pypi.org/project/pico-boot/)
|
|
57
|
+
[](https://opensource.org/licenses/MIT)
|
|
58
|
+

|
|
59
|
+
[](https://codecov.io/gh/dperezcabrera/pico-boot)
|
|
60
|
+
[](https://dperezcabrera.github.io/pico-boot/)
|
|
61
|
+
|
|
62
|
+
**Zero-configuration bootstrap for the Pico ecosystem.**
|
|
63
|
+
|
|
64
|
+
Pico-Boot is a thin orchestration layer over [pico-ioc](https://github.com/dperezcabrera/pico-ioc) that provides:
|
|
65
|
+
|
|
66
|
+
- **Auto-discovery of plugins** via Python entry points
|
|
67
|
+
- **Custom scanner harvesting** from loaded modules
|
|
68
|
+
|
|
69
|
+
> 🐍 Requires Python 3.11+
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## When to Use Pico-Boot vs Pico-IoC
|
|
74
|
+
|
|
75
|
+
| Use Case | Recommendation |
|
|
76
|
+
|----------|----------------|
|
|
77
|
+
| Simple app, manual control | Use `pico-ioc` directly |
|
|
78
|
+
| Multiple pico-* integrations (fastapi, sqlalchemy, celery) | Use `pico-boot` |
|
|
79
|
+
| Want zero-config plugin discovery | Use `pico-boot` |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Installation
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pip install pico-boot
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
This automatically installs `pico-ioc` as a dependency.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Quick Start
|
|
94
|
+
|
|
95
|
+
### Basic Usage
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
# app.py
|
|
99
|
+
from pico_ioc import component, provides
|
|
100
|
+
from pico_boot import init
|
|
101
|
+
|
|
102
|
+
@component
|
|
103
|
+
class Database:
|
|
104
|
+
def query(self) -> str:
|
|
105
|
+
return "data"
|
|
106
|
+
|
|
107
|
+
@component
|
|
108
|
+
class UserService:
|
|
109
|
+
def __init__(self, db: Database):
|
|
110
|
+
self.db = db
|
|
111
|
+
|
|
112
|
+
# pico-boot's init() replaces pico-ioc's init()
|
|
113
|
+
# It auto-discovers plugins and harvests custom scanners
|
|
114
|
+
container = init(modules=[__name__])
|
|
115
|
+
|
|
116
|
+
service = container.get(UserService)
|
|
117
|
+
print(service.db.query())
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Features
|
|
123
|
+
|
|
124
|
+
### 1. Plugin Auto-Discovery
|
|
125
|
+
|
|
126
|
+
When you install a pico-* integration package, it automatically registers itself:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
pip install pico-fastapi pico-sqlalchemy pico-celery
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from pico_boot import init
|
|
134
|
+
|
|
135
|
+
# All installed pico-* plugins are automatically loaded!
|
|
136
|
+
container = init(modules=["myapp"])
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
No need to explicitly import or configure each integration.
|
|
140
|
+
|
|
141
|
+
### 2. Custom Scanner Harvesting
|
|
142
|
+
|
|
143
|
+
Modules can expose custom component scanners via `PICO_SCANNERS`:
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
# my_plugin/__init__.py
|
|
147
|
+
from pico_ioc import CustomScanner
|
|
148
|
+
|
|
149
|
+
class MyScanner(CustomScanner):
|
|
150
|
+
def scan(self, module):
|
|
151
|
+
# Custom component discovery logic
|
|
152
|
+
pass
|
|
153
|
+
|
|
154
|
+
PICO_SCANNERS = [MyScanner()]
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Pico-Boot automatically collects and applies these scanners.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Environment Variables
|
|
162
|
+
|
|
163
|
+
| Variable | Default | Description |
|
|
164
|
+
|----------|---------|-------------|
|
|
165
|
+
| `PICO_BOOT_AUTO_PLUGINS` | `true` | Enable/disable plugin auto-discovery |
|
|
166
|
+
|
|
167
|
+
### Disabling Auto-Discovery
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
export PICO_BOOT_AUTO_PLUGINS=false
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Useful for testing or when you want explicit control.
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Creating a Pico-Boot Plugin
|
|
178
|
+
|
|
179
|
+
To make your library discoverable by pico-boot, add an entry point in `pyproject.toml`:
|
|
180
|
+
|
|
181
|
+
```toml
|
|
182
|
+
[project.entry-points."pico_boot.modules"]
|
|
183
|
+
my_library = "my_library"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Example: Creating a Redis Integration
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
# pico_redis/__init__.py
|
|
190
|
+
import redis
|
|
191
|
+
from pico_ioc import provides, configured
|
|
192
|
+
from dataclasses import dataclass
|
|
193
|
+
|
|
194
|
+
@configured(prefix="redis")
|
|
195
|
+
@dataclass
|
|
196
|
+
class RedisConfig:
|
|
197
|
+
url: str = "redis://localhost:6379/0"
|
|
198
|
+
|
|
199
|
+
@provides(redis.Redis)
|
|
200
|
+
def build_redis(config: RedisConfig) -> redis.Redis:
|
|
201
|
+
return redis.Redis.from_url(config.url)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
```toml
|
|
205
|
+
# pyproject.toml
|
|
206
|
+
[project.entry-points."pico_boot.modules"]
|
|
207
|
+
pico_redis = "pico_redis"
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Now any app using pico-boot will automatically have Redis available!
|
|
211
|
+
|
|
212
|
+
For a complete guide, see the [Creating Plugins](https://dperezcabrera.github.io/pico-boot/creating-plugins/) documentation.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Complete Example
|
|
217
|
+
|
|
218
|
+
### Project Structure
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
myapp/
|
|
222
|
+
├── application.yaml
|
|
223
|
+
├── main.py
|
|
224
|
+
├── config.py
|
|
225
|
+
├── services.py
|
|
226
|
+
└── repositories.py
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### application.yaml
|
|
230
|
+
|
|
231
|
+
```yaml
|
|
232
|
+
database:
|
|
233
|
+
url: postgresql://localhost/myapp
|
|
234
|
+
|
|
235
|
+
redis:
|
|
236
|
+
url: redis://localhost:6379/0
|
|
237
|
+
|
|
238
|
+
app:
|
|
239
|
+
name: My Application
|
|
240
|
+
debug: false
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### config.py
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
from dataclasses import dataclass
|
|
247
|
+
from pico_ioc import configured
|
|
248
|
+
|
|
249
|
+
@configured(prefix="database")
|
|
250
|
+
@dataclass
|
|
251
|
+
class DatabaseConfig:
|
|
252
|
+
url: str
|
|
253
|
+
|
|
254
|
+
@configured(prefix="redis")
|
|
255
|
+
@dataclass
|
|
256
|
+
class RedisConfig:
|
|
257
|
+
url: str
|
|
258
|
+
|
|
259
|
+
@configured(prefix="app")
|
|
260
|
+
@dataclass
|
|
261
|
+
class AppConfig:
|
|
262
|
+
name: str
|
|
263
|
+
debug: bool = False
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### services.py
|
|
267
|
+
|
|
268
|
+
```python
|
|
269
|
+
from pico_ioc import component
|
|
270
|
+
from .config import AppConfig
|
|
271
|
+
|
|
272
|
+
@component
|
|
273
|
+
class GreetingService:
|
|
274
|
+
def __init__(self, config: AppConfig):
|
|
275
|
+
self.app_name = config.name
|
|
276
|
+
|
|
277
|
+
def greet(self, user: str) -> str:
|
|
278
|
+
return f"Welcome to {self.app_name}, {user}!"
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### main.py
|
|
282
|
+
|
|
283
|
+
```python
|
|
284
|
+
from pico_ioc import configuration, YamlSource, EnvSource
|
|
285
|
+
from pico_boot import init
|
|
286
|
+
from .services import GreetingService
|
|
287
|
+
|
|
288
|
+
def main():
|
|
289
|
+
# Load configuration via pico-ioc, let pico-boot discover plugins
|
|
290
|
+
config = configuration(
|
|
291
|
+
YamlSource("application.yaml"),
|
|
292
|
+
EnvSource()
|
|
293
|
+
)
|
|
294
|
+
container = init(modules=["myapp.config", "myapp.services"], config=config)
|
|
295
|
+
|
|
296
|
+
service = container.get(GreetingService)
|
|
297
|
+
print(service.greet("Alice"))
|
|
298
|
+
|
|
299
|
+
container.shutdown()
|
|
300
|
+
|
|
301
|
+
if __name__ == "__main__":
|
|
302
|
+
main()
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Running
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
$ python -m myapp.main
|
|
309
|
+
Welcome to My Application, Alice!
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Override with Environment Variables
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
$ APP_NAME="Production App" python -m myapp.main
|
|
316
|
+
Welcome to Production App, Alice!
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## API Reference
|
|
322
|
+
|
|
323
|
+
### `init(*args, **kwargs) -> PicoContainer`
|
|
324
|
+
|
|
325
|
+
Drop-in replacement for `pico_ioc.init()` with additional features:
|
|
326
|
+
|
|
327
|
+
- Auto-discovers plugins from `pico_boot.modules` entry points
|
|
328
|
+
- Harvests custom scanners (`PICO_SCANNERS`) from loaded modules
|
|
329
|
+
|
|
330
|
+
All parameters from `pico_ioc.init()` are supported:
|
|
331
|
+
|
|
332
|
+
```python
|
|
333
|
+
container = init(
|
|
334
|
+
modules=["myapp"], # Modules to scan
|
|
335
|
+
config=my_config, # Optional: custom ContextConfig
|
|
336
|
+
profiles=["prod"], # Optional: active profiles
|
|
337
|
+
overrides={Service: Mock()}, # Optional: test overrides
|
|
338
|
+
observers=[MyObserver()], # Optional: container observers
|
|
339
|
+
custom_scanners=[], # Optional: additional scanners
|
|
340
|
+
)
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Documentation
|
|
346
|
+
|
|
347
|
+
Full documentation is available at [dperezcabrera.github.io/pico-boot](https://dperezcabrera.github.io/pico-boot/).
|
|
348
|
+
|
|
349
|
+
- [Getting Started](https://dperezcabrera.github.io/pico-boot/getting-started/)
|
|
350
|
+
- [Configuration](https://dperezcabrera.github.io/pico-boot/configuration/)
|
|
351
|
+
- [Creating Plugins](https://dperezcabrera.github.io/pico-boot/creating-plugins/)
|
|
352
|
+
- [API Reference](https://dperezcabrera.github.io/pico-boot/api-reference/)
|
|
353
|
+
- [Ecosystem](https://dperezcabrera.github.io/pico-boot/ecosystem/)
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## Ecosystem
|
|
358
|
+
|
|
359
|
+
Pico-Boot works with these integration packages:
|
|
360
|
+
|
|
361
|
+
| Package | Description |
|
|
362
|
+
|---------|-------------|
|
|
363
|
+
| [pico-ioc](https://github.com/dperezcabrera/pico-ioc) | Core DI container |
|
|
364
|
+
| [pico-fastapi](https://github.com/dperezcabrera/pico-fastapi) | FastAPI integration |
|
|
365
|
+
| [pico-sqlalchemy](https://github.com/dperezcabrera/pico-sqlalchemy) | SQLAlchemy integration |
|
|
366
|
+
| [pico-celery](https://github.com/dperezcabrera/pico-celery) | Celery integration |
|
|
367
|
+
| [pico-pydantic](https://github.com/dperezcabrera/pico-pydantic) | Pydantic validation |
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Development
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
# Run tests
|
|
375
|
+
pip install tox
|
|
376
|
+
tox
|
|
377
|
+
|
|
378
|
+
# Build documentation locally
|
|
379
|
+
pip install -r docs/requirements.txt
|
|
380
|
+
mkdocs serve
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
## License
|
|
386
|
+
|
|
387
|
+
MIT - [LICENSE](./LICENSE)
|