You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: best_practice/index.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -424,9 +424,9 @@ If there is anything you don't understand, **ask on slack**!
424
424
- Follow conventional variable naming
425
425
- Example: https://docs.fast.ai/dev/abbr.html
426
426
- See the [Working with Python Environments](/best_practice/python_environments) guide for details on installing Python versions and managing virtual environments.
427
-
- All repos should use [poetry](https://python-poetry.org/)
428
-
- Set up this way: `poetry new --src my-project-name`
429
-
- OR use `linkml-ws new` for schema-centric repos
427
+
- All repos should use [uv](https://github.com/astral-sh/uv)
428
+
- Set up this way: `uv init --package my-project-name`
429
+
- OR use [`linkml-project-copier`](https://github.com/linkml/linkml-project-copier) for schema-centric repos
430
430
- follow standard layouts, with code in `src/`
431
431
- Linting/formatting:
432
432
- Use [black](https://github.com/psf/black) and [flake8](https://pypi.org/project/flake8/) and ruff
## Managing Python Versions and Virtual Environments with uv
8
8
9
-
Most projects we work on require Python 3.8 or greater. A few projects may require an even later version. In either case it is necessary to be able to have multiple versions of Python installed and easily switch between them. Both can be accomplished using [pyenv](https://github.com/pyenv/pyenv).
9
+
Most projects we work on require Python 3.9 or greater. Many require a later version. In either case it is necessary to be able to have multiple versions of Python installed and easily switch between them, as well as manage project-specific dependencies. We use [uv](https://github.com/astral-sh/uv) to handle both Python version management and virtual environments.
10
10
11
-
### Installing pyenv
11
+
### Installing uv
12
12
13
-
Use one of the [recommended installation methods](https://github.com/pyenv/pyenv#installation). If you are using Windows use the [pyenv-win fork](https://github.com/pyenv-win/pyenv-win/blob/master/docs/installation.md).
13
+
Follow [uv's recommended installation methods](https://github.com/astral-sh/uv#installation). The quickest way is usually:
14
+
15
+
```shell
16
+
curl -LsSf https://astral.sh/uv/install.sh | sh
17
+
```
18
+
19
+
Or on macOS with Homebrew:
20
+
21
+
```shell
22
+
brew install uv
23
+
```
14
24
15
25
To verify that the installation was successful run the following and ensure that it prints out a version number:
16
26
17
27
```shell
18
-
pyenv --version
28
+
uv --version
19
29
```
20
30
21
31
### Installing Python Versions
22
32
23
-
Running the `pyenv versions` command will list the versions of Python that pyenv knows about. If you just installed pyenv the output should say that either no Python version are installed:
33
+
uv can install and manage Python versions directly. To see available Python versions:
34
+
35
+
```shell
36
+
uv python list --all-versions
37
+
```
38
+
39
+
To install a specific Python version:
24
40
25
41
```shell
26
-
$ pyenv versions
27
-
Warning: no Python detected on the system
42
+
uv python install 3.11
28
43
```
29
44
30
-
Or that a system version (not managed by pyenv) is installed and active (denoted by the asterisk):
45
+
Or install the latest patch version of a minor release:
31
46
32
47
```shell
33
-
$ pyenv versions
34
-
* system (set by [...]/.pyenv/version)
48
+
uv python install 3.11 # Installs latest 3.11.x
35
49
```
36
50
37
-
Use the `pyenv install` command to install new versions of Python that will be managed by pyenv. For example to install a Python 3.8 version[^1]:
51
+
To see which Python versions are currently installed:
38
52
39
53
```shell
40
-
pyenv install 3.8.15
54
+
uv python list
41
55
```
42
56
43
-
This can be repeated for any other versions you would like to install. The `pyenv install --list` command will show all the versions available for installation.
57
+
### Selecting a Python Version for Your Project
44
58
45
-
Once you have a few Python versions installed by pyenv, verify they are listed in the output of `pyenv versions`:
59
+
When creating a new project, you can specify which Python version to use:
46
60
47
61
```shell
48
-
pyenv versions
49
-
* system (set by [...]/.pyenv/version)
50
-
3.8.15
51
-
3.9.15
52
-
3.10.8
62
+
uv init --python 3.11 my-project
63
+
cd my-project
53
64
```
54
65
55
-
### Selecting a Python Version
66
+
For existing projects, uv will use the Python version specified in the `pyproject.toml` file's `requires-python` field. You can also specify a Python version when syncing:
56
67
57
-
pyenv allows setting a Python version at three levels: global, local, and shell[^2]. When getting set up for the first time, the most important version to set is the global version. Depending on the projects you work on, you may never use local or shell versions at all.
68
+
```shell
69
+
uv sync --python 3.11
70
+
```
58
71
59
-
To set the global Python version use the `pyenv global <version>` command. For example:
72
+
Or pin a specific Python version for your project:
60
73
61
74
```shell
62
-
pyenv global 3.8.15
75
+
uv python pin 3.11
63
76
```
64
77
65
-
Verify that this version is now the default Python version by running:
78
+
This creates a `.python-version` file in your project directory that uv will respect.
79
+
80
+
## Managing Virtual Environments
81
+
82
+
uv automatically creates and manages virtual environments for your projects. By default, it creates them in a `.venv` directory within your project folder.
83
+
84
+
### Creating Virtual Environments
85
+
86
+
For a new project:
66
87
67
88
```shell
68
-
$ python --version
69
-
Python 3.8.15
89
+
uv init my-project
90
+
cd my-project
91
+
uv sync
70
92
```
71
93
72
-
The selected version can also be verified with the `pyenv versions`. The asterisk indicates the currently selected Python version:
94
+
You can also create a project with a specific structure:
73
95
74
96
```shell
75
-
$ pyenv versions
76
-
system
77
-
* 3.8.15 (set by [...]/.pyenv/version)
78
-
3.9.15
79
-
3.10.8
97
+
uv init --package my-project # Creates a package structure
98
+
uv init --app my-project # Creates an application structure
80
99
```
81
100
82
-
## Managing Virtual Environments
101
+
For an existing project with a `pyproject.toml` file:
83
102
84
-
Dependencies for different projects need to managed independently in what Python calls virtual environments. Generally each project will have one virtual environment and we use [Poetry](https://python-poetry.org/docs/) to manage those environments.
103
+
```shell
104
+
uv sync
105
+
```
85
106
86
-
### Installing Poetry
107
+
This will:
108
+
- Create a virtual environment in `.venv`
109
+
- Install the Python version specified in `pyproject.toml`
110
+
- Install all project dependencies
87
111
88
-
First you should have at least one Python 3.7+ version installed and set as the global version through pyenv. Then follow [Poetry's recommended installation methods](https://python-poetry.org/docs/#installation).
112
+
### Adding Dependencies
89
113
90
-
To verify that the installation was successful run the following and ensure that it prints out a version number:
114
+
Use `uv add` to add new dependencies to your project:
91
115
92
116
```shell
93
-
poetry --version
117
+
uv add requests
94
118
```
95
119
96
-
### Configuring Poetry
120
+
This updates your `pyproject.toml` and `uv.lock` files and installs the package.
97
121
98
-
By default Poetry creates virtual environments in one central location. However, we find it more convenient to have the virtual environment created within the project directory itself (specifically in a directory called `.venv`). This behavior can be enabled by running:
122
+
For development dependencies:
99
123
100
124
```shell
101
-
poetry config virtualenvs.in-project true
125
+
uv add --dev pytest black mypy
102
126
```
103
127
104
-
By default Poetry has its own mechanism for locating (but **not** installing) different Python versions[^3]. This can cause some confusion when used alongside pyenv. Instead of having Poetry attempt to find the right Python version when creating a virtual environment, we want to use pyenv to activate an appropriate version and then use that version to create the virtual environment[^4]. To allow that to work set the following option:
If you start working on an existing project that already uses Poetry (i.e. it has a `pyproject.toml` and `poetry.lock` file in the root of the project), first ensure that you have a compatible Python version. You can find out which Python versions are acceptable for the project by looking at the `python` entry in the `tool.poetry.dependencies` section of the `pyproject.toml` file. If necessary install and/or activate a compatible Python version using pyenv as described above.
136
+
Update a specific package:
113
137
114
-
Next create the virtual environment and install the projects dependencies into it by running:
138
+
```shell
139
+
uv add requests@latest
140
+
```
141
+
142
+
Update to a specific version:
115
143
116
144
```shell
117
-
poetry install
145
+
uv add requests==2.31.0
118
146
```
119
147
120
-
To start a new project that uses Poetry use either the `poetry new` or `poetry init` command. `poetry new` generates a simple project directory structure, including a `pyproject.toml` file, based on a name you provide. Using the `--src` option to create a `src` directory is recommended:
148
+
Update all packages to their latest compatible versions:
121
149
122
150
```shell
123
-
poetry new --src my-project
124
-
cd my-project
125
-
poetry install
151
+
uv sync --upgrade
126
152
```
127
153
128
-
`poetry init` will interactively prompt you to build a custom `pyproject.toml` file. It does not create any other files.
Use `poetry add` to add a new dependency to a project.
162
+
View the dependency tree:
140
163
141
164
```shell
142
-
poetry add requests
165
+
uv tree
143
166
```
144
167
145
-
This will install the requests package into the project's virtual environment, add it to the `pyproject.toml` file, and update the `poetry.lock` file with information about the exact version installed.
168
+
Show outdated packages:
146
169
147
-
In order to synchronize your poetry.lock file with any manual changes to pyproject.yaml directly, be sure to run:
148
170
```shell
149
-
poetry lock --no-update
171
+
uv pip list --outdated
150
172
```
151
173
152
-
### Updating Dependencies
174
+
### Running Commands
153
175
154
-
The `poetry add` command can also be used to upgrade a package to a particular version (or range of versions):
176
+
Run commands in the project's virtual environment:
155
177
156
178
```shell
157
-
poetry add requests@^2.25.0
179
+
uv run python src/main.py
180
+
uv run pytest
181
+
uv run black .
158
182
```
159
183
160
-
Or automatically upgrade to the latest version:
184
+
For interactive sessions, you can activate the virtual environment:
161
185
162
186
```shell
163
-
poetry add requests@latest
187
+
source .venv/bin/activate # On Unix/macOS
188
+
# or
189
+
.venv\Scripts\activate # On Windows
190
+
191
+
python src/main.py # Uses the virtual environment's Python
192
+
deactivate # Exit the virtual environment
164
193
```
165
194
166
-
To update a dependency to the latest version that still respects what is specified in `pyproject.toml` use the `poetry update` command:
195
+
## Advanced Features
196
+
197
+
### Running Tools Without Installation
198
+
199
+
Run Python tools without installing them globally:
167
200
168
201
```shell
169
-
poetry update requests
202
+
uv tool run black .
203
+
uv tool run --from ruff ruff check
204
+
uv tool run --python 3.12 mypy src/
170
205
```
171
206
172
-
If you need to debug a dependency tree, use the `poetry show` command:
207
+
### Installing Global Tools
208
+
209
+
Install tools globally for command-line use:
173
210
174
211
```shell
175
-
poetry show --tree my_package
212
+
uv tool install black
213
+
uv tool install ruff
176
214
```
177
215
178
-
### Running Commands
216
+
### Working with Scripts
179
217
180
-
Use the `poetry run` command to run commands in the project's virtual environment. For example to run an arbitrary Python module:
218
+
Run Python scripts with inline dependencies:
181
219
182
220
```shell
183
-
poetry run python src/main.py
221
+
uv run --with pandas,matplotlib analysis.py
184
222
```
185
223
186
-
Or if your project (or one of its dependencies) provides a CLI (e.g. pytest):
224
+
Create self-contained scripts with dependency declarations:
225
+
226
+
```python
227
+
# /// script
228
+
# requires-python = ">=3.11"
229
+
# dependencies = [
230
+
# "requests",
231
+
# "rich",
232
+
# ]
233
+
# ///
234
+
235
+
import requests
236
+
from rich importprint
237
+
238
+
response = requests.get("https://api.github.com")
239
+
print(response.json())
240
+
```
241
+
242
+
Then run it with:
187
243
188
244
```shell
189
-
poetry run pytest
245
+
uv run script.py
190
246
```
191
247
192
-
For interactive sessions it may be more convenient to activate the virtual environment in which case `poetry run` will not be necessary. This can be accomplished by running:
248
+
### Working with Requirements Files
249
+
250
+
Export dependencies to a requirements file:
193
251
194
252
```shell
195
-
poetry shell
196
-
python src/main.py # this will use the virtual environment's Python version
197
-
exit# deactivate the virtual environment
253
+
uv pip compile pyproject.toml -o requirements.txt
198
254
```
199
255
200
-
## Further Reading
256
+
Install from a requirements file:
201
257
202
-
*[Documentation on all pyenv subcommands](https://github.com/pyenv/pyenv/blob/master/COMMANDS.md#command-reference)
203
-
*[Documentation on all poetry subcommands](https://python-poetry.org/docs/cli/)
258
+
```shell
259
+
uv pip sync requirements.txt
260
+
```
261
+
262
+
## Migrating from Other Tools
263
+
264
+
### From pip/venv
265
+
266
+
If you have a `requirements.txt` file:
267
+
268
+
```shell
269
+
uv init
270
+
uv pip sync requirements.txt
271
+
uv add --dev <your-dev-packages>
272
+
```
204
273
205
-
## Footnotes
274
+
### From Poetry
275
+
276
+
uv can read `pyproject.toml` files created by Poetry. Simply run:
277
+
278
+
```shell
279
+
uv sync
280
+
```
281
+
282
+
To fully migrate, you may want to:
283
+
1. Remove the `[tool.poetry]` sections from `pyproject.toml`
284
+
2. Delete `poetry.lock`
285
+
3. Run `uv sync` to generate `uv.lock`
286
+
287
+
## Further Reading
206
288
207
-
[^1]: Use `pyenv latest --known <prefix>` to list latest version that matches `<prefix>`. For example: `pyenv latest --known 3.8`.
208
-
[^2]: This guide mainly focuses on setting the global Python version. See the pyenv documentation for more information about setting [local](https://github.com/pyenv/pyenv/blob/master/COMMANDS.md#pyenv-local) and [shell](https://github.com/pyenv/pyenv/blob/master/COMMANDS.md#pyenv-shell) versions.
209
-
[^3]: For more information see the `poetry env`[documentation](https://python-poetry.org/docs/managing-environments/), but it **not** recommended to use this feature in conjunction with pyenv.
210
-
[^4]: If an incompatible Python version was active when you attempt to create a virtual environment via `poetry install` you will see a message like: `The currently activated Python version 3.8.15 is not supported by the project (^3.9.0).` Or, when attempting to run the Python executable: `Current Python version (3.8.15) is not allowed by the project (^3.9.0).` In this case, instead of using the `poetry env` command just delete the virtual environment (`rm -rf .venv`), ensure a compatible Python version is activated via pyenv (`pyenv global 3.9.15`), and recreate the virtual environment (`poetry install`)
0 commit comments