Sometimes you want to run your own and local python repository. For example you want to manage your development projects within your LAN environment without using a public repository.
Before doing it by copying from dev machine to production machine and install it from bare it might be a good idea to use pypi-server as a local repository, making pip you dependency manager as you normally also would do.
This short post is based on the very good docs of pypi-server and adds some further information. I also found that the docs is a bit outdated.
In this example I’m installing a server on a raspberry pi 3. Dependencies for this are running python 3 interpreter, working virtual environment, working pip. S
- Running python 3 interpreter:
python3 --version
- Working virtual environment:
python -m venv --help
- Working pip:
pip --version
- Some basic knowledge in python package distribution might help as well.
First we start on our rpi with updating it.
sudo apt update
sudo apt upgrade
Then we should check if venv is running and doing things the right way. Please note no superuser do (sudo).
mkdir app
cd app
mkdir pypiserver
python3 -m venv ./pypiserver
This will create a fresh virtual environment. There should be no error. Now we can activate the venv and install pypiserver.
cd pypiserver
source ./bin/activate
pip install pypiserver passlib
pypiserver is now installed. We also installed passlib to handle login/identification. Now we need a container for the packages and see if the server script is working
mkdir packages
pypi-server --version
> 1.5.1
Before starting serving packages we need to add a possibility to upload packages via twine or setuptools (both are recommended) instead of placing the packages directly into the above packages directory.
htpasswd -sc htpasswd.txt pypiuser
You will be prompted for a password string then. If htpasswd is not you can either install apache2 (sudo apt install apache2
) or generate password file manual via https://hostingcanada.org/htpasswd-generator/.
We are now ready to serve.
pypi-server run -p 8080 -P htpasswd.txt ./packages &
You can check also from now via http://localhost:8080 if server is okay. You should see something similar like
Now we could try to upload our first package to local pypi. My typical tool chain to build and upload a python package looks like following shell commands (Assuming a complete setup.cfg and pyproject.toml in the root folder. More can be found here).
python -m build -o ./build
twine check build/*
twine upload --verbose --repository-url http://xxx.xxx.xxx.xx:8080 build/* -u pypiuser -p apasswordphrase
And now you could convince pip to install that package from the local repository. We are doing a dry run here.
pip install --index-url http://192.168.178.22:8080 --trusted-host 192.168.178.22:8080 PACKAGENAME --dry-run
That was quiet easy and you now can distribute packages locally with the benefits of pip.