To work with python you only need a .py
file. However if you are creating a package you need to follow a concrete structure and include some needed files.
Before creating your project, I suggest you check if the name you want to use exists:
pip search package_name
You can also look for it at pypi web
You should have your project inside a folder with the name of the package. This will be the root
of your project and should include .gitignore
, README.md
and LICENSE.txt
among other configuration files.
The code should be inside another folder with the name of the package. So the structure should be:
- /package_name ├── /package_name │ ├── __init__.py │ ├── file1.py │ ├── file2.py │ └── fileN.py ├── .gitignore ├── LICENSE.txt ├── README.md └── setup.py
All files inside /package_name/package_name
should have imports that work from the main path. For example to import the file1
in file2
you should:
from .file1 import my_function
Do not forget the '.' before the name
The __init__.py
file will contain whatever you want to call from the 'outside'.
For example:
from .file2 import public_function
This is what will allow you to do the following one you have uploaded the package:
import package_name package_name.public_function() # This will call the 'public_function' from 'file2.py'
This is where you define the package itself, how can it be installed and some basic information about it. A basic example would be:
import io from setuptools import setup setup( name="package_name", version="1.0.2", author="Your Name", author_email="your@email.com", packages=["package_name"], install_requires=io.open("requirements.txt", encoding="utf-8").read().splitlines(), include_package_data=True, license="MIT", description=("write here a short description"), long_description=io.open("README.md", encoding="utf-8").read(), long_description_content_type="text/markdown", url="https://github.com/your_user/package_name", package_data={"package_name": ["resources/*"]}, )
long_description
is extracted from the README.md
you can use other formats for the README like
ost
install_requires
is a list of requirements. In the example I get it from requirements.txt
.
You could also write the requirements by hand with:
install_requires=["pandas>0.22", "flask"]
You should avoid requirements with a fixed number version use
<
or>
instead.
The package_data
parameter allows you to include all files inside /package_name/resources/
path even if they are not .py
files. This will be useful if you want to include html
templates or yaml
/json
with data.
Before creating the package I suggest you add some rules in the .gitignore
:
build/ dist/ *.egg-info
After that you can run:
python setup.py sdist bdist_wheel
Then you will have build
with the content of the package and dist
with tar
and wheels
of the package (what will be uploaded).
When you run pip install package
you are actually downloading it from pypi. There is also test.pypi for testing purpouses. So you will need to register:
To upload the packages I suggest you use twine
. You can install it with:
pip install twine
You can run the next command which will upload all packages created in the dist
folder:
python -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*
The first time you run this command you will be asked to log in. Use the credentials from the previous step.
After uploading the package you can download it to test if it is working as expected:
pip install --index-url https://test.pypi.org/simple/ package_name # You can specify the version with pip install --index-url https://test.pypi.org/simple/ package_name==X.X.X
In order to upload the package to pypi
the process is very similar to the step before:
python -m twine upload dist/*
And to install it you can simply run:
pip install package
Well done, you now have your first python package uploaded to pypi.