Skip to content

Instantly share code, notes, and snippets.

@gboeing
Last active June 17, 2022 16:11
Show Gist options
  • Save gboeing/dcfaf5e13fad16fc500717a3a324ec17 to your computer and use it in GitHub Desktop.
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

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

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

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

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

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

wgwz commented Dec 30, 2018

also the twine register step is deprecated in newer versions

@spiros
Copy link

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

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