|
1 | | -.. image:: https://img.shields.io/pypi/pyversions/importspy |
2 | 1 | .. image:: https://img.shields.io/pypi/v/importspy |
3 | 2 | :target: https://pypi.org/project/importspy/ |
4 | | -.. image:: https://static.pepy.tech/badge/importspy |
5 | | - :target: https://pepy.tech/projects/importspy |
6 | | - :alt: PyPI Downloads |
| 3 | + :alt: PyPI Version |
| 4 | + |
| 5 | +.. image:: https://img.shields.io/pypi/pyversions/importspy |
| 6 | + :alt: Supported Python Versions |
| 7 | + |
7 | 8 | .. image:: https://img.shields.io/github/actions/workflow/status/atellaluca/ImportSpy/python-package.yml?style=flat-square |
8 | 9 | :target: https://github.com/atellaluca/ImportSpy/actions/workflows/python-package.yml |
| 10 | + :alt: Build Status |
| 11 | + |
9 | 12 | .. image:: https://img.shields.io/readthedocs/importspy?style=flat-square |
10 | 13 | :target: https://importspy.readthedocs.io/ |
| 14 | + :alt: Documentation Status |
| 15 | + |
11 | 16 | .. image:: https://img.shields.io/github/license/atellaluca/importspy |
| 17 | + :alt: License |
| 18 | + |
| 19 | +.. image:: https://img.shields.io/github/stars/atellaluca/ImportSpy?style=social |
| 20 | + :target: https://github.com/atellaluca/ImportSpy |
| 21 | + :alt: GitHub Stars |
12 | 22 |
|
13 | 23 | ImportSpy |
14 | 24 | ========= |
15 | 25 |
|
16 | | -Contract-based import validation for Python modules. |
17 | | - |
18 | | -ImportSpy is a runtime enforcement engine that protects Python modules from being imported or executed in unauthorized, unverified, or structurally incompatible environments — using declarative **import contracts** defined in YAML. |
19 | | - |
20 | | -🧠 **ImportSpy** ensures: |
21 | | - |
22 | | - ✅ Your code is only imported in **verified contexts** |
23 | | - |
24 | | - ✅ Module structure matches declared expectations |
25 | | - |
26 | | - ✅ Runtime conditions (OS, Python version, architecture) are enforced |
27 | | - |
28 | | - ✅ Environments behave predictably across CI, staging, and production |
| 26 | +Contract-based import validation for Python modules. |
| 27 | +Runtime-safe. Structure-aware. Declarative. |
29 | 28 |
|
| 29 | +ImportSpy allows your Python modules to define explicit **import contracts**: |
| 30 | +rules about where, how, and by whom they can be safely imported — and blocks any import that doesn’t comply. |
30 | 31 |
|
31 | 32 | .. image:: https://raw.githubusercontent.com/atellaluca/ImportSpy/refs/heads/main/assets/importspy-works.png |
32 | | - :width: 830 |
33 | 33 | :alt: How ImportSpy Works |
| 34 | + :width: 830 |
| 35 | + |
| 36 | +🔍 Key Benefits |
| 37 | +--------------- |
| 38 | + |
| 39 | +✅ Prevent import from unsupported environments |
| 40 | +✅ Enforce structural expectations (classes, attributes, arguments) |
| 41 | +✅ Control who can use your module and how |
| 42 | +✅ Reduce runtime surprises across CI, staging, and production |
| 43 | +✅ Define everything in readable `.yml` contracts |
34 | 44 |
|
35 | 45 | 💡 Why ImportSpy? |
36 | 46 | ----------------- |
37 | 47 |
|
38 | | -Python's flexibility is powerful — but risky. |
| 48 | +Python is flexible, but uncontrolled imports can lead to: |
39 | 49 |
|
40 | | -Without guardrails, imports can break due to: |
| 50 | +- 🔥 Silent runtime failures |
| 51 | +- 🔍 Structural mismatches (wrong or missing methods/classes) |
| 52 | +- 🌍 Inconsistent behavior across platforms |
| 53 | +- 🚫 Unauthorized usage of internal code |
41 | 54 |
|
42 | | -- 🚫 Missing or malformed classes/functions |
43 | | -- 🚫 Undeclared changes in shared dependencies |
44 | | -- 🚫 Execution in unsupported OS/Python environments |
45 | | -- 🚫 Unauthorized use of internal packages |
| 55 | +ImportSpy offers you **runtime import governance** — clearly defined, enforced in real-time. |
46 | 56 |
|
47 | | -ImportSpy gives you **import boundaries** and **runtime control** using **YAML-defined contracts**. |
| 57 | +📐 Architecture Highlight |
| 58 | +------------------------- |
48 | 59 |
|
49 | | -Two powerful usage modes: |
| 60 | +ImportSpy uses a layered model (`SpyModel`) that mirrors your execution context and module structure: |
50 | 61 |
|
51 | | -- 🔒 **Embedded Mode** – Self-protective modules that validate their own importers. |
52 | | -- 🧪 **External CLI Mode** – Contract validation via `importspy` during builds or CI/CD pipelines. |
| 62 | +- `Runtime` → defines architecture and system |
| 63 | +- `System` → declares OS and environment variables |
| 64 | +- `Python` → specifies interpreter, version, and modules |
| 65 | +- `Module` → lists classes, functions, variables (each represented as objects, not dicts) |
53 | 66 |
|
54 | | -Comparison Table |
55 | | ----------------- |
| 67 | +Each element is introspected and validated dynamically, at runtime or via CLI. |
56 | 68 |
|
57 | | -.. list-table:: |
58 | | - :widths: 20 40 40 |
59 | | - :header-rows: 1 |
60 | | - |
61 | | - * - Aspect |
62 | | - - Without ImportSpy |
63 | | - - With ImportSpy |
64 | | - * - Compatibility |
65 | | - - Modules can run in unsupported runtimes |
66 | | - - Imports blocked in mismatched OS/Python contexts |
67 | | - * - Debugging |
68 | | - - Silent runtime errors and broken contracts |
69 | | - - Clear errors with structured validation output |
70 | | - * - Security |
71 | | - - Unverified third-party modules can access internals |
72 | | - - Controlled import surface and enforced structure |
73 | | - * - Reproducibility |
74 | | - - Behavior varies across environments |
75 | | - - Predictable imports under contract governance |
76 | | - |
77 | | -📜 What’s a Contract? |
78 | | ---------------------- |
79 | | - |
80 | | -A **contract** is a YAML file that defines the expected structure and runtime constraints of your module. |
81 | | - |
82 | | -Example: |
| 69 | +📜 Contract Example |
| 70 | +------------------- |
83 | 71 |
|
84 | 72 | .. code-block:: yaml |
85 | 73 |
|
86 | | - filename: extension.py |
| 74 | + filename: plugin.py |
87 | 75 | variables: |
88 | | - engine: docker |
| 76 | + - name: mode |
| 77 | + value: production |
| 78 | + annotation: str |
89 | 79 | classes: |
90 | | - - name: Extension |
91 | | - attributes: |
92 | | - - type: class |
93 | | - name: extension_name |
94 | | - value: extension_value |
| 80 | + - name: Plugin |
95 | 81 | methods: |
96 | | - - name: add_extension |
| 82 | + - name: run |
97 | 83 | arguments: |
98 | 84 | - name: self |
99 | | - - name: msg |
100 | | - annotation: str |
101 | | - return_annotation: str |
102 | | - superclasses: |
103 | | - - Plugin |
104 | | -
|
105 | | -This defines a structural + runtime boundary for where your module is allowed to run — and how. |
| 85 | + - name: data |
| 86 | + annotation: dict |
| 87 | + return_annotation: None |
106 | 88 |
|
107 | | -⚙️ Embedded Mode |
108 | | ----------------- |
| 89 | +📦 Installation |
| 90 | +--------------- |
109 | 91 |
|
110 | | -Validate importer modules from inside your code. |
| 92 | +.. code-block:: bash |
111 | 93 |
|
112 | | -.. code-block:: python |
| 94 | + pip install importspy |
113 | 95 |
|
114 | | - from importspy import Spy |
115 | | - import logging |
| 96 | +✅ Requires Python 3.10+ |
116 | 97 |
|
117 | | - importer = Spy().importspy(filepath="spymodel.yml", log_level=logging.DEBUG) |
118 | | - importer.Foo().run() |
| 98 | +🔒 Usage Modes |
| 99 | +-------------- |
119 | 100 |
|
120 | | -🔧 CLI Mode (External) |
121 | | ----------------------- |
| 101 | +**Embedded Mode** – the module protects itself: |
122 | 102 |
|
123 | | -Validate a module against its contract from CI, terminal, or script. |
| 103 | +.. image:: https://raw.githubusercontent.com/atellaluca/ImportSpy/refs/heads/main/assets/importspy-embedded-mode.png |
| 104 | + :alt: How ImportSpy Embedded Mode Works |
| 105 | + :width: 830 |
124 | 106 |
|
125 | | -.. code-block:: bash |
| 107 | +.. code-block:: python |
126 | 108 |
|
127 | | - importspy -s spymodel.yml -l DEBUG path/to/module.py |
| 109 | + from importspy import Spy |
| 110 | + importer = Spy().importspy(filepath="spymodel.yml") |
| 111 | + importer.Plugin().run() |
128 | 112 |
|
129 | | -📦 Installation |
130 | | ---------------- |
| 113 | +**CLI Mode** – validate externally in CI/CD: |
131 | 114 |
|
132 | 115 | .. code-block:: bash |
133 | 116 |
|
134 | | - pip install importspy |
135 | | -
|
136 | | -Supported Python: 3.10+ |
| 117 | + importspy -s spymodel.yml -l DEBUG path/to/module.py |
137 | 118 |
|
138 | | -📚 Features at a Glance |
139 | | ------------------------ |
| 119 | +📚 Features Overview |
| 120 | +-------------------- |
140 | 121 |
|
141 | | -- ✅ YAML-based declarative import contracts |
142 | | -- ✅ OS + interpreter + architecture validation |
143 | | -- ✅ Class/function/argument/attribute enforcement |
144 | | -- ✅ Embedded or CLI-driven validation modes |
145 | | -- ✅ Full error trace and CI/CD logging support |
146 | | -- ✅ SpyModel-powered introspection pipeline |
| 122 | +- ✅ Runtime validation based on import contracts |
| 123 | +- ✅ YAML-based, declarative format |
| 124 | +- ✅ Fine-grained introspection of classes, functions, arguments |
| 125 | +- ✅ OS, architecture, interpreter matching |
| 126 | +- ✅ Full error messages, CI-friendly output |
| 127 | +- ✅ Supports embedded or external enforcement |
| 128 | +- ✅ Strong internal model (`SpyModel`) powered by `pydantic` |
147 | 129 |
|
148 | | -📎 Ideal For: |
149 | | -------------- |
| 130 | +🚀 Ideal Use Cases |
| 131 | +------------------ |
150 | 132 |
|
151 | | -- 🔐 Security-driven systems (banking, medical, gov) |
152 | | -- 🧩 Plugin frameworks (CMS, IoT, CLI extensions) |
153 | | -- 🔬 Large codebases needing structural validation |
154 | | -- 🧪 CI/CD workflows enforcing compatibility and compliance |
155 | | -- 📦 Maintainers distributing validated packages |
| 133 | +- 🛡️ Security-sensitive systems (finance, IoT, medical) |
| 134 | +- 🧩 Plugin-based architectures (CMS, CLI, extensions) |
| 135 | +- 🧪 CI/CD pipelines with strict integration rules |
| 136 | +- 🧱 Frameworks with third-party extension points |
| 137 | +- 📦 Package maintainers enforcing integration rules |
156 | 138 |
|
157 | | -🔍 How It Works |
| 139 | +🧠 How It Works |
158 | 140 | --------------- |
159 | 141 |
|
160 | | -1. Your module defines a contract (YAML or Python). |
161 | | -2. ImportSpy is triggered at runtime or CLI. |
162 | | -3. The environment and structure of the importer are introspected. |
163 | | -4. Validation checks everything against the contract. |
164 | | -5. If the contract fails: import is blocked. |
165 | | - If it passes: import proceeds safely. |
166 | | - |
167 | | -🔧 Example CLI Usage |
168 | | - |
169 | | -.. code-block:: bash |
170 | | -
|
171 | | - importspy -s spymodel.yml -l ERROR plugin.py |
| 142 | +1. Define your contract in `.yml` or Python. |
| 143 | +2. ImportSpy loads your module and introspects its importer. |
| 144 | +3. Runtime environment + structure are matched against the contract. |
| 145 | +4. If mismatch → import blocked. |
| 146 | + If valid → import continues safely. |
172 | 147 |
|
173 | 148 | 🎯 Tech Stack |
174 | 149 | ------------- |
175 | 150 |
|
176 | | -- ✅ Pydantic v2 → validation engine |
177 | | -- ✅ Typer → CLI interface |
178 | | -- ✅ ruamel.yaml → YAML parsing |
179 | | -- ✅ inspect + platform + sys → runtime reflection |
180 | | -- ✅ Poetry → package management |
181 | | -- ✅ Sphinx + ReadTheDocs → full docs coverage |
| 151 | +- ✅ Pydantic 2.x – contract validation engine |
| 152 | +- ✅ Typer – CLI interface |
| 153 | +- ✅ ruamel.yaml – YAML parsing |
| 154 | +- ✅ inspect + sys – runtime context introspection |
| 155 | +- ✅ Poetry – package + dependency management |
| 156 | +- ✅ Sphinx + ReadTheDocs – full docs and architecture reference |
182 | 157 |
|
183 | | -📚 Docs |
184 | | -------- |
| 158 | +📘 Documentation |
| 159 | +---------------- |
185 | 160 |
|
186 | | -- 📘 Full Documentation → https://importspy.readthedocs.io/ |
187 | | -- 🧱 Architecture Overview → https://importspy.readthedocs.io/en/latest/advanced/architecture_index.html |
188 | | -- 🧪 Examples & Use Cases → https://importspy.readthedocs.io/en/latest/overview/use_cases_index.html |
| 161 | +- 🔗 Full Docs → https://importspy.readthedocs.io/ |
| 162 | +- 🧱 Model Overview → https://importspy.readthedocs.io/en/latest/advanced/architecture_index.html |
| 163 | +- 🧪 Use Cases → https://importspy.readthedocs.io/en/latest/overview/use_cases_index.html |
189 | 164 |
|
190 | | -❤️ Contribute, Share, Support |
191 | | ------------------------------ |
| 165 | +🌟 Contribute & Support |
| 166 | +----------------------- |
192 | 167 |
|
193 | | -- ⭐ Star on GitHub → https://github.com/atellaluca/ImportSpy |
194 | | -- 🛠 Contribute: PRs, Issues, Docs welcome |
| 168 | +- ⭐ Star → https://github.com/atellaluca/ImportSpy |
| 169 | +- 🛠 Contribute via issues or PRs |
195 | 170 | - 💖 Sponsor → https://github.com/sponsors/atellaluca |
196 | 171 |
|
197 | 172 | 📜 License |
198 | 173 | ---------- |
199 | 174 |
|
200 | | -MIT © 2024 — Luca Atella |
| 175 | +MIT © 2024 – Luca Atella |
201 | 176 |
|
202 | | -🔥 Take control of your imports. Validate with ImportSpy. |
| 177 | +🔥 **Let your modules enforce their own rules.** |
| 178 | +Start importing with structure. |
0 commit comments