Package: sdl-example-package
An Example Python PackageThis repo is a simple demonstration of how to create and publish a Python package to PyPI (the Python Package Index, pronounced "pie-pee-eye", but I preferpie-pie, because who doesn't like pie).PyPI Account SetupBefore getting started, please create an account at bothtest.pypi.orgANDpypi.org.Next, create a file called.pypirc. Add the following to it:[pypi]
  username = __token__
  password = <the full pypi token string including the pypi- prefix>

[testpypi]
  username = __token__
  password = <the full testpypi token string including the pypi- prefix>We will replace the passwords once we have generated each of the tokens. Save this file in your home directory, e.g.C:\Users\YourNamefor Windows. This will allowtwine(the PyPI publishing tool) to automatically log you in whenever you upload a package.After you have created and verified your account(s), navigate to theAccount Settingspage and find theAPI Tokenssection. ClickAdd API Token, and then enter a name (e.g.pypi-global-api-token) and selectEntire Accountfor the scope. Your token should now appear. Edit your.pypircfile in the appropriate location.Create the Repo for your PackageIf you do not yet have a repo for your package, create one!Create a repository on GitHubFor your.gitignore, choose the Python option.Clone into your repoDirectory setupSetup the following directory structure inside of your repository:my-package/
├─ my_package/
│  ├─ __init__.py
│  ├─ module1.py
│  ├─ module2.py
│  ├─ sub_package/
│  │  ├─ __init__.py
│  │  ├─ module3.py
│  │  ├─ module4.py
├─ tests/
│  ├─ test_module1.py
│  ├─ test_module2.py
│  ├─ test_module3.py
│  ├─ test_module4.py
├─ LICENSE
├─ README.md
├─ .gitignore
├─ pyproject.tomlYour package files should be copied into themy_packagesubfolder (feel free to rename). For now, you can leave thetestsfolder empty. Your.gitignoreshould probably follow a standard Python.gitignore. Add your license text (e.g.MIT License) to the license file.Populate pyproject.tomlYourpyproject.tomlis a configuration file for packaging and building a Python package that is ready for distribution. If you are familiar withsetup.py, you can think of it as a cleaner, more readable way of automating the configuration normally done there.It is a table of key-value pairs, with sections defined by brackets, e.g.[section_name]. Some sections may have keys which may need their own tables, e.g.[section_name.sub_section].Let's build it!The Build System sectionThe first[build-system]section defines which packaging backend you will use. Stick to the defaults for now![build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"The Project SectionNext, the[project section]is where you enter the main project metadata, like the package name, the version, etc. Start with the following keys:[project]
name = "your-package-name"
description = "An example package which does something"
version = "0.0.1"Next let's add a few optional keys to the project section which identify some important files and additional metadata. Note that the value stored at a key can itself be a table (as in thelicensekey), an array (as in theclassifierskey), or even an array of tables (as in theauthorskey).readme = "README.md"
license = {file = "LICENSE"}
authors = [
    {name = "Your Name", email = "you@email.com"},
    {name = "Another Name", email = "them@email.com"}
]
classifiers = [
    "Development Status :: 4 - Beta",
    "Intended Audience :: Science/Research",
    "License :: OSI Approved :: MIT License",
    "Programming Language :: Python :: 3.7",
    "Programming Language :: Python :: 3.8",
    "Programming Language :: Python :: 3.9",
]Next, we will specify which dependencies your package needs. This example assumes that the package requires Python v3.7 or higher, as well as therequestspackage.requires-python = ">=3.7"
dependencies = [
    "requests"
]nb: if you already have arequirements.txtfile, follow the instructionsherefor dynamically injecting your requirements into thedependencieskey.Finally, let's add some additional metadata by creating a subsection for theurlskey:[project.urls]
Documentation = "https://somesite.com"
Repository = "https://github.com/username/repository"There's a lot more advanced configuration we can do, plugins that can be installed, etc etc, but that should be enough for now!Build and Publish the PackageInstall thepippackagesbuild(for creating the disribution files) andtwine(for publishing the package to PyPI):pip install build twineFrom the root directory of your project, run the following command to build your dist and wheel files!python -m buildWhenbuildis complete, you should now see adistfile in your package directory.That was easy! Next, let's publish it. We will start by publishing totest.pypi.orgin order to make sure everything is working.python -m twine upload --repository testpypi dist/*When it completes, head over totest.pypi.organd check it out! It's now ready to be installed (though thetestpypiindex is pruned regularly). You can install it viapipas you would any other package, but you will need to specify that it is coming fromtestpypiwith the--index-urlflag.pip install --index-url https://test.pypi.org/simple/ your-package-nameFinally, let's publish it to the real Python PI:twine upload dist/*Additional ResourcesSetuptools User GuideMore in-depth instructions on package creation and publicationAnd some more...Some info on .pypirc