{"id":20455266,"url":"https://github.com/alexmhack/python_packaging","last_synced_at":"2025-07-04T06:07:43.567Z","repository":{"id":62580272,"uuid":"147392367","full_name":"Alexmhack/python_packaging","owner":"Alexmhack","description":"This tutorial walks you through how to package a simple Python project.","archived":false,"fork":false,"pushed_at":"2018-09-05T12:01:36.000Z","size":10,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-01T20:50:08.861Z","etag":null,"topics":["beginner-project","pypi","pypi-packages","python-packages","python-tutorial","python3","setuptools","simple-project"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Alexmhack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-09-04T18:39:14.000Z","updated_at":"2023-08-27T01:37:22.000Z","dependencies_parsed_at":"2022-11-03T21:02:54.883Z","dependency_job_id":null,"html_url":"https://github.com/Alexmhack/python_packaging","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Alexmhack/python_packaging","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexmhack%2Fpython_packaging","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexmhack%2Fpython_packaging/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexmhack%2Fpython_packaging/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexmhack%2Fpython_packaging/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Alexmhack","download_url":"https://codeload.github.com/Alexmhack/python_packaging/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexmhack%2Fpython_packaging/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263457182,"owners_count":23469290,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["beginner-project","pypi","pypi-packages","python-packages","python-tutorial","python3","setuptools","simple-project"],"created_at":"2024-11-15T11:18:23.396Z","updated_at":"2025-07-04T06:07:43.535Z","avatar_url":"https://github.com/Alexmhack.png","language":"Python","readme":"# python_packaging\nThis tutorial walks you through how to package a simple Python project. It will show you how to add the necessary files and structure to create the package, how to build the package, and how to upload it to the Python Package Index.\n\n# Introduction\nThis tutorial uses a simple project named **pyexample**\n\nThroughout this tutorial we will be creating necessary files and structure to create the \npackage, how to build the package, and how to upload it the to python packaging index.\n\nThis tutorial will be starter for our large python email package which will be used to \nsend emails using command line by setting in the sender's email address, a file for\nour email template and another file that will have the receiver's email or emails. But \nmore on that later.\n\n[SOURCE](https://packaging.python.org/tutorials/packaging-projects/) FOR THIS TUTORIAL\n\n# A simple project\nYou can name your project a unique name which does not already exists on [pypi.org](https://pypi.org)\n\nSince this is a example python package so we name it **pyexample** that is [unique](https://pypi.org/search/?q=pyexample)\n\nOkay enough of the chit chat. Let's begin with our package project structure.\n\nCreate the structure for your project\n\n```\nC:.\n└───pyexample\n    └───pyexample\n```\n\nInside the inner **pyexample** folder create a new file named ```__init__.py``` and place \nthis piece of code in it.\n\n```\nname = \"pyexample\"\n```\n\nOnce you have this structure ready **cd** into the outer or the main project folder\n\n```\n.../pyexample\u003e dir\n\n05-09-2018  14:43    \u003cDIR\u003e          .\n05-09-2018  14:43    \u003cDIR\u003e          ..\n05-09-2018  14:43    \u003cDIR\u003e          pyexample\n               0 File(s)              0 bytes\n               3 Dir(s)  211,912,638,464 bytes free\n```\n\n# Create the package files\nFor distributing our project we need to create some files.\n\nCreate the files as listed below\n\n\n**+ is a folder and - is a file and space represents path**\n```\n+ example_pkg\n\t+ example_pkg\n\t\t- __init__.py\n\t- setup.py\n\t- LICENSE\n\t- README.md\n```\n\n# Create setup.py file\n```setup.py``` is the build script for [setuptools](https://packaging.python.org/key_projects/#setuptools). According to setuptools,\n\n**\nsetuptools (which includes easy_install) is a collection of enhancements to the Python distutils that allow you to more easily build and distribute Python distributions, especially ones that have dependencies on other packages.\n\n[distribute](https://pypi.org/project/distribute) was a fork of setuptools that was merged back into setuptools (in v0.7), thereby making setuptools the primary choice for Python packaging.\n**\n\nThe ```setup.py``` is the file which tells setuptools about the name and version and also \nthe files to include.\n\nOpen ```setup.py``` and enter the below code in it, you can customize the code as you want\n\n**setup.py**\n```\nimport setuptools\n```\n\nNow we will set the several arguments that ```setuptools.setup()``` takes, we will set the \nname, version, description etc. for our package in this file only\n\n```\nimport setuptools\n\nwith open('README.md') as fh:\n\tlong_description = fh.read()\n\nsetuptools.setup(\n\tname=\"pyexample\",\n\tversion=\"0.0.1\",\n\tauthor=\"PSG\",\n\tauthor_email=\"author@example.com\",\n\tdescription=\"A small python example project\",\n\tlong_description=long_description,\n\tlong_description_content_type=\"text/markdown\",\n\turl=\"https://github.com/Alexmhack/python_packaging\",\n\tpackages=setuptools.find_packages(),\n\tclassifiers=[\n\t\t\"Programming Language :: Python :: 3\",\n\t\t\"License :: OSI Approved :: MIT License\",\n\t\t\"Operating System :: OS Independent\",\n\t]\n)\n```\n\n1. **name** is the name of the python package which be as long and contain any letters \nincluding *-*, *_*, *numbers*\n\n2. **version** is the package version for example ```django==2.0```\n\n3. **author** and **author_email** are the details of the package author\n\n4. **description** is the small single line summary of the package.\n\n5. **long_description** is a detailed description of the package. This is shown on the \npackage detail package on the Python Package Index. In this case, the long \ndescription is loaded from README.md which is a common pattern.\n\n\t```\n\twith open('README.md') as fh:\n\t\tlong_description = fh.read()\n\t...\n\tauthor_email=\"author@example.com\",\n\tdescription=\"A small python example project\",\n\tlong_description=long_description,\n\t...\n\t```\n\n6. **long_description_content_type** tells the index what type of markup is used for the long \ndescription. In this case, it’s Markdown.\n\n7. **url** is the link to the project homepage which usually is on github like our project\nor bitbucket.\n\n8. **packages** is a list of all Python import packages that should be included in the \ndistribution package. Instead of listing each package manually, we can use find_\npackages() to automatically discover all packages and subpackages. In this case, the list \nof packages will be **pyexample** as that’s the only package present.\n\n9. **classifiers** tell the index and pip some additional metadata about your package. In \nour project, the package is only compatible with Python 3, is licensed under the MIT \nlicense, and is OS-independent. You should always include at least which version(s) of \nPython your package works on, which license your package is available under, and which \noperating systems your package will work on. Visit [link](https://pypi.org/classifiers/) \nfor a complete list of classifiers.\n\n# README and LICENSE\nYour package README.md and LICENSE file should contain relevant information for your \nparticular package.\n\nREADME.md file contents will be dispalyed on the pypi.org package homepage and github \npackage homepage.\n\nAnd LICENSE should be included with every python package, the most common license is the \nMIT LICENSE, checkout the [LICENSE](https://github.com/Alexmhack/python_packaging/blob/master/pyexample/LICENSE\n) and [README.md](https://github.com/Alexmhack/python_packaging/blob/master/pyexample/README.md) file.\n\n# Generating distribution archives\nIn this section we will be generating distribution packages for our package. These are \nthe files which are uploaded to the Package Index and this enables anyone with a internet\nconnection and python install that package with [pip](https://packaging.python.org/key_projects/#pip)\n\nInstall the latest version of **setuptools** and **wheel** by running\n\n```\n\u003e pip install --user --upgrade setuptools wheel\n```\n\nOR\n\n```\n\u003e python3 -m pip install --user --upgrade setuptools wheel\n```\n\nNow run this command from the same directory where setup.py is located\n\n```\n.../pyexample\u003e python3 setup.py sdist bdist_wheel\n\n...\nadding 'pyexample\\__init__.py'\nadding 'pyexample-0.0.1.dist-info\\top_level.txt'\nadding 'pyexample-0.0.1.dist-info\\WHEEL'\nadding 'pyexample-0.0.1.dist-info\\METADATA'\nadding 'pyexample-0.0.1.dist-info\\RECORD'\nremoving build\\bdist.win-amd64\\wheel\n```\n\nThe process after completion should create some new folders -- ```build``` ```dist``` ```pyexample.egg-info``` and many files inside them. inside the main \nfolder.\n\n\nFor more Information visit the [official](https://packaging.python.org/tutorials/packaging-projects/) tutorial\n\n# Uploading the distribution archives\nFinally, we will upload our package onto Python Package Index\n\nFirst thing we need to do is create an account on [Test PyPi](https://test.pypi.org/). Well the yellow highlighted text on the homepage\nof TestPypi says this but just for clarity Test Pypi is **Test PyPI is a \nseparate instance of the package index intended for testing and \nexperimentation.**\n\nYou might be wondering why this but this ensures that we test our package\non an instance here without affecting the real python package index.\n\nTo register an account, go to https://test.pypi.org/account/register/ and \ncomplete the steps on that page. You will also need to verify your email \naddress before you’re able to upload any packages. For more details on Test \nPyPI, see Using TestPyPI.\n\nNow that you are registered and verified your account you can upload your\ndistributions using [twine](https://packaging.python.org/key_projects/#twine)\n\nInstall twine locally using \n\n```\n\u003e pip install --user --upgrade twine\n```\n\nOr if that doesn't work\n\n```\npython3 -m pip install --user --upgrade twine\n```\n\nOnce installed you can upload your distributions well uploading your archives\ninside **dist** folder using twine\n\nYou should get errors like\n\n```\nThe user '[your username]' isn't allowed to upload to project 'example-pkg'...\n```\n\n**NOTE:**To solve this problem which is basically caused due to package name \nconflicts you need to change the name of the package inside the ```setup.py``` \nfile\n\nI renmaed the file to **your_package_username**\n\n```\nsetuptools.setup(\n\tname=\"\u003cyour_package_username\u003e\",\n\tversion=\"0.0.1\",\n\tauthor=\"psg\",\n```\n\nAfter renaming the package inside ```setup.py``` file you need to delete the \nfolder that the ```python setup.py sdist bdist_wheel``` and run this command \nagain because we made changes in the name of the package and twine will upload the\nsame archives until we delete or upadte them.\n\n```\ntwine upload --repository-url https://test.pypi.org/legacy/ dist/*\n\nupload --repository-url https://test.pypi.org/legacy/ dist/*\nUploading distributions to https://test.pypi.org/legacy/\nEnter your username: [username]\nEnter your password: [password]\nUploading pyexample-0.0.1-py3-none-any.whl\n100%|██████████████████████████████████████████| 4.66k/4.66k [00:06\u003c00:00, 66234B/s]\n...\n```\n\n# Installing your test package\nrun the pip install but with a simple tweak\n\nI would prefer to install our example package in a virtualenv\n\n```\n(env)\u003e python3 -m pip install --index-url https://test.pypi.org/simple/ pyexample_psg\n\nLooking in indexes: https://test.pypi.org/simple/\nCollecting pyexample-psg\n  Downloading https://test-files.pythonhosted.org/packages/55/99/690744d9eba00f94cdf0631d36a36254b3537309e6311b926943fbe4694d/pyexample_psg-0.0.1-py3-none-any.whl\nInstalling collected packages: pyexample-psg\nSuccessfully installed pyexample-psg-0.0.1\n```\n\nYou can check if the package is actually installed and works like the other python\npackages do,\n\n**testing.py**\n```\nimport pyexample_psg\n\nprint(pyexample_psg.name)\n```\n\nCongratulations on your first python package. This was a very simple project and\nwe uploaded our project on Test PyPi not on PyPi, the process for that is same\nbut we need to upload the archives on the pypi site which can be done by\n\n```\ntwine upload dist/*\n```\n\nThe same credentials will be asked but this time enter in pypi.org details and\ninstall the package using the simple \n\n```\npip install your-package\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexmhack%2Fpython_packaging","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexmhack%2Fpython_packaging","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexmhack%2Fpython_packaging/lists"}