Loading...
Automatically sorts and optimizes Python imports using isort when Python files are modified
{
"hookConfig": {
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/python-import-optimizer.sh",
"matchers": [
"write",
"edit"
]
}
}
},
"scriptContent": "#!/bin/bash\n\n# Read the tool input from stdin\nINPUT=$(cat)\nTOOL_NAME=$(echo \"$INPUT\" | jq -r '.tool_name')\nFILE_PATH=$(echo \"$INPUT\" | jq -r '.tool_input.file_path // .tool_input.path // \"\"')\n\nif [ -z \"$FILE_PATH\" ]; then\n exit 0\nfi\n\n# Check if this is a Python file\nif [[ \"$FILE_PATH\" == *.py ]]; then\n echo \"๐ Python Import Optimizer - Processing Python file...\"\n echo \"๐ File: $FILE_PATH\"\n \n # Check if file exists\n if [ ! -f \"$FILE_PATH\" ]; then\n echo \"โ ๏ธ File not found: $FILE_PATH\"\n exit 1\n fi\n \n # Step 1: Sort imports with isort\n echo \"๐ Sorting imports with isort...\"\n if command -v isort >/dev/null 2>&1; then\n if isort \"$FILE_PATH\" --profile black --line-length 88 --check-only --diff; then\n echo \"โ
Imports are already sorted\"\n else\n echo \"๐ Sorting imports...\"\n isort \"$FILE_PATH\" --profile black --line-length 88\n echo \"โ
Imports sorted successfully\"\n fi\n else\n echo \"โ ๏ธ isort not found. Install with: pip install isort\"\n fi\n \n # Step 2: Remove unused imports with autoflake (optional)\n echo \"๐งน Removing unused imports...\"\n if command -v autoflake >/dev/null 2>&1; then\n # Check for unused imports first\n if autoflake --check \"$FILE_PATH\" --remove-unused-variables --remove-all-unused-imports; then\n echo \"โ
No unused imports found\"\n else\n echo \"๐ Removing unused imports...\"\n autoflake --in-place \"$FILE_PATH\" --remove-unused-variables --remove-all-unused-imports\n echo \"โ
Unused imports removed\"\n fi\n else\n echo \"โน๏ธ autoflake not found (optional). Install with: pip install autoflake\"\n fi\n \n # Step 3: Additional import analysis\n echo \"๐ Analyzing import structure...\"\n \n # Count different types of imports\n STDLIB_IMPORTS=$(grep -c \"^import \\(os\\|sys\\|re\\|json\\|datetime\\|collections\\|itertools\\|functools\\|pathlib\\)\" \"$FILE_PATH\" 2>/dev/null || echo 0)\n THIRD_PARTY_IMPORTS=$(grep -c \"^\\(import\\|from\\) \\(numpy\\|pandas\\|requests\\|flask\\|django\\|fastapi\\)\" \"$FILE_PATH\" 2>/dev/null || echo 0)\n RELATIVE_IMPORTS=$(grep -c \"^from \\.[.]*\" \"$FILE_PATH\" 2>/dev/null || echo 0)\n \n echo \"๐ Import Summary:\"\n echo \" โข Standard Library: $STDLIB_IMPORTS\"\n echo \" โข Third Party: $THIRD_PARTY_IMPORTS\"\n echo \" โข Relative: $RELATIVE_IMPORTS\"\n \n # Check for potential issues\n if grep -q \"^import \\*\" \"$FILE_PATH\" 2>/dev/null; then\n echo \"โ ๏ธ Warning: Star imports detected (import *) - consider specific imports\"\n fi\n \n if [ \"$(grep -c '^import\\|^from' \"$FILE_PATH\" 2>/dev/null || echo 0)\" -gt 20 ]; then\n echo \"๐ก Tip: Consider grouping related imports or using a package structure\"\n fi\n \n echo \"\"\n echo \"๐ก Python Import Tips:\"\n echo \" โข Use absolute imports when possible\"\n echo \" โข Group imports: stdlib, third-party, local\"\n echo \" โข Avoid star imports (import *)\"\n echo \" โข Use 'from module import specific_function' for clarity\"\n \n echo \"\"\n echo \"๐ฏ Python import optimization complete!\"\n \nelse\n echo \"โน๏ธ File is not a Python file: $FILE_PATH\"\nfi\n\nexit 0"
}.claude/hooks/~/.claude/hooks/{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/python-import-optimizer.sh",
"matchers": [
"write",
"edit"
]
}
}
}#!/bin/bash
# Read the tool input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
# Check if this is a Python file
if [[ "$FILE_PATH" == *.py ]]; then
echo "๐ Python Import Optimizer - Processing Python file..."
echo "๐ File: $FILE_PATH"
# Check if file exists
if [ ! -f "$FILE_PATH" ]; then
echo "โ ๏ธ File not found: $FILE_PATH"
exit 1
fi
# Step 1: Sort imports with isort
echo "๐ Sorting imports with isort..."
if command -v isort >/dev/null 2>&1; then
if isort "$FILE_PATH" --profile black --line-length 88 --check-only --diff; then
echo "โ
Imports are already sorted"
else
echo "๐ Sorting imports..."
isort "$FILE_PATH" --profile black --line-length 88
echo "โ
Imports sorted successfully"
fi
else
echo "โ ๏ธ isort not found. Install with: pip install isort"
fi
# Step 2: Remove unused imports with autoflake (optional)
echo "๐งน Removing unused imports..."
if command -v autoflake >/dev/null 2>&1; then
# Check for unused imports first
if autoflake --check "$FILE_PATH" --remove-unused-variables --remove-all-unused-imports; then
echo "โ
No unused imports found"
else
echo "๐ Removing unused imports..."
autoflake --in-place "$FILE_PATH" --remove-unused-variables --remove-all-unused-imports
echo "โ
Unused imports removed"
fi
else
echo "โน๏ธ autoflake not found (optional). Install with: pip install autoflake"
fi
# Step 3: Additional import analysis
echo "๐ Analyzing import structure..."
# Count different types of imports
STDLIB_IMPORTS=$(grep -c "^import \(os\|sys\|re\|json\|datetime\|collections\|itertools\|functools\|pathlib\)" "$FILE_PATH" 2>/dev/null || echo 0)
THIRD_PARTY_IMPORTS=$(grep -c "^\(import\|from\) \(numpy\|pandas\|requests\|flask\|django\|fastapi\)" "$FILE_PATH" 2>/dev/null || echo 0)
RELATIVE_IMPORTS=$(grep -c "^from \.[.]*" "$FILE_PATH" 2>/dev/null || echo 0)
echo "๐ Import Summary:"
echo " โข Standard Library: $STDLIB_IMPORTS"
echo " โข Third Party: $THIRD_PARTY_IMPORTS"
echo " โข Relative: $RELATIVE_IMPORTS"
# Check for potential issues
if grep -q "^import \*" "$FILE_PATH" 2>/dev/null; then
echo "โ ๏ธ Warning: Star imports detected (import *) - consider specific imports"
fi
if [ "$(grep -c '^import\|^from' "$FILE_PATH" 2>/dev/null || echo 0)" -gt 20 ]; then
echo "๐ก Tip: Consider grouping related imports or using a package structure"
fi
echo ""
echo "๐ก Python Import Tips:"
echo " โข Use absolute imports when possible"
echo " โข Group imports: stdlib, third-party, local"
echo " โข Avoid star imports (import *)"
echo " โข Use 'from module import specific_function' for clarity"
echo ""
echo "๐ฏ Python import optimization complete!"
else
echo "โน๏ธ File is not a Python file: $FILE_PATH"
fi
exit 0isort conflicts with Black formatter settings
Hook already uses --profile black flag for compatibility. Ensure Black and isort versions are current. Add .isort.cfg with profile = black and line_length = 88 for project-wide consistency.
autoflake removes imports that are actually used
Add # noqa comments to imports that should be preserved. Configure autoflake to exclude specific files with --exclude in hook script, or use __all__ exports to signal intentional module-level imports.
Hook processes __init__.py and breaks package exports
Exclude __init__.py from autoflake processing by modifying hook to check filename. Add special handling for package files where import * is intentional for re-exporting.
Relative imports get converted to absolute incorrectly
Configure isort with known_first_party setting in setup.cfg or pyproject.toml. Use --src-path flag in hook to help isort determine project root for proper import classification.
Loading reviews...
Join our community of Claude power users. No spam, unsubscribe anytime.
Automated accessibility testing and compliance checking for web applications following WCAG guidelines
Automatically generates or updates API documentation when endpoint files are modified
Automatically formats code files after Claude writes or edits them using Prettier, Black, or other formatters