Repository containing howto guides for python development and shared linting and formatting settings using ruff and mypy.
- Using UV for Python Project & Environment Management
- Python formatting and linting
This guide explains how to install UV, set up a project, manage environments, and install dependencies using modern Python packaging practices.
UV is a fast Python package and environment manager from Astral. Install it using one of the options below.
brew install uvcurl -LsSf https://astral.sh/uv/install.sh | shUV can generate a clean project structure following modern Python packaging standards.
Create a new Python project (in this example we call the project cyclops-dev but this is arbitrary) managed by uv:
uv init cyclops-devs --packageTo specify a particular Python version:
uv init cyclops-devs --package --python=3.12After initialization, your folder will look like this:
cyclops-dev
βββ pyproject.toml
βββ README.md
βββ src
βββ cyclops_dev
βββ __init__.py
pyproject.tomlβ stores dependencies and project metadata.src/β contains your Python source code.
Keep notebooks separate from your package code to avoid mixing experimental work with production modules.
cyclops-dev
βββ notebooks
β βββ exploration.ipynb
βββ pyproject.toml
βββ README.md
βββ src
βββ cyclops_dev
βββ __init__.py
UV automatically creates an isolated environment and installs dependencies in one step. From your project root:
uv syncThis generates:
cyclops-dev
βββ .venv
βββ pyproject.toml
βββ README.md
βββ src
This will:
-
Create a
.venv/folder -
Install dependencies from
pyproject.toml
Activate the environment:
source .venv/bin/activateAdd all the required dependency needed to deploy and run your code. This excludes development dependencies like jupyterlab and potentially matplotlib. These development dependencies might be used for research and development but are not required when deploying the code.
uv add numpyCreate a separate dependency list for additional dependencies that are only needed for your development environment.
uv add jupyterlab --devIn case you want migrate your dependencies from a requirements.txt file (used by pip) to a pyproject.toml (used by uv), you can use the following command:
uv add -r requirements.txtuv automatically updates your pyproject.toml with these dependencies.
Configuring Ruff locally allows developers to catch and resolve issues in real-time as they write code. Ruff is used for code formatting. Below the steps to setup Ruff for local development.
-
Install Ruff: Here we assume that you are in a repository that already contains the
pyproject.tomlfile withruffandmypylisted as dependencies. First thing to do is sync your environment so the dependencies are installed in your local virutal environment:uv sync
In case ruff and mypy are not listed as dependencies you can add them the
lintinggroup:uv add --group linting ruff mypy
-
Copy the Ruff configuration file: The Ruff formatting rules are specified in the
ruff.tomlfile in this repository (python-dev-standards). Copy theruff.tomlfile from this repository to root directory of your own repository.
You can run Ruff from your terminal to format code or check for issues.
- Format the entire project:
ruff format . - Format a specific folder:
ruff format path/to/your/folder/
- Format a single file:
ruff format path/to/your/file.py
- Check the entire project and apply automatic fixes:
ruff check . --fix - Check a specific folder (without fixing):
ruff check path/to/your/folder/
- Check a single file (without fixing):
ruff check path/to/your/file.py
-
Install the Ruff Extension: Install the official Ruff extension from the VS Code Marketplace.
-
Configure VS Code Settings: Create or open the
.vscode/settings.jsonfile in your project's root directory and add the following configuration. This ensures everyone on the team uses the same settings for this project.{ // Enable format on save for all files "editor.formatOnSave": true, // Set Ruff as the default formatter for Python files "[python]": { "editor.defaultFormatter": "charliermarsh.ruff" }, // Run Ruff's "fixAll" and "organizeImports" actions on save. // This applies linting fixes before formatting. "editor.codeActionsOnSave": { "source.fixAll": "explicit", "source.organizeImports": "explicit" } }
This project uses Mypy for static type checking, which helps ensure type safety and prevent common bugs. The configuration is defined in the mypy.ini file. Copy the mypyp.ini file to your repositories root directory.
All linting dependencies and stubs for mypy (types-* packages), are managed in the pyproject.toml file under the [dependency-groups.linting] group.
To add a new type stub for a library (e.g., requests) to the linting group, use the uv add command:
uv add types-requests --group lintingThis will automatically update your pyproject.toml file.
To run mypy:
- Check the entire project:
mypy . - Check a specific folder:
mypy path/to/your/folder/
- Check a single file:
mypy path/to/your/file.py
- Install the Mypy Type Checker Extension: Install the official Mypy Type Checker extension from the VS Code Marketplace.
Our repositories use pre-commit to automatically check code formatting and type annotations before committing changes. The hooks configured in the .pre-commit-config.yaml file ensure that:
- Ruff runs to check for code style issues and automatically fix them.
- Mypy checks for type annotations and ensures type safety.
-
Install Pre-commit: If you haven't already, install the
pre-commitpackage:pip install pre-commit
-
Install the Hooks: Run the following command to install the hooks defined in your
.pre-commit-config.yaml:pre-commit install
Once the hooks are installed, they will automatically run every time you attempt to commit changes. This means you don't have to manually run ruff or mypyβthe pre-commit hooks will handle it for you. If there are any issues found by Ruff or Mypy, the commit will be blocked until those issues are resolved.
If you want to run the hooks manually at any time, you can do so with the following commands:
-
Run all hooks on all files:
pre-commit run --all-files
-
Run a specific hook (e.g., Mypy):
pre-commit run mypy --all-files
-
Run a specific hook (e.g., Ruff):
pre-commit run ruff --all-files