This guide covers setting up a Python development environment using pyenv, poetry, and HashiCorp Vault for secrets management.
# Install pyenv using Homebrew
brew install pyenv
# Add pyenv to your shell (add these to your ~/.zshrc)
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init -)"' >> ~/.zshrc
# Reload your shell
source ~/.zshrccurl -sSL https://install.python-poetry.org | python3 -brew tap hashicorp/tap
brew install hashicorp/tap/hcp
# Login and initialize
hcp auth login
hcp profile init --vault-secretswhy we use poetry and pyenv:
- pyenv ensures your project uses the exact Python version you want, even if it’s not the system default.
- Poetry by itself doesn’t install or manage Python versions — it just uses what’s available.
- Create and activate a new Python environment:
# Install Python version
pyenv install 3.12.2
# Create virtual environment
pyenv virtualenv 3.12.2 project-env-3.12.2
# Activate environment
pyenv activate project-env-3.12.2- Initialize Poetry project:
# Initialize new project
poetry init
# Verify environment
poetry env info
poetry run python --version- Add dependencies:
# Add main dependencies
poetry add fastapi uvicorn
# Add development dependencies
poetry add -G dev pytest black isort mypy# Open secrets
hcp vault-secrets secrets open {desired secret}
# Run application with injected secrets
hcp vault-secrets run -- python3 my_app.pyCreate the following files in your project root:
.cursorignore:
# Ignore virtual environments
.venv/
venv/
__pycache__/
*.pyc
# Ignore build artifacts
dist/
build/
*.egg-info/
# Ignore environment files
.env
.env.*
.cursorrules:
{
"python": {
"formatter": "black",
"linter": "flake8",
"typeChecker": "mypy"
}
}.vscode/settings.json(for Cursor compatibility):
{
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
"python.analysis.typeCheckingMode": "basic",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
}