Search code examples
pythonpython-3.xpypi

Python - Cannot publish module to PyPI


My problem is that I can't upload my module to PyPI. When I run twine upload dist/easy-email-0.0.1.tar.gz I get HTTPError: 400 Client Error: 'Easy-email-0.0.1.tar.gz' is an invalid value for Download-URL. Error: Invalid URI see https://packaging.python.org/specifications/core-metadata for url: https://test.pypi.org/legacy/

What am I doing wrong?

Here is the setup.py:

from distutils.core import setup

setup(
    name = 'easy-email',
    packages = ['easy-email'],
    version = '0.0.1',  # Ideally should be same as your GitHub release tag varsion
    description = 'Send emails in python!',
    author = 'myname',
    author_email = 'myemail',
    url = 'https://github.com/marmadukeandbob05/Easy-Email/',
    download_url = 'Easy-Email-0.0.1.tar.gz',
    keywords = ['email', 'gmail'],
    classifiers = [],
)

Solution

  • Your download_url is invalid, it is not a valid URL. Note that you don't need to set that value at all when uploading your installation archive to PyPI, because the download URL is on PyPI.

    Only set download_url when you are going to host your packages elsewhere, not on PyPI. You would have to use a full URL, so one that starts with http:// or https://, and pip or easy_install would then follow that URL from PyPI to find the installation archive. You'd only use the twine register to register the metadata and just not use twine upload at all.

    The error message linked you to the documentation for the field:

    A string containing the URL from which this version of the distribution can be downloaded.

    Bold emphasis mine; Easy-Email-0.0.1.tar.gz is not a URL. It is merely a filename.

    You'd use this when you want people to download the archive from a different host, for example, from GitHub. For example, if the requests project wanted people to download the release from GitHub instead of from the PyPI servers, they could use download_url = 'https://github.com/requests/requests/archive/v2.18.4.tar.gz', and then only use twine register to put the metadata on PyPI.