Creating a Python package
This guide describes how to create a Python package for publishing to a Cloud Registry.
Python package structure
Here is an example of a project structure:
my_package/ # Project root directory
│
├── my_package/ # Main package (its name must match the project name)
│ ├── __init__.py # Makes the directory a Python package
│ └── core.py # Main module (optional)
│
├── tests/ # Test directory
│ ├── __init__.py
│ └── test_core.py # Tests for core.py
│
├── README.md # Project description
├── LICENSE # License
└── pyproject.toml # Project metadata
Creating a package
-
Set up your environment:
apt update && \ apt-get install python3 -y && \ apt-get install python3.12-venv -y && \ python3 -m ensurepip --default-pip -
Install build tools:
python3 -m venv my-venv && source my-venv/bin/activate pip install build twine -
Create the project structure:
mkdir -p my_package/my_package cd my_package -
Create a file named
my_package/__init__.py:cat > my_package/__init__.py << 'EOF' def hello(): print("Hello from my package!") EOF -
Create a file named
pyproject.toml:cat > pyproject.toml << 'EOF' [build-system] requires = ["setuptools"] build-backend = "setuptools.build_meta" [project] name = "my_package" version = "0.0.1" description = "A small example package" readme = "README.md" [project.scripts] my_package = "my_package:hello" EOF -
Create a file named
README.md:cat > README.md << 'EOF' # my_package A small example package. EOF -
Build the package:
python3 -m buildResult:
Successfully built my_package-0.0.1.tar.gz and my_package-0.0.1-py3-none-any.whlThe built files will appear in the
dist/directory. -
Check the package:
twine check dist/*Result:
Checking dist/my_package-0.0.1-py3-none-any.whl: PASSED Checking dist/my_package-0.0.1.tar.gz: PASSED
-
Install Poetry:
curl -sSL https://install.python-poetry.org | python3 - -
Create a new project:
poetry new my_package cd my_packagePoetry will automatically create the project structure with a file named
pyproject.toml. -
Edit
pyproject.toml:[tool.poetry] name = "my_package" version = "0.0.1" description = "A small example package" authors = ["Example Author <author@example.com>"] readme = "README.md" [tool.poetry.dependencies] python = "^3.9" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" -
Create a file named
mypackage/__init__.py:def hello(): return "Hello from my package!" -
Build the package:
poetry buildResult:
Building my_package (0.0.1) - Building sdist - Built my_package-0.0.1.tar.gz - Building wheel - Built my_package-0.0.1-py3-none-any.whl
-
Install
uv:curl -LsSf https://astral.sh/uv/install.sh | shAlternatively, you can use
pip:pip install uv -
Create a new project:
uv init mypackage --lib && cd mypackage -
Create a virtual environment:
uv venv && source .venv/bin/activate -
Create a file named
mypackage/__init__.py:cat > src/mypackage/__init__.py << 'EOF' def hello(name: str = "World") -> str: return f"Hello, {name}!" def add(a: int, b: int) -> int: return a + b EOF -
Build the package:
uv buildResult:
Building my_package-0.0.1.tar.gz and my_package-0.0.1-py3-none-any.whl