Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e192483
feat(environment): introduce structured environment declaration and v…
atellaluca May 2, 2025
f242d64
refactor(errors): unify error messages under consistent templates
atellaluca May 2, 2025
2abb3e6
refactor(errors,validators): remove legacy scope-based error maps and…
atellaluca May 3, 2025
01e7dea
refactor(error-handling): unify validation errors into centralized, c…
atellaluca May 14, 2025
b466f27
refactor(validators): partial cleanup of legacy validator architecture
atellaluca May 16, 2025
6a5b56a
feat(errors): introduce structured contract violation system for labe…
atellaluca May 17, 2025
e0c0fb1
refactor(constants, models): replace literals with typed enums for va…
atellaluca May 18, 2025
bb7d3f8
feat(models, validators): introduce RuntimeContractViolation for stru…
atellaluca May 18, 2025
b1d4627
feat(errors): add structured contract violations for system, python, …
atellaluca May 18, 2025
64333b9
refactor(errors): centralize contract violation handling and improve …
atellaluca May 18, 2025
6494b92
refactor(class-validator): isolate class vs instance attributes for s…
atellaluca May 20, 2025
1ec8612
refactor(models/validators): extract contract violation logic to dedi…
atellaluca May 27, 2025
96d48fd
refactor(validation): centralize violation payload with shared Bundle
atellaluca May 28, 2025
06ccd89
refactor(bundle): enable dict-like access to Bundle for cleaner usage
atellaluca May 29, 2025
1c53c7b
refactor(errors): introduce spec-based label formatting for contract …
atellaluca May 30, 2025
e879f81
feat(validators): add contextualized class validation and superclass …
atellaluca May 31, 2025
1ec2029
refactor(validators): unify variable validation across arguments and …
atellaluca Jun 1, 2025
992fb59
feat(validators): support dynamic spec dispatch for variable contract…
atellaluca Jun 1, 2025
7194306
refactor(validators): standardize use of VariableContractViolation in…
atellaluca Jun 2, 2025
5795a9d
refactor(constants, validators): unify dynamic payload keys for funct…
atellaluca Jun 3, 2025
399535b
refactor(validators): decouple ModuleValidator from persistent bundle…
atellaluca Jun 3, 2025
0673a28
refactor(runtime): unify contract violation handling across validators
atellaluca Jun 16, 2025
93d11ce
refactor: improve error reporting and runtime validation formatting
atellaluca Jun 17, 2025
ff0816c
refactor(models): improve string representations for core model classes
atellaluca Jun 17, 2025
41b96c8
chore: remove unused import and fix test enum usage
atellaluca Jun 20, 2025
3b2e0a0
chore: whole deps updated
atellaluca Jul 6, 2025
2b5f144
fix(examples): Fix the example so that it respects the contract
atellaluca Jul 6, 2025
23373c8
chore(docs): migrate documentation from Sphinx to MkDocs
Jul 31, 2025
1184328
build(docs): configure MkDocs site metadata and theme
Jul 31, 2025
7e2e7d7
docs: add homepage, reference structure and violation system docs
Aug 2, 2025
4a02120
docs(readme): convert README from reStructuredText to Markdown
Aug 2, 2025
cbe4a78
docs: move contributing guidelines to project root and link from mkdocs
Aug 2, 2025
8246444
docs: rewrite contract syntax page and update validation path
Aug 4, 2025
02d5a9f
docs(uml): update UML diagrams
Aug 6, 2025
27fc773
chore: bumping to 0.4.0
Aug 6, 2025
125d090
chore: add /site/ on .gitignore
Aug 6, 2025
a626c8c
docs: clean homepage and unify contributing path
Aug 6, 2025
f5a609b
chore(dependencies): updating rich 14.0.0 -> 14.1.0
Aug 7, 2025
d7b7bc0
chore(docs): cleanup assets and update links, unify utility docstrings
Aug 7, 2025
b0ad99b
chore(readme): fix media reference
Aug 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ venv/
ENV/
env.bak/
venv.bak/
.pytest_cache/
.pytest_cache/
/site/
142 changes: 118 additions & 24 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,127 @@
# Contributing to ImportSpy

🎉 Thank you for considering a contribution to **ImportSpy**! We value your efforts and welcome **issues, features, and documentation improvements**.
🎉 Thank you for considering a contribution to **ImportSpy** — a project designed to bring structure, security, and clarity to Python imports.

We welcome all kinds of contributions: new features, bug fixes, tests, documentation, and even thoughtful ideas. Your involvement makes the project better.

---

## 📢 How to Contribute

### 🔍 1. Issue Reporting
If you find a **bug** or have a **feature request**, please open an issue:
🔗 [GitHub Issues](https://github.com/atellaluca/ImportSpy/issues)

### 🔄 2. Fork & Branching Strategy
- **Create a fork** and work on a separate branch before submitting a pull request.
- Use the following **branch naming conventions**:
- **For features:** `feature/nome-feature-in-breve`
- **For bug fixes:** `fix/bugfix-description`
- **For documentation:** `docs/update-section`

### ✅ 3. Code Style & Commit Rules
- **Follow Conventional Commits**:
- `feat:` → For new features
- `fix:` → For bug fixes
- `docs:` → For documentation changes
- `test:` → For tests
- `refactor:` → Code improvements without changing functionality

Example:
### 1. Open an Issue
If you encounter a bug, have a feature suggestion, or want to propose a change, please [open an issue](https://github.com/atellaluca/ImportSpy/issues). Use clear and descriptive titles.

You can use labels such as:
- `bug`: for broken functionality
- `enhancement`: for feature requests
- `question`: for clarification or design discussions

### 2. Fork and Branch Strategy

- Create a **fork** of the repository.
- Work in a dedicated **feature branch** off `main`.
- Use consistent branch naming:

| Purpose | Branch Name Format |
|----------------|-------------------------------|
| Feature | `feature/short-description` |
| Bug fix | `fix/issue-description` |
| Documentation | `docs/section-description` |
| Tests | `test/feature-or-bug-name` |

> 💡 Keep pull requests focused and small. This helps reviewers and speeds up merging.

---

## ✅ Code Standards

### Python Style Guide
ImportSpy follows:
- [PEP8](https://peps.python.org/pep-0008/)
- Type hints throughout the codebase
- `black` + `ruff` for formatting and linting
- `pydantic` for data models

### Linting & Tests

To run tests and lint checks:

```bash
git commit -m "feat: add validation for OS compatibility"
poetry install
pytest
ruff check .
black --check .
```

💡 **We Appreciate Every Contribution!**
---

## 📄 Commit Conventions

We use **[Conventional Commits](https://www.conventionalcommits.org/)** for readable history and automatic changelog generation.

| Type | Use For |
|----------|-------------------------------|
| `feat:` | New feature |
| `fix:` | Bug fix |
| `docs:` | Documentation only |
| `refactor:` | Code change w/o new feature or fix |
| `test:` | Adding or updating tests |
| `chore:` | Internal tooling or CI |

**Example:**
```bash
git commit -m "feat: support multiple Python interpreters in contract"
```

---

## 🧪 Test Philosophy

Tests live in `tests/validators/` and should:
- Cover core logic (validators, spymodel, contract violations)
- Include both positive and negative cases
- Be fast, deterministic, and isolated

---

## ✍️ Docs Contributions

We use **MkDocs + Material** for documentation. Docs live under:

```
docs/
```

To preview locally:

```bash
poetry install
mkdocs serve
```

New pages should be added to `mkdocs.yml` under the right section.

---

## 🙌 Join the Community

While we don’t yet have a Discord or forum, we encourage:
- Sharing feedback via GitHub Issues
- Discussing architecture via PRs and comments
- Connecting with the maintainer via LinkedIn or GitHub

---

## 💬 Need Help?

Open an issue with the `question` label or ping @atellaluca in your PR.

---

## 📜 License

By contributing, you agree your work will be released under the MIT License.

---

ImportSpy is an open-source project, and every contribution—big or small—helps make it better. 🚀
**Let your modules enforce their own rules — and thank you for helping ImportSpy grow!**
178 changes: 178 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# ImportSpy

![License](https://img.shields.io/github/license/atellaluca/importspy)
[![PyPI Version](https://img.shields.io/pypi/v/importspy)](https://pypi.org/project/importspy/)
![Python Versions](https://img.shields.io/pypi/pyversions/importspy)
[![Build Status](https://img.shields.io/github/actions/workflow/status/atellaluca/ImportSpy/python-package.yml?branch=main)](https://github.com/atellaluca/ImportSpy/actions/workflows/python-package.yml)
[![Docs](https://img.shields.io/readthedocs/importspy)](https://importspy.readthedocs.io/)

![ImportSpy banner](https://github.com/atellaluca/ImportSpy/docs/assets/importspy-banner.png)

**Runtime contract validation for Python imports.**
_Enforce structure. Block invalid usage. Stay safe at runtime._

---

## 🔍 What is ImportSpy?

**ImportSpy** lets your Python modules declare structured **import contracts** (via `.yml` files) to define:

- What environment they expect (OS, Python version, interpreter)
- What structure they must follow (classes, methods, variables)
- Who is allowed to import them

If the contract is not met, **ImportSpy blocks the import** — ensuring safe and predictable runtime behavior.

---

## ✨ Key Features

- ✅ Validate imports dynamically at runtime or via CLI
- ✅ Block incompatible usage of internal or critical modules
- ✅ Enforce module structure, arguments, annotations
- ✅ Context-aware: Python version, OS, architecture, interpreter
- ✅ Human-readable YAML contracts
- ✅ Clear, CI-friendly violation messages

---

## 📦 Installation

```bash
pip install importspy
```

> Requires Python 3.10+

---

## 📐 Architecture

![SpyModel UML](https://github.com/atellaluca/ImportSpy/docs/assets/importspy-spy-model-architecture.png)

ImportSpy is powered by a layered introspection model (`SpyModel`), which captures:

- `Runtime`: CPU architecture
- `System`: OS and environment
- `Python`: interpreter and version
- `Module`: classes, functions, variables, annotations

Each layer is validated against the corresponding section of your `.yml` contract.

---

## 📜 Example Contract

```yaml
filename: plugin.py
variables:
- name: mode
value: production
annotation: str
classes:
- name: Plugin
methods:
- name: run
arguments:
- name: self
- name: data
annotation: dict
return_annotation: None
```

---

## 🔧 Modes of Use

### Embedded Mode – protect your own module

```python
from importspy import Spy

caller = Spy().importspy(filepath="spymodel.yml")
caller.Plugin().run()
```

![Embedded mode](https://github.com/atellaluca/ImportSpy/docs/assets/importspy-embedded-mode.png)

---

### CLI Mode – external validation in CI

```bash
importspy -s spymodel.yml -l DEBUG path/to/module.py
```

![CLI mode](https://github.com/atellaluca/ImportSpy/docs/assets/importspy-works.png)

---

## 🧠 How It Works

1. You define an import contract in `.yml`
2. At runtime or via CLI, ImportSpy inspects:
- Who is importing the module
- What the system/environment looks like
- What the module structure provides
3. If validation fails → the import is blocked
4. If valid → the module runs safely

---

## ✅ Tech Stack

- [Pydantic 2.x](https://docs.pydantic.dev) – schema validation
- [Typer](https://typer.tiangolo.com) – CLI
- [ruamel.yaml](https://yaml.readthedocs.io/) – YAML support
- `inspect` + `sys` – runtime introspection
- [Poetry](https://python-poetry.org) – dependency management
- [Sphinx](https://www.sphinx-doc.org) + ReadTheDocs – documentation

---

## 📘 Documentation

- **Full docs** → [importspy.readthedocs.io](https://importspy.readthedocs.io)
- [Quickstart](https://importspy.readthedocs.io/en/latest/intro/quickstart.html)
- [Contract syntax](https://importspy.readthedocs.io/en/latest/contracts/syntax.html)
- [Violation system](https://importspy.readthedocs.io/en/latest/advanced/violations.html)
- [API Reference](https://importspy.readthedocs.io/en/latest/api-reference.html)

---

## 🚀 Ideal Use Cases

- Plugin-based frameworks (e.g., CMS, CLI, IDE)
- CI/CD pipelines with strict integration
- Security-regulated environments (IoT, medical, fintech)
- Package maintainers enforcing internal boundaries

---

## 💡 Why It Matters

Python’s flexibility comes at a cost:

- Silent runtime mismatches
- Missing methods or classes
- Platform-dependent failures
- No enforcement over module consumers

**ImportSpy brings governance**
to how, when, and where modules are imported.

---

## ❤️ Contribute & Support

- ⭐ [Star on GitHub](https://github.com/atellaluca/ImportSpy)
- 🐛 [File issues or feature requests](https://github.com/atellaluca/ImportSpy/issues)
- 🤝 [Contribute](https://github.com/atellaluca/ImportSpy/blob/main/CONTRIBUTING.md)
- 💖 [Sponsor on GitHub](https://github.com/sponsors/atellaluca)

---

## 📜 License

MIT © 2024 – Luca Atella
![ImportSpy logo](https://github.com/atellaluca/ImportSpy/docs/assets/importspy-logo.png)
Loading
Loading