Skip to main content

Python

Virtual environments

Every project gets its own environment. Installing packages into the system interpreter breaks distribution-managed tooling, and on Debian and Ubuntu it is blocked outright (error: externally-managed-environment).

venv

venv ships with Python, so it is the default choice unless something else is already in use.

# Debian / Ubuntu only: the module is packaged separately
sudo apt install python3-venv python3-pip

python3 -m venv .venv

# Activate
source .venv/bin/activate # Linux, macOS
.venv\Scripts\Activate.ps1 # Windows PowerShell
.venv\Scripts\activate.bat # Windows cmd.exe

deactivate

Once activated, python and pip resolve to the ones inside .venv. Calling them as python -m pip is still worth the habit — it guarantees the packages go to the interpreter you think they do.

python -m pip install requests
python -m pip install "requests==2.32.3" # pin an exact version
python -m pip install --upgrade requests
python -m pip uninstall requests
python -m pip show requests # version, location, dependencies
python -m pip list
python -m pip list --outdated

Recording dependencies

python -m pip freeze > requirements.txt
python -m pip install -r requirements.txt

pip freeze captures the entire resolved environment, transitive dependencies included, which is what you want for a reproducible deployment. For a library, declare only the direct dependencies in pyproject.toml instead.

pipenv

Combines the environment and the lock file. Pipfile records what was asked for, Pipfile.lock records exactly what was installed, with hashes.

python -m pip install --user pipenv

pipenv --python 3.12 # create the environment
pipenv install requests chardet
pipenv install --dev pytest # development-only dependency
pipenv uninstall requests
pipenv shell # spawn a shell inside the environment
pipenv run pytest # run one command inside it, no shell
pipenv --venv # print the environment path
pipenv --rm # delete the environment

Other environment managers

  • uv — resolver and installer written in Rust; drop-in pip/venv replacement and far faster on large dependency trees.
  • Poetry — dependency management plus packaging, driven by pyproject.toml.
  • conda / mamba — manages non-Python dependencies (BLAS, CUDA, compilers) as well, which matters for the scientific stack.
  • pyenv — installs and switches between interpreter versions; complements rather than replaces the above.

Installation on Windows

The official installer offers "Add python.exe to PATH" — tick it. To fix PATH afterwards, add both of these entries, in this order:

C:\Users\USER\AppData\Local\Programs\Python\PythonVERSION\Scripts
C:\Users\USER\AppData\Local\Programs\Python\PythonVERSION

VERSION has no separator: Python 3.12 installs into Python312. The Scripts directory holds pip.exe and any console entry points that packages install.

Windows also ships the py launcher, which works without PATH changes and can select a version explicitly:

py -0p # list installed interpreters and their paths
py -3.12 -m venv .venv

Common commands

# Run a module as a script
python -m http.server 8000

# Unit tests: a single file, then discovery over a package
python -m unittest tests/test_1.py
python -m unittest discover -s tests -p "test_*.py"

# pytest equivalents
pytest tests/test_1.py
pytest -k "keyword" -x # filter by name, stop at the first failure

# Interactive debugger at the point of failure
python -m pdb script.py

unittest discover needs the directory it scans to be importable. Add an __init__.py, or pass -t to name the top-level directory, otherwise tests that import project modules fail with ModuleNotFoundError.

Useful built-ins

chr(65) # 'A' integer -> character
ord('A') # 65 character -> integer
hex(255) # '0xff' integer -> hexadecimal string
bin(5) # '0b101'
int('ff', 16) # 255 parse from any base
format(255, '02X') # 'FF' no prefix, fixed width, upper case

Joining and splitting:

>>> a = ['a', 'b', 'c', 'd']
>>> ''.join(a)
'abcd'
>>> ', '.join(a)
'a, b, c, d'
>>> 'a,b,c'.split(',')
['a', 'b', 'c']

str.join only accepts strings. Convert first when the list holds other types:

>>> ''.join(str(n) for n in [1, 2, 3])
'123'

Bytes and hex, which comes up constantly with firmware images and protocols:

>>> bytes([0xDE, 0xAD]).hex()
'dead'
>>> bytes.fromhex('dead')
b'\xde\xad'
>>> int.from_bytes(b'\x01\x00', 'little')
1
>>> (1024).to_bytes(2, 'little')
b'\x00\x04'

Notable packages

A curated shortlist rather than an exhaustive index — every entry below is actively maintained and installable on current Python versions.

Formatting and linting

PackagePurpose
blackOpinionated formatter. Almost nothing is configurable beyond line length and string quoting, so any two Black-formatted files agree. Stricter than PEP 8 requires.
ruffExtremely fast linter and formatter that reimplements most Flake8, isort and pyupgrade rules in one tool.
flake8Long-standing linter, plug-in ecosystem.
pylintDeeper static analysis than Flake8: detects unused code, naming issues, refactoring opportunities. Slower, noisier by default.
mypy / pyrightStatic type checkers for annotated code.
isortSorts and groups imports.

Text and data processing

PackagePurpose
chardet / charset-normalizerDetect the character encoding of text, HTML or XML. charset-normalizer is the one requests depends on today.
coloramaANSI colour output that also works on Windows terminals.
richColour, tables, progress bars, tracebacks and markup for terminal output.
prettytable / tabulateRender tabular data as ASCII tables.
difflibStandard library; computes differences between sequences.
Levenshtein / rapidfuzzFast edit distance and fuzzy string matching. rapidfuzz supersedes the unmaintained fuzzywuzzy.
regexDrop-in re replacement with fuller Unicode support.
ftfyRepairs text that was decoded with the wrong encoding ("mojibake").
UnidecodeTransliterates Unicode to ASCII.
python-slugifyConverts arbitrary text into URL-safe slugs.
shortuuidCompact, URL-friendly UUIDs.
phonenumbersGoogle libphonenumber port: parse, format and validate phone numbers.
sqlparseNon-validating SQL parser and formatter.
pygmentsSyntax highlighting for many languages.
pyparsing / lark / plyBuild parsers for custom grammars.
pyfigletASCII-art banner text.

Dates and times

PackagePurpose
zoneinfoStandard library since 3.9; IANA time zone support. Prefer it over pytz in new code.
python-dateutilFlexible date-string parsing (parser) and recurrence rules (rrule).
arrow / pendulumFriendlier datetime replacements with time-zone-aware arithmetic.

Documents, spreadsheets and files

PackagePurpose
openpyxlRead and write .xlsx. The usual fix for ModuleNotFoundError: No module named 'openpyxl' is simply installing it into the active environment.
xlsxwriterWrite-only .xlsx with strong charting and formatting support.
xlrdLegacy .xls only; it dropped .xlsx support in 2.0.
xlwingsDrives a running Excel instance from Python.
python-docxRead, create and modify Word .docx files.
pypdfSplit, merge and transform PDFs. Successor to PyPDF2.
pdfplumber / pdfminer.sixExtract text and tables from PDFs.
tablibOne dataset object exported as XLSX, CSV, JSON or YAML.
markdown / mistune / markdown-it-pyMarkdown parsers and renderers.
pathlibStandard library; object-oriented filesystem paths. Prefer it over os.path.
watchdogFilesystem event monitoring.
python-magicFile-type detection from content via libmagic.
pickleStandard library object serialisation. Never unpickle untrusted data — it executes arbitrary code. Use JSON or a schema format for anything crossing a trust boundary.

Configuration and logging

PackagePurpose
configparserStandard library INI parser.
tomllibStandard library TOML reader since 3.11; tomli backports it, tomli-w writes.
PyYAML / ruamel.yamlYAML. Always parse with yaml.safe_load.
python-dotenvLoad .env files into the environment.
pydantic-settingsTyped, validated configuration from environment and files.
loggingStandard library; configure once at start-up, then use module-level loggers.
loguruZero-configuration logging with sensible defaults.
sentry-sdkError reporting and traces to a Sentry server.

Documentation

PackagePurpose
sphinxDocumentation generator; reStructuredText, with Markdown via myst-parser.
mkdocs + mkdocs-materialMarkdown-first documentation site generator.
pdocGenerates API documentation straight from docstrings.

Images and plotting

PackagePurpose
PillowThe imaging library. Maintained fork of the long-dead PIL — import it as PIL.
opencv-pythonOpenCV bindings: image processing, computer vision, classic ML algorithms.
scikit-imageImage processing built on NumPy.
matplotlibThe reference plotting library, MATLAB-like API.
seabornStatistical plots on top of matplotlib, with better defaults.
plotly / bokehInteractive, browser-rendered charts.
pygalSVG charts.
qrcodeQR code generation (python-qrcode on PyPI).
python-barcode1D barcodes without requiring Pillow.
graphvizPython interface to Graphviz layout.
fonttoolsInspect and manipulate TTF/OTF fonts.

Audio, video and games

PackagePurpose
pydubHigh-level audio manipulation; needs ffmpeg for compressed formats.
librosaAudio analysis and feature extraction.
mutagen / tinytagRead and write audio metadata tags.
moviepyScripted video editing, including GIF export.
yt-dlpMedia downloader. Actively maintained successor to youtube-dl.
pygame2D game and multimedia framework built on SDL.
pygletWindowing and multimedia, no external dependencies.
PyOpenGLOpenGL bindings.
Panda3DFull 3D engine with Python bindings, originally from Disney.

Scientific computing and data

PackagePurpose
numpyN-dimensional arrays (ndarray) and vectorised operations (ufunc). The foundation nearly everything else builds on.
scipyOptimisation, linear algebra, integration, interpolation, signal and image processing, ODE solvers, statistics.
pandasLabelled tabular data (DataFrame), time-series handling, I/O for most tabular formats.
polarsDataFrame library with a Rust core; larger-than-memory and multi-threaded workloads.
sympySymbolic mathematics.
statsmodelsStatistical models, hypothesis tests, econometrics.
networkxGraph and network algorithms.
numbaJIT-compiles numeric Python to machine code via LLVM.
cythonCompiles annotated Python to C extensions.
daskParallel and out-of-core execution of NumPy/pandas-style workloads.
pysparkPython API for Apache Spark.
astropy / biopython / rdkitDomain toolkits for astronomy, biology and cheminformatics.

Machine learning and NLP

PackagePurpose
scikit-learnClassification, regression, clustering, model selection and preprocessing with a consistent estimator API. (Imported as sklearn; the old scikits.learn name is long gone.)
pytorch / tensorflowDeep-learning frameworks with GPU support.
xgboost / lightgbmGradient-boosted trees; typically the strongest baselines on tabular data.
transformersPretrained transformer models and pipelines.
spacyIndustrial-strength NLP: tokenisation, tagging, parsing, NER.
nltkTeaching- and research-oriented NLP toolkit with large corpora.
gensimTopic modelling and document similarity.
jiebaChinese word segmentation.
pymcBayesian modelling and probabilistic programming.

Databases

PackagePurpose
sqlite3Standard library; zero-configuration embedded SQL database.
SQLAlchemyCore query builder plus ORM; the de facto standard.
psycopgPostgreSQL driver. Version 3 supersedes psycopg2.
mysqlclientMySQL C-extension driver; the maintained successor to MySQL-python.
PyMySQLPure-Python MySQL driver, no build step.
redisRedis client.
pymongoOfficial MongoDB driver.
peeweeSmall, expressive ORM.
alembicSchema migrations for SQLAlchemy.

Networking and HTTP

PackagePurpose
requestsThe everyday HTTP client. Simpler than urllib and supports sessions, TLS verification and streaming.
httpxrequests-compatible API with HTTP/2 and async support.
aiohttpAsync HTTP client and server.
urllib3Connection pooling and retries; requests is built on it.
pycurllibcurl bindings — faster than urllib, and speaks FTP, SFTP, LDAP and more. Harder to install and to use.
httpieCommand-line HTTP client, friendlier than curl.
scrapyFull crawling and scraping framework.
beautifulsoup4Forgiving HTML/XML parser; copes with malformed markup.
lxmlFast XML/HTML processing with XPath; the recommended parser backend for BeautifulSoup.
pyqueryjQuery-style selectors over HTML.
xmltodictTreat XML as nested dictionaries.
html2textConvert HTML to Markdown.
paramikoSSHv2 client and server implementation.
scapyPacket crafting, sniffing and protocol analysis.
websocketsAsync WebSocket client and server.
pyzmqZeroMQ bindings.
pikaRabbitMQ (AMQP 0-9-1) client.
boto3AWS SDK.
paho-mqttMQTT client, widely used with embedded devices.

Web frameworks

PackagePurpose
djangoBatteries-included MVT framework: ORM, admin, auth, migrations. Best fit for content-heavy applications.
flaskMinimal WSGI framework; you assemble the rest.
fastapiAsync framework with automatic validation and OpenAPI docs from type hints.
starletteASGI toolkit underneath FastAPI.
djangorestframeworkREST APIs on top of Django.
jinja2The standard template engine, used by Flask and many others.
pydanticData validation and settings from type annotations.
celeryDistributed task queue backed by Redis or RabbitMQ.
gunicorn / uvicornProduction WSGI and ASGI servers.
elasticsearchOfficial Elasticsearch client.
wagtail / django-cmsDjango-based content management systems.
pelicanStatic site generator from Markdown or reStructuredText.

Security and cryptography

PackagePurpose
cryptographyThe recommended modern toolkit: hashes, symmetric and asymmetric ciphers, X.509 handling. Replaces the unmaintained PyCrypto.
hashlibStandard library; MD5, SHA-1, SHA-2, SHA-3, BLAKE2 with one API, backed by OpenSSL. MD5 and SHA-1 are broken for signatures — use SHA-256 or better.
secretsStandard library; cryptographically secure random values for tokens and keys. random is not suitable for this.
passlib / argon2-cffi / bcryptPassword hashing with correct salting and work factors.
PyJWTEncode and decode JSON Web Tokens.
authlibOAuth 1/2 and OpenID Connect clients and servers.
ecdsaPure-Python ECDSA; convenient for verifying signatures offline, as in the ESP32 signing example.
pyOpenSSLOpenSSL bindings for protocol-level work.

System and command line

PackagePurpose
argparseStandard library argument parser.
click / typerDeclarative CLIs; typer derives them from type hints.
subprocessStandard library; the supported way to run external commands.
psutilCross-platform process, CPU, memory, disk and network statistics.
threading / asyncio / multiprocessingStandard library concurrency. asyncio for I/O-bound work, multiprocessing to escape the GIL for CPU-bound work.
geventCoroutine-based networking with greenlets.
schedule / APSchedulerIn-process job scheduling.
fabricRun commands over SSH on remote hosts.
ansibleAgentless configuration management and deployment.
cookiecutterGenerate projects from templates.
ctypes / cffiCall C libraries from Python. cffi reads C declarations directly and needs no wrapper module; ctypes needs no build step at all.
pybind11Write C++ extension modules with a modern API.
keyboard / pyautoguiKeyboard, mouse and screen automation.

Testing and debugging

PackagePurpose
unittestStandard library xUnit framework.
pytestThe usual choice: plain assert, fixtures, parametrisation, large plug-in ecosystem.
unittest.mockStandard library test doubles (also on PyPI as mock).
pytest-cov / coverageLine and branch coverage measurement.
hypothesisProperty-based testing; generates inputs that break your assumptions.
responses / respxStub HTTP calls made with requests / httpx.
freezegunFreeze or move datetime.now() in tests.
fakerGenerate realistic fake data.
factory-boyBuild test objects for Django, SQLAlchemy and others.
selenium / playwrightDrive real browsers for end-to-end tests.
locustLoad testing with scenarios written in Python.
pdb / ipdb / pudbInteractive debuggers: standard, IPython-flavoured, full-screen.
memory_profiler / scaleneMemory and combined CPU/memory profiling.
py-spySampling profiler that attaches to a running process without modifying it.
django-debug-toolbarPer-request SQL, cache and timing panels for Django.

Packaging and distribution

PackagePurpose
pipThe package installer.
build + twineBuild wheels and sdists, then upload them to PyPI.
hatchling / setuptools / flitBuild backends configured through pyproject.toml.
wheelThe binary distribution format; replaced eggs.
pyinstallerBundle an application and its interpreter into a standalone executable, on all major platforms.
cx_FreezeSame idea, different trade-offs.
py2appmacOS application bundles.
pynsistWindows installers that ship a normal Python installation.
devpiPrivate PyPI server, mirroring and staging.

Industrial and hardware

PackagePurpose
pyserialSerial port access on Windows, macOS, Linux and BSD. Import it as serial.
pymodbusModbus RTU and TCP client and server.
python-canCAN bus interface layer across many adapters.
esptoolEspressif flashing tool for ESP8266 and ESP32.
RPi.GPIO / gpiozeroRaspberry Pi GPIO access.
pyvisaControl lab instruments over GPIB, USB, serial and Ethernet.

Troubleshooting

VS Code does not see the pipenv environment

The interpreter selected in VS Code is not the pipenv one. Get the path, then select it:

pipenv --venv

Press Ctrl+Shift+P, run Python: Select Interpreter, and either pick the entry matching that path or choose Enter interpreter path… and point at <venv>/bin/python (<venv>\Scripts\python.exe on Windows).

Pin it per project so the choice survives a reload — .vscode/settings.json:

{
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python"
}

Setting PIPENV_VENV_IN_PROJECT=1 before pipenv install places the environment in .venv inside the project, which VS Code detects on its own.

Reload the window after switching interpreters — the language server keeps the old environment cached until it restarts.

ModuleNotFoundError for a package you just installed

Almost always a wrong-environment problem. Confirm which interpreter is running and where its packages come from:

python -c "import sys; print(sys.executable)"
python -m pip -V # prints the pip path and the interpreter it serves

If those two disagree, the environment is not active. Reactivate it and install with python -m pip install PACKAGE.

error: externally-managed-environment

Debian, Ubuntu and Homebrew mark the system interpreter as managed by the OS package manager. Create a virtual environment instead. --break-system-packages exists but does what its name says.