- What's a package, project structure
- Building a package
- Installing a package
- Uploading a package
- Extra
The end result:
1. π¦ What is a Python Package?
A package is simply a directory of Python modules (.py files). To be recognized by Python, it typically contains an __init__.py file.
The core philosophy of packaging is reusability:
- others can use your code
- you can also use other peoples packages and integrate them into your own project
Example of packages:
I have a poll application with preset questions. On this webapp you can choose options for a given preset question and see statistics after submitting your choice.

The project structure:
.
βββ core
βΒ Β βββ __init__.py
βΒ Β βββ __pycache__
βΒ Β βββ asgi.py
βΒ Β βββ settings.py
βΒ Β βββ urls.py
βΒ Β βββ wsgi.py
βββ db.sqlite3
βββ manage.py
βββ polls
βββ __init__.py
βββ __pycache__
βββ admin.py
βββ apps.py
βββ migrations
βββ models.py
βββ static
βββ templates
βββ test_models.py
βββ test_views.py
βββ urls.py
βββ views.py
Every feature related to poll application is done inside the app 'polls' app. Let's turn the polls app into a package and upload it to a website of packages.
Feel free to create a simple django project with a single view that returns HttpResponse('Hello Package!') or similar and follow along.
2. Building a package
- Install setuptools and build. We will use these packages to build a package.
- Create another directory separate from the project. You can call it django-polls, this will be the name of our package.
- Move polls app of your project to django-polls directory and rename polls to 'django_polls'
- Edit
django_polls/apps.pyso that name refers to the new module name 'django_polls' and add labels to give a short name to the app 'polls'
from django.apps import AppConfig
class PollsConfig(AppConfig):
name = "django_polls"
label = "polls"
5.Create django-polls/README.rst file with the following content:
============
django-polls
============
django-polls is a Django app to conduct web-based polls. For each
question, visitors can choose between a fixed number of answers.
Detailed documentation is in the "docs" directory.
Quick start
-----------
1. Add "polls" to your INSTALLED_APPS setting like this::
INSTALLED_APPS = [
...,
"django_polls",
]
2. Include the polls URLconf in your project urls.py like this::
path("polls/", include("django_polls.urls")),
3. Run ``python manage.py migrate`` to create the models.
4. Start the development server and visit the admin to create a poll.
5. Visit the ``/polls/`` URL to participate in the poll.
- Create django-polls/LICENSE file
- Create django-polls/pyproject.toml file which details how to build and install the app. It must have the following content:
[build-system]
requires = ["setuptools>=77.0.3"]
build-backend = "setuptools.build_meta"
[project]
name = "django-polls-yourname"
version = "0.1"
dependencies = [
"django>=X.Y", # Replace "X.Y" as appropriate
]
description = "A Django app to conduct web-based polls."
readme = "README.rst"
license = "BSD-3-Clause"
requires-python = ">= 3.12"
authors = [
{name = "Your Name", email = "yourname@example.com"},
]
classifiers = [
"Environment :: Web Environment",
"Framework :: Django",
"Framework :: Django :: X.Y", # Replace "X.Y" as appropriate
"Intended Audience :: Developers",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
]
[project.urls]
Homepage = "https://www.example.com/"
You can check django version using this command:
python3 -m django --version
8.Create django-polls/MANIFEST.in with the following content. It's used to templates and static files:
recursive-include django_polls/static *
recursive-include django_polls/templates *
9.Build your package by running:
python -m build
It creates dist/ directory containing Source Distribution (.tar.gz) and your Built Distribution (the .whl or "wheel" file). I personally refer to them as zipped version of my app.
3. Installing the django-polls package
Since we moved polls directory out of the project, it's no longer working. We can fix our project by installing the django-polls package.
- Install django-polls
python3 -m pip install django-polls/dist/django_polls-0.1.tar.gz
2.Update settings.py of your project
INSTALLED_APPS = [
"django_polls.apps.PollsConfig",
...,
]
3.Update core/urls.py to point to the new module name
urlpatterns = [
path("polls/", include("django_polls.urls")),
...,
]
4.Run the development server to confirm the project is continues to work
Now if you run pip list, you should see 'django-polls' package.
Uploading a package
- Register on test.pypi.org. The real python index is pypi.org, but we will use test.pypi
- To securely upload our package, create an API token at https://test.pypi.org/manage/account/#api-tokens and copy it
- Install twine to upload the package
- cd into django-polls and run
python3 -m twine upload --repository testpypi dist/*
During the process it will ask you for API token, copy, paste the token you just created.
After the command completes, you should see something like this:
Uploading distributions to https://test.pypi.org/legacy/
Enter your API token:
Uploading example_package_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl
100% ββββββββββββββββββββββββββββββββββββββββ 8.2/8.2 kB β’ 00:01 β’ ?
Uploading example_package_YOUR_USERNAME_HERE-0.0.1.tar.gz
100% ββββββββββββββββββββββββββββββββββββββββ 6.8/6.8 kB β’ 00:00 β’ ?
Extra
Now if you want to install the version of the package that you just uploaded to test.pypi
- Uninstall the previously locally installed django-polls
pip uninstall django-polls
- Install
pip install -i https://test.pypi.org/simple/ django-polls-erlan
Replace 'django-polls-erlan' with the package name you gave when building.
You can also access the install command by clicking on 'View'.



Top comments (0)