"]
+requires-python = ">=3.14"
+dependencies = [
+ "typer>=0.21.0",
+]
-[tool.poetry.scripts]
+[project.scripts]
rick-portal-gun = "rick_portal_gun.main:app"
-[tool.poetry.dependencies]
-python = "^3.10"
-typer = "^0.12.0"
-
[build-system]
-requires = ["poetry-core"]
-build-backend = "poetry.core.masonry.api"
+requires = ["uv_build>=0.8.14,<0.9.0"]
+build-backend = "uv_build"
```
Here's what that line means:
@@ -209,7 +204,7 @@ from rick_portal_gun.main import app
app()
```
-That config section tells Poetry that when this package is installed we want it to create a command line program called `rick-portal-gun`.
+That config section tells uv that when this package is installed, we want it to create a command line program called `rick-portal-gun`.
And that the object to call (like a function) is the one in the variable `app` inside of the module `rick_portal_gun.main`.
@@ -222,20 +217,22 @@ You can now install it:
```console
-$ poetry install
+$ uv sync
-Installing dependencies from lock file
+Resolved 10 packages in 1ms
+ Built rick-portal-gun @ file:/home/rick-portal-gun
+Prepared 1 package in 18ms
+Uninstalled 1 package in 1ms
+Installed 1 package in 13ms
+ ~ rick-portal-gun==0.1.0 (from file:/home/rick-portal-gun)
-No dependencies to install or update
-
- - Installing the current project: rick-portal-gun (0.1.0)
```
## Try your CLI program
-Your package is installed in the environment created by Poetry, but you can already use it.
+Your package is installed in the environment created by uv, but you can already use it.
@@ -244,7 +241,7 @@ Your package is installed in the environment created by Poetry, but you can alre
$ which rick-portal-gun
// You get the one from your environment
-/home/rick/.cache/pypoetry/virtualenvs/rick-portal-gun-w31dJa0b-py3.10/bin/rick-portal-gun
+/home/rick-portal-gun/.venv/bin/rick-portal-gun
// Try it
$ rick-portal-gun --help
@@ -261,8 +258,8 @@ Options:
--help Show this message and exit.
Commands:
- load Load the portal gun
shoot Shoot the portal gun
+ load Load the portal gun
```
@@ -271,18 +268,17 @@ Commands:
Python packages have a standard format called a "wheel". It's a file that ends in `.whl`.
-You can create a wheel with Poetry:
+You can create a wheel with uv:
```console
-$ poetry build
+$ uv build
-Building rick-portal-gun (0.1.0)
- - Building sdist
- - Built rick-portal-gun-0.1.0.tar.gz
- - Building wheel
- - Built rick_portal_gun-0.1.0-py3-none-any.whl
+Building source distribution (uv build backend)...
+Building wheel from source distribution (uv build backend)...
+Successfully built dist\rick_portal_gun-0.1.0.tar.gz
+Successfully built dist\rick_portal_gun-0.1.0-py3-none-any.whl
```
@@ -415,19 +411,18 @@ You can support that same style of calling the package/module for your own packa
Python will look for that file and execute it.
-The file would live right beside `__init__.py`:
+The file would live right beside `__init__.py` and `main.py`:
``` hl_lines="7"
.
-├── poetry.lock
├── pyproject.toml
├── README.md
-├── rick_portal_gun
-│ ├── __init__.py
-│ ├── __main__.py
-│ └── main.py
-└── tests
- └── __init__.py
+├── src
+│ └── rick_portal_gun
+│ ├── __init__.py
+│ ├── __main__.py
+│ └── main.py
+└── uv.lock
```
No other file has to import it, you don't have to reference it in your `pyproject.toml` or anything else, it just works by default, as it is standard Python behavior.
@@ -439,14 +434,14 @@ from .main import app
app()
```
-Now, after installing your package, if you call it with `python -m` it will work (for the main part):
+Now, after installing your package, if you call it with `python -m` it will work:
```console
$ python -m rick_portal_gun --help
-Usage: __main__.py [OPTIONS] COMMAND [ARGS]...
+Usage: python -m rick_portal_gun [OPTIONS] COMMAND [ARGS]...
Awesome Portal Gun
@@ -457,8 +452,8 @@ Options:
--help Show this message and exit.
Commands:
- load Load the portal gun
shoot Shoot the portal gun
+ load Load the portal gun
```
@@ -469,59 +464,7 @@ Notice that you have to pass the importable version of the package name, so `ric
///
-That works! 🚀 Sort of... 🤔
-
-See the `__main__.py` in the help instead of `rick-portal-gun`? We'll fix that next.
-
-### Set a program name in `__main__.py`
-
-We are setting the program name in the file `pyproject.toml` in the line like:
-
-```TOML
-[tool.poetry.scripts]
-rick-portal-gun = "rick_portal_gun.main:app"
-```
-
-But when Python runs our package as a script with `python -m`, it doesn't have the information of the program name.
-
-So, to fix the help text to use the correct program name when called with `python -m`, we can pass it to the app in `__main__.py`:
-
-```Python
-from .main import app
-app(prog_name="rick-portal-gun")
-```
-
-/// tip
-
-You can pass all the arguments and keyword arguments you could pass to a Click application, including `prog_name`.
-
-///
-
-
-
-```console
-$ python -m rick_portal_gun --help
-
-Usage: rick-portal-gun [OPTIONS] COMMAND [ARGS]...
-
- Awesome Portal Gun
-
-Options:
- --install-completion Install completion for the current shell.
- --show-completion Show completion for the current shell, to copy it or customize the installation.
-
- --help Show this message and exit.
-
-Commands:
- load Load the portal gun
- shoot Shoot the portal gun
-```
-
-
-
-Great! That works correctly! 🎉 ✅
-
-Notice that now it uses `rick-portal-gun` instead of `__main__.py` in the help.
+That works! 🚀
### Autocompletion and `python -m`
@@ -561,12 +504,12 @@ Let's say your new API token is:
pypi-wubalubadubdub-deadbeef1234
```
-Now configure Poetry to use this token with the command `poetry config pypi-token.pypi`:
+Now configure uv to use this token by setting an environment variable:
```console
-$ poetry config pypi-token.pypi pypi-wubalubadubdub-deadbeef1234
+$ export UV_PUBLISH_TOKEN=pypi-wubalubadubdub-deadbeef1234
// It won't show any output, but it's already configured
```
@@ -574,28 +517,16 @@ $ poetry config pypi-token.pypi pypi-wubalubadubdub-deadbeef1234
### Publish to PyPI
-Now you can publish your package with Poetry.
-
-You could build the package (as we did above) and then publish later, or you could tell poetry to build it before publishing in one go:
+Now you can publish your package.
```console
-$ poetry publish --build
-
-# There are 2 files ready for publishing. Build anyway? (yes/no) [no] $ yes
-
----> 100%
-
-Building rick-portal-gun (0.1.0)
- - Building sdist
- - Built rick-portal-gun-0.1.0.tar.gz
- - Building wheel
- - Built rick_portal_gun-0.1.0-py3-none-any.whl
+$ uv publish
-Publishing rick-portal-gun (0.1.0) to PyPI
- - Uploading rick-portal-gun-0.1.0.tar.gz 100%
- - Uploading rick_portal_gun-0.1.0-py3-none-any.whl 100%
+Publishing 2 files https://upload.pypi.org/legacy/
+Uploading rick_portal_gun-0.1.0-py3-none-any.whl (2.3KiB)
+Uploading rick_portal_gun-0.1.0.tar.gz (841.0B)
```
@@ -606,7 +537,7 @@ You should now see your new "rick-portal-gun" package.
### Install from PyPI
-Now to see that we can install it form PyPI, open another terminal, and uninstall the currently installed package.
+Now to see that we can install it from PyPI, open another terminal, and uninstall the currently installed package.
@@ -694,26 +625,26 @@ Now you can publish a new version with the updated docs.
For that you need to first increase the version in `pyproject.toml`:
```TOML hl_lines="3"
-[tool.poetry]
+[project]
name = "rick-portal-gun"
version = "0.2.0"
-description = ""
-authors = ["Rick Sanchez
"]
+description = "Add your description here"
readme = "README.md"
+authors = ["Rick Sanchez "]
+requires-python = ">=3.14"
+dependencies = [
+ "typer>=0.21.0",
+]
-[tool.poetry.scripts]
+[project.scripts]
rick-portal-gun = "rick_portal_gun.main:app"
-[tool.poetry.dependencies]
-python = "^3.10"
-typer = "^0.12.0"
-
[build-system]
-requires = ["poetry-core"]
-build-backend = "poetry.core.masonry.api"
+requires = ["uv_build>=0.8.14,<0.9.0"]
+build-backend = "uv_build"
```
-And in the file `rick_portal_gun/__init__.py`:
+And in the file `src/rick_portal_gun/__init__.py`:
```Python
__version__ = '0.2.0'
@@ -724,19 +655,12 @@ And then build and publish again:
```console
-$ poetry publish --build
-
----> 100%
-
-Building rick-portal-gun (0.2.0)
- - Building sdist
- - Built rick-portal-gun-0.2.0.tar.gz
- - Building wheel
- - Built rick_portal_gun-0.2.0-py3-none-any.whl
+$ uv build
+$ uv publish
-Publishing rick-portal-gun (0.2.0) to PyPI
- - Uploading rick-portal-gun-0.2.0.tar.gz 100%
- - Uploading rick_portal_gun-0.2.0-py3-none-any.whl 100%
+Publishing 2 files https://upload.pypi.org/legacy/
+Uploading rick_portal_gun-0.2.0-py3-none-any.whl (2.3KiB)
+Uploading rick_portal_gun-0.2.0.tar.gz (840.0B)
```
@@ -749,7 +673,7 @@ This is a very simple guide. You could add many more steps.
For example, you should use Git, the version control system, to save your code.
-You can add a lot of extra metadata to your `pyproject.toml`, check the docs for Poetry: Libraries.
+You can add a lot of extra metadata to your `pyproject.toml`, check the docs for Poetry metadata settings.
You could use `pipx` to manage your installed CLI Python programs in isolated environments.