Skip to content

Commit 2c496d3

Browse files
committed
new post / 2025-08-26-python-uv-cheat-sheet.md
1 parent 1e6a03d commit 2c496d3

4 files changed

Lines changed: 220 additions & 2 deletions

File tree

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
---
2+
authors:
3+
- copdips
4+
categories:
5+
- python
6+
- package
7+
comments: true
8+
date:
9+
created: 2025-08-26
10+
---
11+
12+
# Python uv cheat sheet
13+
14+
Python [UV](https://docs.astral.sh/uv/) common usage cheat sheet, but doesn't cover all the features.
15+
16+
<!-- more -->
17+
18+
## Init project
19+
20+
```bash
21+
# init new project with new folder
22+
uv init my-project -p python3.13
23+
24+
# init an existing project
25+
uv init -p python3.13
26+
```
27+
28+
!!! warning "uv init under a folder with already a pyproject.toml"
29+
If upper folders has already a `pyproject.toml` file, uv will also add the new project (created by `uv init`) as `[tool.uv.workspace]` members. This cheat sheet doesn't cover that. As that makes uv workspace management more complex. You might need to use `uv sync --active` to install dependencies in the separate venv of the sub module if needed.
30+
31+
## Add dependencies
32+
33+
### optional-dependencies vs dependency-groups
34+
35+
Ref:
36+
37+
- [UV's Dependency fields](https://docs.astral.sh/uv/concepts/projects/dependencies/#dependency-fields)
38+
- https://github.com/astral-sh/uv/issues/8981#issuecomment-2466787211
39+
40+
> `optional-dependencies` are part of the published metadata for your package, while `dependency-groups` are only visible when working with your package locally
41+
42+
### Add to dependencies
43+
44+
```bash
45+
uv add fastapi
46+
```
47+
48+
Could be installed by end users with `uv pip install temp`
49+
50+
```toml title="pyproject.toml"
51+
[project]
52+
name = "temp"
53+
...
54+
dependencies = [
55+
"fastapi>=0.116.1",
56+
]
57+
```
58+
59+
### Add to optional dependencies as extra packages
60+
61+
```bash
62+
uv add ruff --optional aio
63+
```
64+
65+
Could be installed by end users with `uv pip install temp[aio]`
66+
67+
```toml title="pyproject.toml"
68+
[project]
69+
name = "temp"
70+
...
71+
[project.optional-dependencies]
72+
aio = [
73+
"aiohttp>=3.12.15",
74+
]
75+
```
76+
77+
### Add to dependency groups
78+
79+
```bash
80+
uv add ruff --dev
81+
# or
82+
uv add ruff --group dev
83+
84+
uv add ty --group typing
85+
```
86+
87+
Dependencies declared in the `dependency-groups` part are not added to the package metadata, so end users cannot install them directly.
88+
89+
```toml title="pyproject.toml"
90+
[project]
91+
name = "temp"
92+
...
93+
[dependency-groups]
94+
dev = [
95+
"ruff>=0.12.4",
96+
]
97+
typing = [
98+
"ty>=0.0.1a19",
99+
]
100+
101+
```
102+
103+
## Install dependencies
104+
105+
```toml title="pyproject.toml"
106+
[project]
107+
name = "temp"
108+
version = "0.1.0"
109+
description = "Add your description here"
110+
readme = "README.md"
111+
requires-python = ">=3.13"
112+
dependencies = [
113+
"fastapi>=0.116.1",
114+
]
115+
116+
# this is the optional extra part, useful for end user
117+
[project.optional-dependencies]
118+
aio = [
119+
"aiohttp>=3.12.15",
120+
]
121+
122+
# this is the local development groups part, useful for developers
123+
[dependency-groups]
124+
dev = [
125+
"ruff>=0.12.4",
126+
]
127+
typing = [
128+
"ty>=0.0.1a19",
129+
]
130+
all = [
131+
{include-group = "dev"},
132+
{include-group = "typing"},
133+
]
134+
```
135+
136+
!!! note "The `--dev`, `--only-dev`, and `--no-dev` flags are equivalent to `--group dev`, `--only-group dev`, and `--no-group dev` respectively."
137+
138+
!!! note "without `--no-dev`, the `dev` group is already installed with `uv sync`"
139+
Use `uv sync --no-dev` or `uv sync --no-default-groups` to avoid installing the `dev` group.
140+
By default, [uv includes the `dev` dependency group](https://docs.astral.sh/uv/concepts/projects/dependencies/#default-groups) in the environment (e.g., during `uv run` or `uv sync`). The default groups to include can be changed using the `tool.uv.default-groups` setting.
141+
142+
!!! note "use `uv sync --dry-run` to see what will be the changes"
143+
144+
- Install dependencies only: `uv sync --no-dev` (without any extra nor any group)
145+
- Install dependencies and `dev` group: `uv sync`
146+
- Install dependencies and all groups (dependency-groups): `uv sync --all-groups`
147+
- Install dependencies and all extras (project.optional-dependencies) and `dev` group: `uv sync --all-extras` (`dev` group is by default)
148+
- Install dependencies and all extras and all groups: `uv sync --all-extras --all-groups`
149+
- Install dependencies and extra `aio` and `dev` group: `uv sync --extra aio`
150+
- Install dependencies and extra `aio` but without `dev` group: `uv sync --extra aio --no-dev`
151+
- Install dependencies and `dev` groups and already installed extraneous packages not declared in pyproject.toml: `uv sync --extra aio --inexact`
152+
153+
- Ensure install by respecting `uv.lock` (ensure uv.lock won't be changed after uv sync) and raise error if lock file doesn't conform with pyproject.toml: `uv sync --locked --no-dev`, in [Dockerfile](https://github.com/astral-sh/uv-docker-example/blob/main/Dockerfile), we often use `uv sync --locked --no-install-project --no-dev`
154+
155+
```bash
156+
$ uv sync --locked --no-dev
157+
Resolved 21 packages in 33ms
158+
The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`.
159+
```
160+
161+
## Dependencies tree
162+
163+
- `uv pip tree`: display the **installed packages** in a tree format.
164+
- `uv tree`: update `uv.lock` based on `pyproject.toml` and display tree based on `uv.lock`, **no package installation will occur**. `uv tree` displays better than `uv tree pip tree`
165+
- `uv tree --frozen`: don't update `uv.lock`, just display tree based on the current `uv.lock`
166+
- `uv tree --locked`: if `uv.lock` is not updated, display a warning message. This command is not very useful.
167+
168+
## List outdated packages
169+
170+
- `uv tree --outdated`: display a list of outdated packages with their latest versions.
171+
172+
## Upgrade packages and uv.lock
173+
174+
- `uv lock`: update the `uv.lock` file to match the current state of `pyproject.toml`.
175+
- `uv lock -U`: update the `uv.lock` file and upgrade all packages to their latest compatible versions.
176+
- `uv sync`: same as `uv lock` but also installs the dependencies.
177+
- `uv sync -U`: same as `uv lock -U` but also installs the dependencies.
178+
179+
!!! note "`uv lock` vs `uv lock -U` and `uv sync` vs `uv sync -U`"
180+
If latest version of fastapi is 0.116.1, and pyproject.toml declares fastapi>=0.115.1, and current uv.lock has fastapi==0.115.1. then:
181+
182+
- `uv lock`: no effect, as `0.115.1` is still within the range of `>=0.115.1`.
183+
- `uv lock -U`: upgrade `fastapi` to `0.116.1`.
184+
185+
Same logic applies to `uv sync` and `uv sync -U`, except for `sync` installing the dependencies too.
186+
187+
## Integrations
188+
189+
Check [this doc](https://docs.astral.sh/uv/guides/integration/) for more information on integrations with other tools and platforms (Docker, Jupyter, Github Actions, Pre Commit, PyTorch FastAPI, etc.).

docs/posts/2025/2025-12-30-sqlalchemy-chaetsheet.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ Just copied from the [official documentation](https://docs.sqlalchemy.org/en/20/
4545
ref: https://docs.sqlalchemy.org/en/20/orm/session_api.html#session-and-sessionmaker
4646

4747
```python hl_lines="11"
48-
from sqlalchemy import create_engine
48+
from sqlalchemy import Engine, create_engine
4949
from sqlalchemy.orm import sessionmaker
5050

5151
# an Engine, which the Session will use for connection resources
52-
engine = create_engine("postgresql+psycopg2://scott:tiger@localhost/")
52+
engine: Engine = create_engine("postgresql+psycopg2://scott:tiger@localhost/")
5353

5454
Session = sessionmaker(engine)
5555
with Session() as session:

docs/posts/2025/scripts/sqlalchemy_multiprocess.db

Whitespace-only changes.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""
2+
https://medium.com/@themightyraider7/multiprocessing-with-sqlalchemy-in-python-65372888cfb8
3+
"""
4+
import multiprocessing
5+
from pathlib import Path
6+
7+
from sqlalchemy import Engine, create_engine, text
8+
9+
# Create an engine with a connection pool in the parent process
10+
engine: Engine = create_engine(f"sqlite:///{Path(__file__).parent}/sqlalchemy_multiprocess.db", pool_size=5)
11+
12+
13+
def get_stuff():
14+
"""
15+
The connection received here is the same
16+
as the one created in the parent process
17+
"""
18+
with engine.connect() as conn:
19+
# And,tada! You might start seeing weird behaviours!
20+
print(conn.execute(text("select 1")).scalar_one_or_none())
21+
22+
23+
# This will create a new connection
24+
with engine.connect() as conn:
25+
# Post execution, the connection is returned to the pool.
26+
conn.execute(text("select 1"))
27+
28+
with multiprocessing.Pool(12) as pool:
29+
pool.apply(get_stuff)

0 commit comments

Comments
 (0)