Created by gh-md-toc
-
This cheat sheet explains how to install and to use Python, and associated tools and utilities. Python is a cornerstone of the so-called Modern Data Stack (MDS) in a box. Python powers other data-related tools, such as PySpark, Jupyter Lab, DuckDB, SQLMesh/SQLGlot, Polars, Daft, FastAPI/Flask.
-
There are several ways to install and use Python and the ecosystem built upon Python.
- PyEnv has been available for a while and is now mature enough to be widely used by the majority of users. PyEnv is the solution be default used in these cheat sheets
- uv is the new, shiny, kid on the block,
and may appeal to those seeking to be on the edge of technological trends.
There is at least a very specific use case where uv proves useful, it is
to power standalone Python scripts: it is enough to add the magic
#!/usr/bin/env -S uvcommand as the first line of any Python script, and that latter becomes standalone, self-served on any platform, any where, whithout requiring the users to install anything like dependencies (apart uv itself, obviously)
- Data Engineering Helpers - Knowledge Sharing - Jupyter, PySpark and DuckDB
- Data Engineering Helpers - Knowledge Sharing - Spark
- Data Engineering Helpers - Knowledge Sharing - SQLMesh
- Data Engineering Helpers - Knowledge Sharing - DuckDB
- Material for the Data platform - Modern Data Stack (MDS) in a box
- (old, but somewhat still relevant) Machine Learning Helpers - Knowledge Sharing - Python virtual environments
- GitHub - uv repository
- Astral doc - uv
- Astral doc - Publishing guide
- Motto: A single tool to replace
pip,pip-tools,pipx,poetry,pyenv,twine,virtualenv, and more
- GitHub - Ruff project
- Astral doc - Ruff page
- Motto: an extremely fast Python linter and code formatter, written in Rust
- Specify a version of Python, either globally or locally for the current
project at hand
- Globally:
pyenv global 3.12.12- Locally, for the current project at hand:
pyenv local 3.12.12- Check the current version
- With PyEnv:
pyenv versions
system
* 3.12.12 (set by ~/.pyenv/version)
3.13.4- With Python directly:
python -V
3.12.12- To execute some simple commands, inline, pass the Python code after the
-c(command) parameter of thepythonutility:
python -c "import sys; print(sys.version)"
3.12.12 (main, Oct 12 2025, 18:37:51) [Clang 17.0.0 (clang-1700.3.19.1)]- Retrieve the latest list of Python versions, filtering for some specific
minor version, say
3.12:
pyenv install --list|grep "3\.12\." | grep -v "conda" | grep -v "forge"
3.12.0
...
3.12.12- Install a specific version of Python, say
3.12.12:
pyenv install 3.12.12- To uninstall a specific version of Python, say the
3.12.11, just execute theuninstallcommand:
pyenv uninstall 3.12.11- uv manages project dependencies and environments, with support for lockfiles,
workspaces, and more, similar to
ryeorpoetry
-
Create a sample project, say
example, and move into it:
$ uv init example
Initialized project `example` at `$PWD/example`
$ pushd example- Add Ruff to the project dependencies:
$ uv add ruff
Creating virtual environment at: .venv
Resolved 2 packages in 170ms
Built example @ file://$PWD/example
Prepared 2 packages in 627ms
Installed 2 packages in 1ms
+ example==0.1.0 (from file://$PWD/example)
+ ruff==0.5.0- Audit the code with Ruff:
$ uv run ruff check
All checks passed!- Update the
uv.lockfile (ignored by Git, here):
$ uv lock
Resolved 2 packages in 0.33ms- Synchronize the dependencies:
$ uv sync
Resolved 2 packages in 0.70ms
Audited 1 package in 0.02ms- Leave the project directory:
popduv manages dependencies and environments for single-file scripts.
- Create a new script:
echo 'import requests; print(requests.get("https://astral.sh"))' > example.py- Add inline metadata declaring its dependencies:
uv add --script example.py requests
Updated `example.py`- Then, run the script in an isolated virtual environment:
uv run example.py
Reading inline script metadata from: example.py
Installed 5 packages in 12ms
<Response [200]>- Even better, by adding the
#!/usr/bin/env -S uv runmagic at the beginning of the script, and making it executable (withchmod +x), that latter becomes standalone and may be executed everywhere (whereuvis available), on any platform- Add the magic header to the
example.pyscript:
- Add the magic header to the
echo "#!/usr/bin/env -S uv run" > magic.hdr
cp example.py example2.py
cat magic.hdr example2.py > example.py
rm -f magic.hdr example2.py
chmod +x example.py- Execute the
example.pyscript, anywhere whereuvis available:
./example.py
<Response [200]>- See the uv scripts documentation to get started.
-
This section partially reproduces, for convenience, the tutorial section of the Ruff documentation. See the Ruff documentation for more details or advanced use cases
-
Initialize a Python module/library project, say
numbers:
uv init --lib numbers- This command creates a Python project with the following structure:
numbers
├── README.md
├── pyproject.toml
└── src
└── numbers
├── __init__.py
└── py.typed- We will then replace the contents of
src/numbers/__init__.pywith the following code:
from typing import Iterable
import os
def sum_even_numbers(numbers: Iterable[int]) -> int:
"""Given an iterable of integers, return the sum of all even numbers
in the iterable."""
return sum(
num for num in numbers
if num % 2 == 0
)- Next, we'll add Ruff to our project:
uv add --dev ruff
Using CPython 3.13.1
Creating virtual environment at: .venv
Resolved 2 packages in 445ms
Built numbers @ file://$HOME/dev/ks-cheat-sheets/programming/python/numbers
Prepared 2 packages in 7.66s
Installed 2 packages in 7ms
+ numbers==0.1.0 (from file://$HOME/dev/ks-cheat-sheets/programming/python/numbers)
+ ruff==0.9.6- We can then run the Ruff linter over our project via uv run ruff check:
uv run ruff check!Note: As an alternative to uv run, you can also run Ruff by activating
the project's virtual environment (source .venv/bin/active on Linux and
macOS, or .venv\Scripts\activate on MS Windows) and running ruff check
directly.
- Ruff identified an unused import, which is a common error in Python code.
Ruff considers this a "fixable" error, so we can resolve the issue
automatically by running
ruff check --fix:
uv run ruff check --fix- Running git diff shows the following:
--- a/src/numbers/__init__.py
+++ b/src/numbers/__init__.py
@@ -1,7 +1,5 @@
from typing import Iterable
-import os
-
def sum_even_numbers(numbers: Iterable[int]) -> int:
"""Given an iterable of integers, return the sum of all even numbers in
the iterable."""
return sum(
num for num in numbers
if num % 2 == 0
)- Note Ruff runs in the current directory by default, but you can pass specific paths to check:
uv run ruff check src/numbers/__init__.py- Now that our project is passing ruff check, we can run the Ruff formatter via ruff format:
uv run ruff format- Running
git diffshows that the sum call was reformatted to fit within the default 88-character line length limit:
--- a/numbers.py
+++ b/numbers.py
@@ -3,7 +3,4 @@ from typing import Iterable
def sum_even_numbers(numbers: Iterable[int]) -> int:
"""Given an iterable of integers, return the sum of all even numbers in
the iterable."""
- return sum(
- num for num in numbers
- if num % 2 == 0
- )
+ return sum(num for num in numbers if num % 2 == 0)- Thus far, we have been using Ruff's default configuration. Let us take a look at how we can customize Ruff's behavior
- This section partially reproduces, for convenience, the content of the PyEnv GitHub project. For more details and advance usage, directly visit it
The Homebrew option from the MacOS section below would also work if you have Homebrew installed.
-
Automatic installer (Recommended):
curl -fsSL https://pyenv.run | bash- For more details visit the PyEnv installer project
-
Basic GitHub Checkout
This will get you going with the latest version of Pyenv and make it easy to fork and contribute any changes back upstream.
- Check out Pyenv where you want it installed. A good place to choose is
$HOME/.pyenv(but you can install it somewhere else):
git clone https://github.com/pyenv/pyenv.git ~/.pyenv- Optionally, try to compile a dynamic Bash extension to speed up Pyenv. Don't worry if it fails; Pyenv will still work normally:
cd ~/.pyenv && src/configure && make -C srcThe options from the Linux section above also work but Homebrew is recommended for basic usage.
Homebrew in macOS
-
Update homebrew and install pyenv:
brew update brew install pyenv
- If you want to install (and update to) the latest development head of Pyenv rather than the latest release, instead run:
brew install pyenv --head
-
Then follow the rest of the post-installation steps, starting with Set up your shell environment for Pyenv
-
OPTIONAL. To fix
brew doctor's warning""config" scripts exist outside your system or Homebrew directories"
-
If you are going to build Homebrew formulae from source that link against Python like Tkinter or NumPy (This is only generally the case if you are a developer of such a formula, or if you have an EOL version of MacOS for which prebuilt bottles are no longer provided and you are using such a formula).
-
To avoid them accidentally linking against a Pyenv-provided Python, add the following line into your interactive shell's configuration:
- Bash/Zsh:
alias brew='env PATH="${PATH//$(pyenv root)\/shims:/}" brew'- Fish:
alias brew="env PATH=(string replace (pyenv root)/shims '' \"\$PATH\") brew"Pyenv does not officially support MS Windows and does not work in Windows outside the Windows Subsystem for Linux (WSL). Moreover, even there, the Pythons it installs are not native Windows versions but rather Linux versions running in a virtual machine -- so you will not get Windows-specific functionality.
If you are in Windows, we recommend using @kirankotari's pyenv-win fork -- which does install native Windows Python versions.
-
The below setup should work for the vast majority of users for common use cases. For details and more configuration options, visit directly the PyEnv GitHub project and, in particular, Advanced configuration for details and more configuration options.
-
Stock Bash startup files vary widely between distributions in which of them source which, under what circumstances, in what order and what additional configuration they perform. As such, the most reliable way to get Pyenv in all environments is to append Pyenv configuration commands to both
.bashrc(for interactive shells) and the profile file that Bash would use (for login shells).
-
First, add the commands to
~/.bashrcby running the following in your terminal:echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc echo 'eval "$(pyenv init - bash)"' >> ~/.bashrc
-
Then, if you have
~/.profile,~/.bash_profileor~/.bash_login, add the commands there as well. If you have none of these, create a~/.profileand add the commands there.
- To add to
~/.profile:
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile
echo 'eval "$(pyenv init - bash)"' >> ~/.profile- To add to
~/.bash_profile:
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init - bash)"' >> ~/.bash_profileBash warning: There are some systems where the BASH_ENV variable is
configured to point to .bashrc. On such systems, you should almost certainly
put the eval "$(pyenv init - bash)" line into .bash_profile, and not into
.bashrc. Otherwise, you may observe strange behaviour, such as pyenv getting
into an infinite loop. See
PyEnv issue #264 for details.
- This section partially reproduces, for convenience, the content of the uv installation documentation. For more details and advance usage, directly visit it
- Install uv on MacOS with Homebrew:
brew install uv- Install uv on Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh- Install uv on MS Windows:
# On Windows.
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"- This section partially reproduces, for convenience, the content of the Ruff installation documentation. For more details and advance usage, directly visit it