pico-boot 0.1.0.post0__py3-none-any.whl
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/__init__.py +121 -0
- pico_boot/_version.py +1 -0
- pico_boot-0.1.0.post0.dist-info/METADATA +387 -0
- pico_boot-0.1.0.post0.dist-info/RECORD +7 -0
- pico_boot-0.1.0.post0.dist-info/WHEEL +5 -0
- pico_boot-0.1.0.post0.dist-info/licenses/LICENSE +21 -0
- pico_boot-0.1.0.post0.dist-info/top_level.txt +1 -0
pico_boot/__init__.py
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
import os
|
|
3
|
+
from importlib import import_module
|
|
4
|
+
from importlib.metadata import entry_points
|
|
5
|
+
from types import ModuleType
|
|
6
|
+
from typing import Any, Iterable, List, TYPE_CHECKING, Union
|
|
7
|
+
|
|
8
|
+
KeyT = Union[str, type]
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from typing import Dict, Optional, Tuple
|
|
12
|
+
from pico_ioc import PicoContainer, ContextConfig
|
|
13
|
+
from pico_ioc import init as init, ContainerObserver
|
|
14
|
+
else:
|
|
15
|
+
from typing import Dict, Optional, Tuple
|
|
16
|
+
import logging
|
|
17
|
+
from pico_ioc import PicoContainer, ContextConfig
|
|
18
|
+
from pico_ioc import init as _ioc_init, ContainerObserver
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
def _to_module_list(modules: Union[Any, Iterable[Any]]) -> List[Any]:
|
|
23
|
+
if isinstance(modules, Iterable) and not isinstance(modules, (str, bytes)):
|
|
24
|
+
return list(modules)
|
|
25
|
+
return [modules]
|
|
26
|
+
|
|
27
|
+
def _import_module_like(obj: Any) -> ModuleType:
|
|
28
|
+
if isinstance(obj, ModuleType):
|
|
29
|
+
return obj
|
|
30
|
+
if isinstance(obj, str):
|
|
31
|
+
return import_module(obj)
|
|
32
|
+
module_name = getattr(obj, "__module__", None) or getattr(obj, "__name__", None)
|
|
33
|
+
if not module_name:
|
|
34
|
+
raise ImportError(f"Cannot determine module for object {obj!r}")
|
|
35
|
+
return import_module(module_name)
|
|
36
|
+
|
|
37
|
+
def _normalize_modules(raw: Iterable[Any]) -> List[ModuleType]:
|
|
38
|
+
seen: set[str] = set()
|
|
39
|
+
result: List[ModuleType] = []
|
|
40
|
+
for item in raw:
|
|
41
|
+
m = _import_module_like(item)
|
|
42
|
+
name = m.__name__
|
|
43
|
+
if name not in seen:
|
|
44
|
+
seen.add(name)
|
|
45
|
+
result.append(m)
|
|
46
|
+
return result
|
|
47
|
+
|
|
48
|
+
def _harvest_scanners(modules: List[ModuleType]) -> list:
|
|
49
|
+
scanners: list = []
|
|
50
|
+
for m in modules:
|
|
51
|
+
module_scanners = getattr(m, "PICO_SCANNERS", None)
|
|
52
|
+
if module_scanners:
|
|
53
|
+
scanners.extend(module_scanners)
|
|
54
|
+
return scanners
|
|
55
|
+
|
|
56
|
+
def _load_plugin_modules(group: str = "pico_boot.modules") -> List[ModuleType]:
|
|
57
|
+
eps = entry_points()
|
|
58
|
+
if hasattr(eps, "select"):
|
|
59
|
+
selected = eps.select(group=group)
|
|
60
|
+
else: # legacy API
|
|
61
|
+
selected = [ep for ep in eps if ep.group == group]
|
|
62
|
+
|
|
63
|
+
seen: set[str] = set()
|
|
64
|
+
modules: List[ModuleType] = []
|
|
65
|
+
|
|
66
|
+
for ep in selected:
|
|
67
|
+
try:
|
|
68
|
+
if ep.module in ("pico_ioc", "pico_boot"):
|
|
69
|
+
continue
|
|
70
|
+
m = import_module(ep.module)
|
|
71
|
+
except Exception as exc:
|
|
72
|
+
logger.warning(
|
|
73
|
+
"Failed to load pico-boot plugin entry point '%s' (%s): %s",
|
|
74
|
+
ep.name,
|
|
75
|
+
ep.module,
|
|
76
|
+
exc,
|
|
77
|
+
)
|
|
78
|
+
continue
|
|
79
|
+
|
|
80
|
+
name = m.__name__
|
|
81
|
+
if name not in seen:
|
|
82
|
+
seen.add(name)
|
|
83
|
+
modules.append(m)
|
|
84
|
+
|
|
85
|
+
return modules
|
|
86
|
+
|
|
87
|
+
_IOC_INIT_SIG = inspect.signature(_ioc_init)
|
|
88
|
+
|
|
89
|
+
def init(*args: Any, **kwargs: Any) -> PicoContainer:
|
|
90
|
+
bound = _IOC_INIT_SIG.bind(*args, **kwargs)
|
|
91
|
+
bound.apply_defaults()
|
|
92
|
+
|
|
93
|
+
base_modules = _normalize_modules(_to_module_list(bound.arguments["modules"]))
|
|
94
|
+
|
|
95
|
+
auto_flag = os.getenv("PICO_BOOT_AUTO_PLUGINS", "true").lower()
|
|
96
|
+
auto_plugins = auto_flag not in ("0", "false", "no")
|
|
97
|
+
|
|
98
|
+
if auto_plugins:
|
|
99
|
+
plugin_modules = _load_plugin_modules()
|
|
100
|
+
all_modules = _normalize_modules(list(base_modules) + plugin_modules)
|
|
101
|
+
else:
|
|
102
|
+
all_modules = base_modules
|
|
103
|
+
|
|
104
|
+
bound.arguments["modules"] = all_modules
|
|
105
|
+
|
|
106
|
+
harvested = _harvest_scanners(all_modules)
|
|
107
|
+
if harvested:
|
|
108
|
+
existing = bound.arguments.get("custom_scanners") or []
|
|
109
|
+
bound.arguments["custom_scanners"] = list(existing) + harvested
|
|
110
|
+
|
|
111
|
+
return _ioc_init(*bound.args, **bound.kwargs)
|
|
112
|
+
|
|
113
|
+
init.__signature__ = _IOC_INIT_SIG
|
|
114
|
+
|
|
115
|
+
__all__ = [
|
|
116
|
+
"init",
|
|
117
|
+
"PicoContainer",
|
|
118
|
+
"ContextConfig",
|
|
119
|
+
"ContainerObserver",
|
|
120
|
+
]
|
|
121
|
+
|
pico_boot/_version.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.1.0.post0'
|
|
@@ -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)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
pico_boot/__init__.py,sha256=kiTzllt7y4VcLwTB-xo8VNvwoEkVvSHeM4A_jy-I0RA,3957
|
|
2
|
+
pico_boot/_version.py,sha256=0iP1THdPq83rbUsMGDOrAIfUyC5BhxyeOWsGdqdnFSY,28
|
|
3
|
+
pico_boot-0.1.0.post0.dist-info/licenses/LICENSE,sha256=j86ePhARUMlHapXj0uGGdmnRTholb6VMoORCv8jkGdU,1068
|
|
4
|
+
pico_boot-0.1.0.post0.dist-info/METADATA,sha256=kr6Kf_u8a_1gCmH9k5_48_sfPuJy0GlnJ6BVUicfNWQ,10238
|
|
5
|
+
pico_boot-0.1.0.post0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
6
|
+
pico_boot-0.1.0.post0.dist-info/top_level.txt,sha256=XKFMUvxblFAJ8HJIToiDbAt5wyzp1xIRcTz0__-0gMo,10
|
|
7
|
+
pico_boot-0.1.0.post0.dist-info/RECORD,,
|
|
@@ -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 @@
|
|
|
1
|
+
pico_boot
|