Skip to content

Instantly share code, notes, and snippets.

@gboeing
Last active October 10, 2025 06:13
Show Gist options
  • Select an option

  • Save gboeing/dcfaf5e13fad16fc500717a3a324ec17 to your computer and use it in GitHub Desktop.

Select an option

Save gboeing/dcfaf5e13fad16fc500717a3a324ec17 to your computer and use it in GitHub Desktop.
How to organize and distribution a package on pypi

To distribute a package on pypi

Directory structure

/project/
    /package/
        __init__.py
        module.py
    setup.py

File contents

/project/package/__init__.py

from .module import *
__version__ = '0.1'

/project/package/module.py

# this file just contains your module's code

/project/setup.py

from setuptools import setup
setup(name='module',
      version='0.1',
      description='What the module does',
      url='https://github.com/username/repo',
      author='Your Name',
      author_email='email@domain.net',
      license='MIT',
      packages=['module'],
      install_requires=['numpy>=1.11',
                        'matplotlib>=1.5'])

Set up pypi

Create a file in the home directory called ~/.pypirc with contents:

[distutils]
index-servers = pypi

[pypi]
repository = https://pypi.python.org/pypi
username = YourPyPiUsername
password = YourPyPiPassword

Build, register, and upload to pypi

Open terminal window and change directory to /project/

Then run setup.py with sdist to build a source distribution and bdist_wheel to build a wheel (with --universal flag if your package is Python 2/3 universal). Then use twine to register it and upload to pypi.

python setup.py sdist bdist_wheel --universal
twine register dist/project-x.y.z.tar.gz
twine register dist/mypkg-0.1-py2.py3-none-any.whl
twine upload dist/*

Build and upload subsequent updates to pypi

Update the change log and edit the version number in setup.py and package/__init__.py and docs/source/conf.py.

Open terminal window and change directory to /project/ then run setup.py with sdist to build a source distribution and bdist_wheel to build a wheel (with --universal flag if your package is Python 2/3 universal). Remove old versions from /project/dist/ and then use twine to upload to pypi.

python setup.py sdist bdist_wheel --universal
twine upload dist/*

Release your code on GitHub

To tag your current commit as a released version, run:

git tag -a v0.1 -m "annotation for this release"
git push origin --tags

Release your code on conda-forge

If you already have a conda-forge feedstock forked to your own GitHub account, first re-render the feedstock with:

conda-smithy rerender

Then edit recipe/meta.yaml to update the version, hash, etc. To calculate the sha256 hash, run:

openssl dgst -sha256 path/to/package_name-0.1.1.tar.gz

Then, commit and push the yaml file to GitHub:

git pull upstream master
git add --all
git commit -m 'version bump to v0.1.1'
git push

Finally, issue a pull request to conda-forge.

@sudarsontm
Copy link
Copy Markdown

Hello Geoff Boeing, I'm unable to follow few things in this blog.

  1. where should I create ~/.pypirc. Under project?
    What is the file name is it only .pypirc?

  2. On executing python setup.py sdist bdist_wheel --universal, I get the following error: package directory 'module' does not exist

I wish to get more clarity on this exercise, can you please spend some time to skype with me. Oh, myself Sudarson a comp-science student. Looking forward eagerly to hearing back from you. Thanks

@flywire
Copy link
Copy Markdown

flywire commented Jun 9, 2018

  • It would be nice to show or link to git for windows desktop
  • .pypirc is depreciated and ignored
  • I note windows also uses: twine register dist/project-x.y.z.tar.gz
  • module.py is a list of as many modules as required with one per line

@E3V3A
Copy link
Copy Markdown

E3V3A commented Nov 26, 2018

  1. twine no longer use/need the register syntax.
  2. __init__.py can probably be skipped altogether if you only have a script. (Not sure when in modular form though.)

@markolofsen
Copy link
Copy Markdown

It's really easy if are you using special tool for publications.
It's works in your browser, without any special dependencies.

Try this library for that https://github.com/markolofsen/how_to_upload_package_to_pypi

@wgwz
Copy link
Copy Markdown

wgwz commented Dec 30, 2018

the pypirc didn't work for me in it's current state. though this one does:

[distutils]
index-servers = pypi

[pypi]
username = YourPyPiUsername
password = YourPyPiPassword

@wgwz
Copy link
Copy Markdown

wgwz commented Dec 30, 2018

also the twine register step is deprecated in newer versions

@spiros
Copy link
Copy Markdown

spiros commented Jan 4, 2019

Thank you for this.

You might need to update the pypi repository URL in .pypirc - I got the following error when trying to upload (which was resolved by setting the upload URL to https://upload.pypi.org/legacy/ )

spiros@tokidoki:$twine upload dist/*
UploadToDeprecatedPyPIDetected: You're trying to upload to the legacy PyPI site 'https://pypi.python.org/pypi'. Uploading to those sites is deprecated. 
The new sites are pypi.org and test.pypi.org. Try using https://upload.pypi.org/legacy/ (or https://test.pypi.org/legacy/) to upload your packages instead. These are the default URLs for Twine now. 
More at https://packaging.python.org/guides/migrating-to-pypi-org/ .

@queirozfcom
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment