Migrate Keboola Python packages from setup.py to modern uv build system with deterministic dependencies. Follows established patterns from python-http-client and python-component migrations.
/plugin marketplace add keboola/ai-kit/plugin install component-developer@keboola-claude-kitThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/examples.mdreferences/migration-guide.mdreferences/troubleshooting.mdreferences/workflow-templates.mdtemplates/flake8.templatetemplates/pr-description.md.templatetemplates/pyproject.toml.templateYou are an expert at migrating Keboola Python packages from legacy setup.py + pip to modern pyproject.toml + uv build system. You understand PEP 517/518/639 standards, GitHub Actions workflows, and Keboola's established migration patterns.
Use this skill when:
setup.py to pyproject.tomluv.lockBefore starting, verify:
setup.py and/or requirements.txtGuideline (not dogma): Use 3 logical commits
Why this works:
Key principle: Logical, reviewable chunks that make sense independently
Always fix linting BEFORE migrating metadata:
Testing phase: Use next minor version
Production release: Use following minor version
Flexibility: Could use 1.7.0a1, 1.7.0a2 instead - pattern matters, not exact format
# What's in setup.py?
cat setup.py
# What's in requirements.txt?
cat requirements.txt
# What's the current version?
# Check PyPI or setup.py
# From setup.py python_requires
# Determine: min_version = max(3.8, current_requires_python)
# Does push_main.yml exist with pdoc?
cat .github/workflows/push_main.yml 2>/dev/null | grep pdoc
Purpose: Establish clean linting baseline
Steps:
# Rename to standard name
mv flake8.cfg .flake8 # if it exists
# Use cookiecutter template standard:
cat > .flake8 << 'EOF'
[flake8]
exclude = __pycache__, .git, .venv, venv, docs
ignore = E203,W503
max-line-length = 120
EOF
# Install flake8
uv add --dev flake8
# Run and fix errors
flake8 src/ tests/
Common fixes:
git add .flake8 src/ tests/
git commit -m "flake8 config consistent with cookiecutter template 🍪"
Purpose: Migrate to modern pyproject.toml
Steps:
templates/pyproject.toml.template):Key points:
version = "0.0.0" - replaced by git tags in CIinstall_requiressetup_requires and tests_requirepdoc3 to dev if docs workflow existsrequires-python = ">=MIN_VERSION" (≥3.8)License :: OSI Approved :: MIT License classifier (PEP 639)license = "MIT" fieldgit rm setup.py requirements.txt
# Update to current year (2026)
sed -i 's/Copyright (c) 20[0-9][0-9]/Copyright (c) 2026/' LICENSE
git add pyproject.toml LICENSE
git commit -m "migrate package configuration to pyproject.toml 📦"
Purpose: Update CI/CD to use uv
Steps:
references/workflow-templates.md):
push_dev.yml - Testing on dev branchesdeploy.yml - Production PyPI deploymentdeploy_to_test.yml - Test PyPI deploymentpush_main.yml - Docs generation (OPTIONAL - only if docs exist)Key changes per workflow:
@v4 → @v5, @v6uses: astral-sh/setup-uv@v6uses: astral-sh/ruff-action@v3 (blocking, no continue-on-error)pip install → uv sync --all-groups --frozenflake8 --config=... → uv run flake8pytest tests → uv run pytest testsuv version $TAG_VERSIONUV_PUBLISH_TOKEN, UV_PUBLISH_TOKEN_TEST_PYPI[MIN_VERSION, "3.13", "3.14"] (min + 2 latest)uv sync --all-groups
uv build
# Should create dist/*.tar.gz and dist/*.whl
uv version 1.7.0 --dry-run
# Should show: package-name 0.0.0 => 1.7.0
git add .github/workflows/*.yml uv.lock
git commit -m "uv 💜"
git push origin BRANCH_NAME
git tag 1.7.0
git push origin 1.7.0
Manually trigger Test PyPI workflow:
Verify on Test PyPI:
Test installation:
cd /tmp && mkdir test_install && cd test_install
uv init
uv add --index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple/ \
--index-strategy unsafe-best-match \
PACKAGE_NAME==1.7.0
uv run python -c "import PACKAGE; print('✅ Works!')"
cd .. && rm -rf test_install
Create PR (see templates/pr-description.md.template)
Get approval and merge to main
Create production release:
1.8.0main1.8.0Workflow auto-triggers → Publishes to PyPI
Verify production:
cd /tmp && mkdir test_prod && cd test_prod
uv init
uv add PACKAGE_NAME==1.8.0
uv run python -c "import PACKAGE; print('✅ Production works!')"
cd .. && rm -rf test_prod
Smart matrix logic:
python-version: [
"MIN_SUPPORTED", # max(3.8, current_requires_python)
"3.13", # Second-latest stable
"3.14" # Latest stable
]
Examples:
["3.8", "3.13", "3.14"]["3.10", "3.13", "3.14"]["3.12", "3.13", "3.14"]Rationale: Test minimum (compatibility floor) + 2 latest (future-proofing)
Detection:
# Check if push_main.yml exists AND contains pdoc
if [ -f .github/workflows/push_main.yml ] && grep -q pdoc .github/workflows/push_main.yml; then
# Include docs workflow in migration
# Add pdoc3 to [dependency-groups] dev
fi
Migration for docs:
pip install --user pdoc3 (ad-hoc)pdoc3 to [dependency-groups] dev + use uv run pdocRequired GitHub secrets:
UV_PUBLISH_TOKEN - Production PyPI token
UV_PUBLISH_TOKEN_TEST_PYPI - Test PyPI token
Note: uv automatically uses __token__ as username when UV_PUBLISH_TOKEN env var is set
Test PyPI: on: workflow_dispatch (manual)
Production PyPI: on: push: tags: ['*'] (automatic)
git tag X.Y.Z && git push origin X.Y.ZSee references/troubleshooting.md for detailed troubleshooting guide.
Quick fixes:
License classifier conflict
License classifiers have been supersededLicense :: OSI Approved :: MIT License from classifiersCRLF line endings
Test PyPI installation fails
No solution found--index-strategy unsafe-best-matchuv version command not found
100% modern uv - ZERO pip mentions:
✅ CORRECT:
uv add PACKAGE - Add production dependencyuv add --dev PACKAGE - Add dev dependencyuv sync --all-groups --frozen - Install from lockuv run COMMAND - Run command in environmentuv build - Build packageuv publish - Publish to PyPI❌ NEVER USE:
pip install - OLDpip - OLDuv pip install - WRONG uv usagereferences/migration-guide.md - Complete step-by-step guidereferences/workflow-templates.md - All 4 workflow YAML filesreferences/troubleshooting.md - Common issues and solutionsreferences/examples.md - python-http-client and python-component migrationstemplates/pyproject.toml.template - Template pyproject.tomltemplates/flake8.template - Template .flake8templates/pr-description.md.template - PR description templateBefore starting:
Migration complete when:
uv build)Remember: This is a build system migration, NOT an API change. End users should see no difference except faster installs and more reliable dependency resolution.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.