Skip to main content

Setting up a great python experience

When developing, there are some tools that are more hassle than they are worth, and then there are tools that are worth their weight in gold. It took a while, but I have settled on a solid set of tools that makes working with python a lot easier. This post goes over each of the tools, how to get them setup, and what they ultimately end up accomplishing working in tandem.

Overall objectives

  1. Clean package management per project. The host system should not become cluttered with global installations.
  2. Formatting and linting (in real-time while editing, especially helpful for keeping track of indentation)
  3. Secret detection. Each commit should be checked for things like API keys and environment variables.

Package management

Usually I am not so committed to a single tool, but uv really is the only way to go in 2025 for python package management. It is fast, it makes sense, and it just works. No more python -m venv .venv with opaque packages and difficulties knowing which python version is being used. Instead it is just uv init . and then uv add for packages, uv handles all the rest behind the scenes.

Installing uv

If you are feeling bold

curl -LsSf https://astral.sh/uv/install.sh | sh

If you use cargo

cargo install --git https://github.com/astral-sh/uv uv

All installation options

Usage

Once installed, there are a few common operations that you will want to use right out of the gate. Even if you only use these three commands, I still believe uv is miles ahead of alternatives.

Formatting and linting

For formatting and linting, I use ruff (made by the same people as uv). There are a few options for how to integrate formatting, however the easiest for most people is to integrate it within the editor. If you use VS Code, then the ruff extension is the easiest way to go. This will provide both formatting and linting. For neovim, I use the conform plugin, which applies the formatting on write, and the mason plugin for installation of the linter. Check out my dotfiles for the specifics.

Of course, formatting requirements may differ by the project that you are working on. If a project uses black, then you will have to use that instead. Instead of configuring the formatter globally, formatters can also be used through uv, which we covered in the previous step. Through the uv tools interface, tools can be run without installing them. For example, to run the ruff formatting and linting tool, you can use:

uvx ruff

Secret protection

For a while, I was using ggshield as a global git pre-push hook. However, a lot of projects use pre-commit configurations, and so I wanted to see about bundling pre-commit checks together into that configuration. Since I use lazygit, this also gives me more visibility than the pre-push hook running in the background.

Installing pre-commit

A very nifty trick that I discovered was that pre-commit can be installed through uv, via pre-commit-uv. This simplifies things because I don’t want to have to dig out pip.

uv tool install pre-commit --with pre-commit-uv --force-reinstall

Configuring pre-commit

The configuration for pre-commit is quite simple, and an example configuration with just ggshield is below. This is placed in .pre-commit-config.yml in the root of the repo which the configuration will apply to. You will need to run pre-commit install after the configuration file is in place.

repos:
  - repo: https://github.com/gitguardian/ggshield
    rev: v1.38.0 # This version will change over time
    hooks:
      - id: ggshield
        language_version: python3
        stages: [pre-commit]

This will initiate a check for secrets on every commit.

Conclusion

And with that, package management, formatting, linting, and secret detection, all through uv. Note that these tools can work together in cool and unexpected ways. For example, instead of having formatting and linting down by the editor, you could include it in the pre-commit configuration. There are a lot of choices, so make the ones that work for you.

If you need help with getting setup, feel free to send me an email, happy to answer any questions!