Python Project with UV and Git

Open a Git Bash terminal.

Initialise the project

A folder with a pyproject.toml is recognised as a project

uv init my_project --python 3.10
cd my_project

Take a look at the project

ls -a
cat pyproject.toml

Create a virtual environment

Install the Python version in .python-version

uv venv

If a different Python version is required

uv venv --python 3.13

Activate the virtual environment

source .venv/scripts/activate

Check that main.py can be executed

uv run main.py

Make source code directory and move main.py

mkdir -p src/my_project
mv main.py src/my_project/main.py

Add the build system to pyproject.toml

echo '' >> pyproject.toml
echo '[build-system]' >> pyproject.toml
echo 'requires = ["hatchling"]' >> pyproject.toml
echo 'build-backend = "hatchling.build"' >> pyproject.toml
echo '' >> pyproject.toml
echo '[tool.hatch.build.targets.wheel]' >> pyproject.toml
echo 'packages = ["src/my_project"]' >> pyproject.toml

Add project dependencies

UV will automatically install dependencies and add them to pyproject.toml

uv add plotly scikit-learn "pandas[computation,excel,output-formatting,performance,plot]"

Remove dependencies like so

uv remove matplotlib

Add optional developer dependencies

uv add --dev pytest
```bash

Check that pyproject.toml has been updated
```bash
cat pyproject.toml

Check if the dependencies were installed in venv

uv pip list

Create a Git and GitHub repository

UV already created a .git directory; to re-initialise

git init

Check that you're on the master branch with no commits yet and all files untracked

git status

Stage all files

git add .

Make initial commit

uv sync
git commit -m "initial commit"

Go to https://github.com/stabilefrisur?tab=repositories to add a new GitHub repository my_project

Establish the remote connection

git remote add origin https://github.com/stabilefrisur/my_project.git

Push to GitHub

git branch -M master
git push -u origin master

Stop tracking private files

Remove private files from staging

git rm -r --cached private_file

Add private folder and file names to .gitignore, such as docs/ *.log todo.md

Create a Git branch and merge into master

Create a new branch

git checkout -b new_feature

Stage all code changes

git add .

Commit code changes

git commit -m "Add new feature"

Push the new branch to GitHub

git push -u origin new_feature

Start a pull request:

Merge the pull request into master:

Delete the new_feature branch locally and remotely:

git checkout master
git pull origin master
git branch -d new_feature
git push origin --delete new_feature

Register and run main.py

Register an entry point to the package

echo '[project.scripts]' >> pyproject.toml
echo 'my_project = "my_project.main:main"' >> pyproject.toml

Install the package in editable mode

uv pip install -e .

The local package will now be listed in pip

uv pip list

Run the main program which is now registered under my_project

uv run my_project

Configure and run pytest

Make tests directory for pytest

mkdir tests

Add the tests path to pyproject.toml

echo '' >> pyproject.toml
echo '[tool.pytest.ini_options]' >> pyproject.toml
echo 'pythonpath = "src"' >> pyproject.toml
echo 'testpaths = "tests"' >> pyproject.toml

Run pytest

pytest

Build and publish the package

Exclude private folders from PyPi package

echo '' >> pyproject.toml
echo '[tool.hatch.build]' >> pyproject.toml
echo 'exclude = ["docs", "output"]' >> pyproject.toml

Update the project environment

uv sync

Delete the dist directory

Build Python packages into source distributions and wheels

uv build

Commit changes and push to GitHub before publishing

git add .
git commit -m "MESSAGE"
git push -u origin master

Upload distributions to an index; input PyPi credentials

uv publish

Verify that the package is published on PyPi: https://pypi.org/project/my_project/

Test the package installation

Create a test environment

python -m venv test_env
source test_env/scripts/activate

Install the package and check that it's listed

pip install my_project
pip list
pip show my_project

Import the package and run its entry point in a Python shell

python
>>> import my_project
>>> my_project.main()

Alternatively, run the main program as a module

python -m my_project.main

If the main module is registered in pyproject.toml, just run

my_project