python-husky 🐶
Git hooks made easy for Python projects
python-husky improves your commits and more 🐶 woof!
Inspired by the amazing Husky tool for Node.js, py-husky brings the same awesome Git hooks experience to Python developers.
The Problem python-husky Solves
The Missing Step That Breaks Everything
Most Git hook tools (like pre-commit) require a two-step process:
- ✅ Install the package:
pip install pre-commit - ❌ Run install command:
pre-commit install← Developers forget this!
The Result? Hooks don't work, and developers don't even know it.
Why This Happens
When you add a package to requirements.txt or pyproject.toml:
pre-commit==3.5.0
And run pip install -r requirements.txt, the package installs but hooks are NOT automatically set up. Developers must remember to run an additional command, which often gets missed, especially when:
- Onboarding new team members
- Cloning the repository on a new machine
- Switching between projects
- After cleaning the environment
python-husky's Solution: Zero Extra Steps
python-husky automatically installs hooks when the package is installed!
pip install python-husky
That's it! If .py-husky/ directory exists in your project, hooks are automatically installed. No extra command needed.
How It Works
- During Installation: py-husky checks for
.py-husky/directory - Automatic Setup: If found, Git hooks are automatically configured
- Zero Friction: Developers get working hooks without knowing it
But Wait, There's More!
If .py-husky/ wasn't present during installation (e.g., you added it later), you can still run:
py-husky install
This gives you the flexibility of manual installation when needed, while providing automatic installation by default.
Real-World Impact
Before py-husky:
git clone repo
pip install -r requirements.txt
# Oops! Forgot to run pre-commit install
git commit -m "bad code" # ❌ No checks run!
With python-husky:
git clone repo
pip install -r requirements.txt # ✅ Hooks automatically installed!
git commit -m "code" # ✅ Checks run automatically!
Comparison
| Tool | Install Package | Setup Hooks | Hooks Work? |
|---|---|---|---|
| pre-commit | pip install pre-commit |
pre-commit install ⚠️ |
Only if you remember step 2 |
| python-husky | pip install python-husky |
✅ Automatic! | Always! |
Features
✨ Easy Setup - Initialize Git hooks with a single command
🎯 Simple Configuration - File-based hooks just like Husky
🔧 Flexible - Support for all Git hooks (pre-commit, pre-push, commit-msg, etc.)
🚀 Lightweight - Minimal dependencies, maximum functionality
🐍 Python Native - Built for Python projects, by Python developers
📦 PyPI Ready - Easy installation via pip
Installation
pip install py-husky
Quick Start
1. Initialize py-husky in your project
cd your-project
py-husky init
This creates:
.py-husky/directory for your hook scripts- Git hooks in
.git/hooks/
2. Add your hooks
Create hook files directly in .py-husky/ or use the CLI:
# Using CLI
py-husky add pre-commit "black ." "flake8"
# Or create files manually
echo '#!/bin/sh
black .
flake8 .' > .py-husky/pre-commit
chmod +x .py-husky/pre-commit
3. That's it! 🎉
Your hooks will now run automatically when you commit or push.
Usage
Initialize py-husky
py-husky init
Add hooks via CLI
# Add a pre-commit hook
py-husky add pre-commit "black ." "flake8"
# Add a pre-push hook
py-husky add pre-push "pytest tests/"
List all hooks
py-husky list-hooks
Install hooks (useful after cloning)
py-husky install
Uninstall hooks
py-husky uninstall
Configuration
Hook Files
Create shell scripts directly in .py-husky/ directory:
# .py-husky/pre-commit
#!/bin/sh
echo "Running custom pre-commit hook..."
black .
flake8 .
if [ $? -ne 0 ]; then
echo "Pre-commit checks failed!"
exit 1
fi
Make it executable:
chmod +x .py-husky/pre-commit
Supported Hooks
py-husky supports all Git hooks:
pre-commit- Run before commitpre-push- Run before pushcommit-msg- Validate commit messagespre-rebase- Run before rebasepost-checkout- Run after checkoutpost-merge- Run after mergeprepare-commit-msg- Prepare commit message
Common Use Cases
Code Formatting
# .py-husky/pre-commit
#!/bin/sh
black .
isort .
Linting
# .py-husky/pre-commit
#!/bin/sh
flake8 src/
pylint src/
mypy src/
Testing
# .py-husky/pre-push
#!/bin/sh
pytest tests/ -v
pytest tests/ --cov --cov-report=term-missing
Commit Message Validation
# .py-husky/commit-msg
#!/bin/sh
python scripts/validate_commit_msg.py "$1"
Example validation script:
# scripts/validate_commit_msg.py
import sys
import re
with open(sys.argv[1], 'r') as f:
commit_msg = f.read()
pattern = r'^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?: .{1,50}'
if not re.match(pattern, commit_msg):
print("❌ Invalid commit message format!")
print("Format: <type>(scope): <subject>")
print("Example: feat(auth): add login functionality")
sys.exit(1)
print("✅ Commit message is valid")
Security Scanning
# .py-husky/pre-commit
#!/bin/sh
bandit -r src/
safety check
Advanced Features
Debug Mode
Enable debug logging:
export PY_HUSKY_DEBUG=1
git commit -m "test"
Skip Hooks
Skip hooks for a single commit:
git commit -m "urgent fix" --no-verify
Project-Specific Configuration
Each project can have its own .py-husky/ hook files, making it easy to share hook configurations across teams via version control.
Integration with CI/CD
Add to your requirements.txt or pyproject.toml:
[project.optional-dependencies]
dev = [
"py-husky>=0.1.0",
"black>=22.0.0",
"flake8>=4.0.0",
"pytest>=7.0.0",
]
In your CI pipeline:
pip install -e ".[dev]"
py-husky install
Comparison with Other Tools
| Feature | py-husky | pre-commit | husky (Node.js) |
|---|---|---|---|
| Language | Python | Python | JavaScript |
| Configuration | Shell Scripts | YAML | Shell Scripts |
| Custom Scripts | ✅ | ✅ | ✅ |
| Easy Setup | ✅ | ✅ | ✅ |
| PyPI Package | ✅ | ✅ | ❌ |
| Node.js Required | ❌ | ❌ | ✅ |
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License - see LICENSE file for details.
Acknowledgments
This project is inspired by Husky by typicode, which revolutionized Git hooks for Node.js developers. py-husky brings that same elegant experience to the Python ecosystem.
Why py-husky?
While Husky is excellent for Node.js projects, Python developers needed a native solution that:
- Works without Node.js dependencies
- Integrates seamlessly with Python tooling (black, flake8, pytest, mypy, etc.)
- Follows Python packaging standards (PyPI, pip)
- Uses simple shell scripts for hooks (just like Husky)
py-husky is an independent project developed by Piyush Gautam, maintaining the same philosophy as Husky: making Git hooks easy and accessible for everyone.
If you find Husky's approach useful, consider checking out the original Husky project.
Support
- 📫 Issues: GitHub Issues
- 📖 Documentation: GitHub README
Changelog
0.1.0 (Initial Release)
- ✨ Initial release
- 🎯 Support for all Git hooks
- 📝 File-based hook configuration
- 🔧 CLI commands for hook management
- 📦 PyPI package ready
Made with ❤️ for the Python community
Metadata
Release files for python-husky 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| python_husky-0.1.0.tar.gz | 12.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| python_husky-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 23.0 kB
Release files / python_husky-0.1.0.tar.gz
| Download URL | python_husky-0.1.0.tar.gz |
|---|---|
| Size | 12.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
de60b5e32eb202c0fc3d43900232229df6ce0a6c6fbadbb2373735f2146e5f96
|
|
BLAKE2b-256 checksum How to use checksums |
df99309c736ea96d9dca4ccaa6c8a483dfc7023eda9acc60aeb6199056db9439
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / python_husky-0.1.0-py3-none-any.whl
| Download URL | python_husky-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
db8e3ce25ec163a6be2d589dbc203bd5d4c3daf1fb762afb2bf01274b54c598e
|
|
BLAKE2b-256 checksum How to use checksums |
b26d224b6e2097a083e15fe2fbe40b101091cf7b735c63944a6dd866498deed0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|