Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Minimal PyPI server for uploading & downloading packages with pip/easy_install

License

NotificationsYou must be signed in to change notification settings

pypiserver/pypiserver

Repository files navigation

pypi server logo

PyPi project badgePython VersionsCI workflowLicensesStable Docker Tag

namedescription
Version2.4.0
Date:2025-08-18
Sourcehttps://github.com/pypiserver/pypiserver
PyPIhttps://pypi.org/project/pypiserver/
Testshttps://github.com/pypiserver/pypiserver/actions
Maintainers@ankostis,@mplanchard,@dee-me-tree-or-love,@pawamoy,Someone new?We are open for new maintainers!#397
Licensezlib/libpng + MIT
Communityhttps://pypiserver.zulipchat.com

Tip

Reach out inDiscussions,or chat with us onZulip

pypiserver is a minimalPyPI compatible server forpip oreasy_install.It is based onbottle and serves packages from regular directories.Wheels, bdists, eggs and accompanying PGP-signatures can be uploadedeither withpip,setuptools,twine,pypi-uploader, or simply copiedwithscp.

Note

The official software poweringPyPI isWarehouse. However,Warehouseis fairly specialized to bepypi.org's own software, and should notbe used in other contexts. In particular, it does not officially supportbeing used as a custom package index by users wishing to serve their ownpackages.

pypiserver implements the same interfaces asPyPI, allowingstandard Python packaging tooling such aspip andtwine tointeract with it as a package index just as they would withPyPI, whilemaking it much easier to get a running index server.

pypiserver

Table of Contents

Quickstart Installation and Usage

Important

pypiserver works with Python 3.8+ and PyPy3.

Warning

Older Python versions may still work, but they are not tested.

For legacy Python versions, usepypiserver-1.x series.
Note that these are not officially supported, and will not receive bugfixes or new features.

Tip

The commands below work on a unix-like operating system with a posix shell.
The'~' character expands to user's home directory.

If you're using Windows, you'll have to use their "Windows counterparts".
The same is true for the rest of this documentation.

  1. Installpypiserver with this command

    pip install pypiserver# Or: pypiserver[passlib,cache]mkdir~/packages# Copy packages into this directory.

    [!TIP]See alsoAlternative Installation methods

  2. Copy some packages into your~/packages folder and thenget yourpypiserver up and running

    pypi-server run -p 8080~/packages&# Will listen to all IPs.
  3. From the client computer, type this

    # Download and install hosted packages.pip install --extra-index-url http://localhost:8080/simple/ ...# orpip install --extra-index-url http://localhost:8080 ...# Search hosted packages.pip search --index http://localhost:8080 ...# Note that pip search does not currently work with the /simple/ endpoint.

    [!TIP]See alsoClient-side configurations for avoiding tedious typing.

  4. Enterpypi-server -h in the cmd-line to print a detailed usage message

    usage: pypi-server [-h] [-v] [--log-file FILE] [--log-stream STREAM]                   [--log-frmt FORMAT] [--hash-algo HASH_ALGO]                   [--backend {auto,simple-dir,cached-dir}] [--version]                   {run,update} ...start PyPI compatible package server serving packages from PACKAGES_DIRECTORY. If PACKAGES_DIRECTORY is not given on the command line, it uses the default ~/packages. pypiserver scans this directory recursively for packages. It skips packages and directories starting with a dot. Multiple package directories may be specified.positional arguments:  {run,update}    run                 Run pypiserver, serving packages from                        PACKAGES_DIRECTORY    update              Handle updates of packages managed by pypiserver. By                        default, a pip command to update the packages is                        printed to stdout for introspection or pipelining. See                        the `-x` option for updating packages directly.options:  -h, --help            show this help message and exit  -v, --verbose         Enable verbose logging; repeat for more verbosity.  --log-file FILE       Write logging info into this FILE, as well as to                        stdout or stderr, if configured.  --log-stream STREAM   Log messages to the specified STREAM. Valid values are                        stdout, stderr, and none  --log-frmt FORMAT     The logging format-string.  (see `logging.LogRecord`                        class from standard python library)  --hash-algo HASH_ALGO                        Any `hashlib` available algorithm to use for                        generating fragments on package links. Can be disabled                        with one of (0, no, off, false).  --backend {auto,simple-dir,cached-dir}                        A backend implementation. Keep the default 'auto' to                        automatically determine whether to activate caching or                        not  --version             show program's version number and exitVisit https://github.com/pypiserver/pypiserver for more information

More details about pypi server run

Enterpypi-server run -h in the cmd-line to print a detailed usage

usage: pypi-server run [-h] [-v] [--log-file FILE] [--log-stream STREAM]                       [--log-frmt FORMAT] [--hash-algo HASH_ALGO]                       [--backend {auto,simple-dir,cached-dir}] [--version]                       [-p PORT] [-i HOST] [-a AUTHENTICATE]                       [-P PASSWORD_FILE] [--disable-fallback]                       [--fallback-url FALLBACK_URL]                       [--health-endpoint HEALTH_ENDPOINT] [--server METHOD]                       [-o] [--welcome HTML_FILE] [--cache-control AGE]                       [--log-req-frmt FORMAT] [--log-res-frmt FORMAT]                       [--log-err-frmt FORMAT]                       [--server-base-url SERVER_BASE_URL]                       [package_directory ...]positional arguments:  package_directory     The directory from which to serve packages.options:  -h, --help            show this help message and exit  -v, --verbose         Enable verbose logging; repeat for more verbosity.  --log-file FILE       Write logging info into this FILE, as well as to                        stdout or stderr, if configured.  --log-stream STREAM   Log messages to the specified STREAM. Valid values are                        stdout, stderr, and none  --log-frmt FORMAT     The logging format-string.  (see `logging.LogRecord`                        class from standard python library)  --hash-algo HASH_ALGO                        Any `hashlib` available algorithm to use for                        generating fragments on package links. Can be disabled                        with one of (0, no, off, false).  --backend {auto,simple-dir,cached-dir}                        A backend implementation. Keep the default 'auto' to                        automatically determine whether to activate caching or                        not  --version             show program's version number and exit  -p PORT, --port PORT  Listen on port PORT (default: 8080)  -i HOST, -H HOST, --interface HOST, --host HOST                        Listen on interface INTERFACE (default: 0.0.0.0)  -a AUTHENTICATE, --authenticate AUTHENTICATE                        Comma-separated list of (case-insensitive) actions to                        authenticate (options: download, list, update;                        default: update).                                                  Any actions not specified are not authenticated, so                         to authenticate downloads and updates, but allow                         unauthenticated viewing of the package list, you would                         use:                                                   pypi-server -a 'download, update' -P                          ./my_passwords.htaccess                                                 To disable authentication, use:                                                   pypi-server -a . -P .                                                 See the `-P` option for configuring users and                        passwords.                                                 Note that when uploads are not protected, the                        `register` command is not necessary, but `~/.pypirc`                        still needs username and password fields, even if                        bogus.  -P PASSWORD_FILE, --passwords PASSWORD_FILE                        Use an apache htpasswd file PASSWORD_FILE to set                        usernames and passwords for authentication.                                                 To allow unauthorized access, use:                                                   pypi-server -a . -P .                           --disable-fallback    Disable the default redirect to PyPI for packages not                        found in the local index.  --fallback-url FALLBACK_URL                        Redirect to FALLBACK_URL for packages not found in the                        local index.  --health-endpoint HEALTH_ENDPOINT                        Configure a custom liveness endpoint. It always                        returns 200 Ok if the service is up. Otherwise, it                        means that the service is not responsive.  --server METHOD       Use METHOD to run the server. Valid values include                        paste, cherrypy, twisted, gunicorn, gevent, wsgiref,                        and auto. The default is to use "auto", which chooses                        one of paste, cherrypy, twisted, or wsgiref.  -o, --overwrite       Allow overwriting existing package files during                        upload.  --welcome HTML_FILE   Use the contents of HTML_FILE as a custom welcome                        message on the home page.  --cache-control AGE   Add "Cache-Control: max-age=AGE" header to package                        downloads. Pip 6+ requires this for caching.AGE is                        specified in seconds.  --log-req-frmt FORMAT                        A format-string selecting Http-Request properties to                        log; set to '%s' to see them all.  --log-res-frmt FORMAT                        A format-string selecting Http-Response properties to                        log; set to '%s' to see them all.  --log-err-frmt FORMAT                        A format-string selecting Http-Error properties to                        log; set to '%s' to see them all.  --server-base-url SERVER_BASE_URL                        Serve all routes under SERVER_BASE_URL prefix                        (default: {DEFAULTS.SERVER_BASE_URL})

More details about pypi-server update

More details aboutpypi-server update

usage: pypi-server update [-h] [-v] [--log-file FILE] [--log-stream STREAM]                          [--log-frmt FORMAT] [--hash-algo HASH_ALGO]                          [--backend {auto,simple-dir,cached-dir}] [--version]                          [-x] [-d DOWNLOAD_DIRECTORY] [-u]                          [--blacklist-file IGNORELIST_FILE]                          [package_directory ...]positional arguments:  package_directory     The directory from which to serve packages.options:  -h, --help            show this help message and exit  -v, --verbose         Enable verbose logging; repeat for more verbosity.  --log-file FILE       Write logging info into this FILE, as well as to                        stdout or stderr, if configured.  --log-stream STREAM   Log messages to the specified STREAM. Valid values are                        stdout, stderr, and none  --log-frmt FORMAT     The logging format-string. (see `logging.LogRecord`                        class from standard python library)  --hash-algo HASH_ALGO                        Any `hashlib` available algorithm to use for                        generating fragments on package links. Can be disabled                        with one of (0, no, off, false).  --backend {auto,simple-dir,cached-dir}                        A backend implementation. Keep the default 'auto' to                        automatically determine whether to activate caching or                        not  --version             show program's version number and exit  -x, --execute         Execute the pip commands rather than printing to                        stdout  -d DOWNLOAD_DIRECTORY, --download-directory DOWNLOAD_DIRECTORY                        Specify a directory where packages updates will be                        downloaded. The default behavior is to use the                        directory which contains the package being updated.  -u, --allow-unstable  Allow updating to unstable versions (alpha, beta, rc,                        dev, etc.)  --blacklist-file IGNORELIST_FILE, --ignorelist-file IGNORELIST_FILE                        Don't update packages listed in this file (one package                        name per line, without versions, '#' comments                        honored). This can be useful if you upload private                        packages into pypiserver, but also keep a mirror of                        public packages that you regularly update. Attempting                        to pull an update of a private package from `pypi.org`                        might pose a security risk - e.g. a malicious user                        might publish a higher version of the private package,                        containing arbitrary code.

Client-Side Configurations

Always specifying the pypi url on the command line is a bitcumbersome.

Tip

Sincepypiserver redirectspip/easy_install to thepypi.org indexif it doesn't have a requested package, it is a good idea to configure them toalways use your local pypi index.

Configuring pip

Forpip command this can be done by setting the environment variablePIP_EXTRA_INDEX_URL in your.bashr/.profile/.zshrc

export PIP_EXTRA_INDEX_URL=http://localhost:8080/simple/

or by adding the following lines to~/.pip/pip.conf

[global]extra-index-url = http://localhost:8080/simple/

Note

If you have installedpypiserver on a remote url withouthttpsyou will receive an "untrusted" warning frompip, urging you to appendthe--trusted-host option. You can also include this option permanentlyin your configuration-files or environment variables.

Configuring easy_install

Foreasy_install command you may set the following configuration in~/.pydistutils.cfg

[easy_install]index_url = http://localhost:8080/simple/

Uploading Packages Remotely

Instead of copying packages directly to the server's folder (i.e. withscp),you may use python tools for the task, e.g.python setup.py upload.
In that case,pypiserver is responsible for authenticating the upload-requests.

Important

We strongly advise topassword-protect your uploads!

It is possible to disable authentication for uploads (e.g. in intranets).To avoid lazy security decisions, read help for-P and-a options.

Apache Like Authentication (htpasswd)

  1. First make sure you have thepasslib module installed (note thatpasslib>=1.6 is required), which is needed for parsing the Apachehtpasswd file specified by the-P,--passwords option(see next steps)

    pip install passlib
  2. Create the Apachehtpasswd file with at least one user/password pairwith this command (you'll be prompted for a password)

    htpasswd -sc htpasswd.txt<some_username>

Tip

Read thisSOquestion for runninghtpasswd cmd underWindowsor if you have bogus passwords that you don't care because they are foran internal service (which is still "bad", from a security perspective...)you may use thispublic service

Tip

When accessing pypiserver via the api, alternate authenticationmethods are available via theauther config flag. Any callablereturning a boolean can be passed through to the pypiserver config inorder to provide custom authentication. For example, to configurepypiserver to authenticate using thepython-pam

importpampypiserver.default_config(auther=pam.authenticate)

Please seeUsing Ad-hoc authentication providers for more information.

  1. You need to restart the server with the-P option only once(but user/password pairs can later be added or updated on the fly)

    ./pypi-server run -p 8080 -P htpasswd.txt~/packages&

Upload with setuptools

  1. On client-side, edit or create a~/.pypirc file with a similar content:

    [distutils]index-servers =  pypi  local[pypi]username:<your_pypi_username>password:<your_pypi_passwd>[local]repository: http://localhost:8080username: <some_username>password: <some_passwd>
  2. Then from within the directory of the python-project you wish to upload,issue this command:

    python setup.py sdist upload -rlocal

Upload with twine

To avoid storing you passwords on disk, in clear text, you may either:

  • use theregistersetuptools's command with the-r option,like that

    python setup.py sdist register -rlocal upload -rlocal
  • usetwine library, whichbreaks the procedure in two steps. In addition, it supports signingyour files with PGP-Signatures and uploading the generated.asc filestopypiserver::

    twine upload -rlocal --sign -identity user_name ./foo-1.zip

Using the Docker Image

Starting with version 1.2.5, official Docker images will be built for eachpush tomain, each dev, alpha, or beta release, and each final release.

The most recent full release will always be available under the taglatest,and the currentmain branch will always be available under the tagunstable.

You can always check to see what tags are currently available at ourDocker Repo.

To run the most recent release ofpypiserver with Docker, simply

docker run pypiserver/pypiserver:latest run

This startspypiserver serving packages from the/data/packagesdirectory inside the container, listening on the container port 8080.

The container takes all the same arguments as the normalpypi-serverexecutable, with the exception of the internal container port (-p),which will always be 8080.

Of course, just running a container isn't that interesting. To mapport 80 on the host to port 8080 on the container::

docker run -p 80:8080 pypiserver/pypiserver:latest run

You can now access yourpypiserver atlocalhost:80 in a web browser.

To serve packages from a directory on the host, e.g.~/packages

docker run -p 80:8080 -v~/packages:/data/packages pypiserver/pypiserver:latest run

To authenticate against a local.htpasswd file::

docker run -p 80:8080 -v~/.htpasswd:/data/.htpasswd pypiserver/pypiserver:latest run -P .htpasswd packages

You can also specifypypiserver to run as a Docker service using acomposefile. An example composefile is provided asdocker-compose.yaml

Alternative Installation Methods

When trying the methods below, first use the following command to check whetherprevious versions ofpypiserver already exist, and (optionally) uninstall them::

# VERSION-CHECK: Fails if not installed.pypi-server --version# UNINSTALL: Invoke again until it fails.pip uninstall pypiserver

Installing the Very Latest Version

In case the latest version inpypi is a pre-release, you have to usepip's--pre option. And to update an existing installation combine itwith--ignore-installed

pip install pypiserver --pre -I

You can even install the latestpypiserver directly fromgithub with thefollowing command, assuming you havegit installed on yourPATH

pip install git+git://github.com/pypiserver/pypiserver.git

Recipes

Managing the Package Directory

Thepypi-server command has theupdate command that searches for updates ofavailable packages. It scans the package directory for availablepackages and searches on pypi.org for updates. Without furtheroptionspypi-server update will just print a list of commands which mustbe run in order to get the latest version of each package. Outputlooks like:

$ ./pypi-server update checking 106 packagesfor newer version.........u.e...........e..u..................e..............................e.............................no releases found on pypifor PyXML, Pymacs, mercurial, setuptools# update raven from 1.4.3 to 1.4.4pip -q install --no-deps  --extra-index-url https://pypi.org/simple/ -d /home/ralf/packages/mirror raven==1.4.4# update greenlet from 0.3.3 to 0.3.4pip -q install --no-deps  --extra-index-url https://pypi.org/simple/ -d /home/ralf/packages/mirror greenlet==0.3.4

It first prints for each package a single character after checking theavailable versions on pypi. A dot(.) means the package is up-to-date,'u'means the package can be updated and'e' means the list of releases onpypi is empty. After that it shows apip command line which can be usedto update a one package. Either copy and paste that or runpypi-server update -x in order to really execute those commands. You needto havepip installed for that to work however.

Specifying an additional-u option will also allow alpha, beta andrelease candidates to be downloaded. Without this option thesereleases won't be considered.

Serving Thousands of Packages

Important

By default,pypiserver scans the entire packages directory each time anincoming HTTP request occurs. This isn't a problem for a small number ofpackages, but causes noticeable slow-downs when serving thousands of packages.

If you run into this problem, significant speedups can be gained by enablingpypiserver's directory caching functionality. The only requirement is toinstall thewatchdog package, or it can be installed duringpypiserverinstallation, by specifying thecache extras option::

pip install pypiserver[cache]

Additional speedups can be obtained by using your webserver's builtincaching functionality. For example, if you are usingnginx as areverse-proxy as described below inBehind a reverse proxy, you caneasily enable caching. For example, to allow nginx to cache up to10 gigabytes of data for up to 1 hour::

proxy_cache_path /data/nginx/cache                  levels=1:2                  keys_zone=pypiserver_cache:10m                  max_size=10g                  inactive=60m                  use_temp_path=off;server{    # ...location /{proxy_cache pypiserver_cache;proxy_passhttp://localhost:8080;}}

Tip

Using webserver caching is especially helpful if you have high requestvolume. Using nginx caching, a real-world pypiserver installation wasable to easily support over 1000 package downloads/min at peak load.

Managing Automated Startup

There are a variety of options for handling the automated starting ofpypiserver upon system startup. Two of the most common aresystemd andsupervisor for linux systems. For windows creating services with scripts isn'tan easy task without a third party tool such asNSSM.

Running As a systemd Service

systemd is installed by default on most modern Linux systems and as such,it is an excellent option for managing the pypiserver process. An exampleconfig file forsystemd can be seen below

[Unit]Description=A minimal PyPI server for use with pip/easy_install.After=network.target[Service]Type=simple# systemd requires absolute path here too.PIDFile=/var/run/pypiserver.pidUser=www-dataGroup=www-dataExecStart=/usr/local/bin/pypi-server run -p 8080 -a update,download --log-file /var/log/pypiserver.log -P /etc/nginx/.htpasswd /var/www/pypiExecStop=/bin/kill -TERM $MAINPIDExecReload=/bin/kill -HUP $MAINPIDRestart=alwaysWorkingDirectory=/var/www/pypiTimeoutStartSec=3RestartSec=5[Install]WantedBy=multi-user.target

Adjusting the paths and adding this file aspypiserver.service into yoursystemd/system directory will allow management of the pypiserver process withsystemctl, e.g.systemctl start pypiserver.

More useful information aboutsystemd can be found athttps://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units

Launching through supervisor

supervisor has the benefit of being a pure pythonpackage and as such, it provides excellent cross-platform support for processmanagement. An example configuration file forsupervisor is given below

[program:pypi]command=/home/pypi/pypi-venv/bin/pypi-server run -p 7001 -P /home/pypi/.htpasswd /home/pypi/packagesdirectory=/home/pypiuser=pypiautostart=trueautorestart=truestderr_logfile=/var/log/pypiserver.err.logstdout_logfile=/var/log/pypiserver.out.log

From there, the process can be managed viasupervisord usingsupervisorctl.

Running As a service with NSSM

For Windows downloadNSSM fromhttps://nssm.cc unzip to adesired location such as Program Files. Decide whether you are goingto usewin32 orwin64, and add thatexe to environmentPATH.

Create astart_pypiserver.bat

pypi-server run -p 8080 C:\Path\To\Packages&

Tip

Test the batch file by running it first before creating the service.Make sure you can access the server remotely, and install packages. If you can,proceed, if not troubleshoot until you can. This will ensure you know the serverworks, before adding NSSM into the mix.

From the command prompt

nssm install pypiserver

This command will launch a NSSM gui application

Path: C:\Path\To\start_pypiserver.batStartup directory: Auto generates when selecting pathService name: pypiserver

There are more tabs, but that is the basic setup. If the service needs to be running with a certainlogin credentials, make sure you enter those credentials in the logon tab.

Start the service

nssm start pypiserver

Tip

Other useful commands

nssm --helpnssm stop<servicename>nssm restart<servicename>nssm status<servicename>

For detailed information please visithttps://nssm.cc

Using a Different WSGI Server

  • Thebottle web-server which supports many WSGI-servers, among others,paste,cherrypy,twisted andwsgiref (part of Python); you selectthem using the--server flag.

  • You may view all supported WSGI servers using the following interactive code

    >>>frompypiserverimportbottle_wrapperasbottle>>>list(bottle.server_names.keys())['cgi','gunicorn','cherrypy','eventlet','tornado','geventSocketIO','rocket','diesel','twisted','wsgiref','fapws3','bjoern','gevent','meinheld','auto','aiohttp','flup','gae','paste','waitress']
  • If none of the above servers matches your needs, invoke just thepypiserver:app() method which returns the internal WSGI-app WITHOUTstarting-up a server - you may then send it to any WSGI server you like.Read also theUtilizing the API section.

  • Some examples are given below - you may find more details inbottlesite.

Apache

To use yourApache2 withpypiserver, prefer to utilizemod_wsgi asexplained inbottle's documentation.

Note

If you choose instead to go withmod_proxy, mind that you may bump into problemswith the prefix-path (see#155).

  1. Adapt and place the followingApache configuration either into top-level scope,or inside some<VirtualHost> (contributed by Thomas Waldmann):

    WSGIScriptAlias//yoursite/wsgi/pypiserver-wsgi.pyWSGIDaemonProcess       pypisrv user=pypisrv group=pypisrv umask=0007 \                        processes=1 threads=5 maximum-requests=500 \                        display-name=wsgi-pypisrv inactivity-timeout=300WSGIProcessGroup        pypisrvWSGIPassAuthorizationOn    # Required for authentication (https://github.com/pypiserver/pypiserver/issues/288)<Directory/yoursite/wsgi>Require all granted</Directory>

    or if using olderApache < 2.4, substitute the last part with this::

    <Directory/yoursite/wsgi>Order deny,allowAllowfrom all</Directory>
  2. Then create the/yoursite/cfg/pypiserver.wsgi file and make sure thattheuser andgroup of theWSGIDaemonProcess directive(pypisrv:pypisrv in the example) have the read permission on it

    importpypiserverconf=pypiserver.default_config(root="/yoursite/packages",password_file="/yoursite/htpasswd", )application=pypiserver.app(**conf)

    [!TIP]If you have installedpypiserver in a virtualenv, followmod_wsgi'sinstructionsand prepend the python code above with the following

    importsitesite.addsitedir('/yoursite/venv/lib/pythonX.X/site-packages')

Note

For security reasons, notice that theDirectory directive grants accessto a directory holding thewsgi start-up script, alone; nothing else.

Note

To enable HTTPS support on Apache, configure the directive that contains theWSGI configuration to use SSL.

gunicorn

The following command usesgunicorn to startpypiserver

gunicorn -w4'pypiserver:app(root="/home/ralf/packages")'

or when using multiple roots

gunicorn -w4'pypiserver:app(root=["/home/ralf/packages", "/home/ralf/experimental"])'

paste

paste allows to run multiple WSGI applicationsunder different URL paths. Therefore, it is possible to serve different setof packages on different paths.

The following examplepaste.ini could be used to serve stable andunstable packages on different paths

[composite:main]use = egg:Paste#urlmap/unstable/ = unstable/ = stable[app:stable]use = egg:pypiserver#mainroot = ~/stable-packages[app:unstable]use = egg:pypiserver#mainroot = ~/stable-packages    ~/unstable-packages[server:main]use = egg:gunicorn#mainhost = 0.0.0.0port = 9000workers = 5accesslog = -

Note

You need to install some more dependencies for this to work, like::

pip install paste pastedeploy gunicorn pypiserver

The server can then start with

gunicorn_paster paste.ini

Behind a Reverse Proxy

You can runpypiserver behind a reverse proxy as well.

Nginx

Extend your nginx configuration

upstream pypi{server              pypiserver.example.com:12345 fail_timeout=0;}server{server_name         myproxy.example.com;location /{proxy_set_header  Host$host:$server_port;proxy_set_header  X-Forwarded-Proto$scheme;proxy_set_header  X-Real-IP$remote_addr;proxy_passhttp://pypi;}}

As of pypiserver 1.3, you may also use theX-Forwarded-Host header in yourreverse proxy config to enable changing the base URL. For example if youwant to host pypiserver under a particular path on your server

upstream pypi{server              localhost:8000;}server{location /pypi/{proxy_set_header  X-Forwarded-Host$host:$server_port/pypi;proxy_set_header  X-Forwarded-Proto$scheme;proxy_set_header  X-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_header  X-Real-IP$remote_addr;proxy_passhttp://pypi;}}

Supporting HTTPS

Using a reverse proxy is the preferred way of getting pypiserver behindHTTPS. For example, to put pypiserver behind HTTPS on port 443, withautomatic HTTP redirection, usingnginx

upstream pypi{server               localhost:8000;}server{listen80 default_server;server_name         _;return301 https://$host$request_uri;}server{listen443ssl;server_name         pypiserver.example.com;ssl_certificate     /etc/star.example.com.crt;ssl_certificate_key /etc/star.example.com.key;ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;ssl_ciphers         HIGH:!aNULL:!MD5;location /{proxy_set_header  Host$host:$server_port;proxy_set_header  X-Forwarded-Proto$scheme;proxy_set_header  X-Real-IP$remote_addr;proxy_passhttp://pypi;}}

Tip

Please seenginx's HTTPS docs for more details.

Getting and keeping your certificates up-to-date can be simplified using,for example, usingcertbot and letsencrypt.

Traefik

It is also possible to useTraefik to put pypiserverbehind HTTPS on port 443, with automatic HTTP redirection using Docker Compose.Please see the provideddocker-compose.ymlexample for more information.

Utilizing the API

In order to enable ad-hoc authentication-providers or to use WSGI-serversnot supported bybottle out-of-the-box, you needed to launchpypiservervia its API.

  • The main entry-point for configuringpypiserver is thepypiserver:app()function. This function returns the internal WSGI-app that you my thensend to any WSGI-server you like.

  • To get allpypiserver:app() keywords and their explanations, read thefunctionpypiserver:default_config()

  • Finally, to fire-up a WSGI-server with the configured app, invokethebottle:run(app, host, port, server) function.Note thatpypiserver ships with its own copy ofbottle; to use it,import it like that:from pypiserver import bottle

Using Ad-Hoc Authentication Providers

Theauther keyword ofpypiserver:app() function maybe set only usingthe API. This can be any callable that returns a boolean when passedtheusername and thepassword for a given request.

For example, to authenticate users based on the/etc/passwd file under Unix,you may delegate such decisions to thepython-pam library by followingthese steps:

  1. Ensurepython-pam module is installed

    pip install python-pam
  2. Create a python-script along these lines

    # pypiserver-start.pyimportpypiserverfrompypiserverimportbottle_wrapperasbottleimportpamapp=pypiserver.app(root='./packages',auther=pam.authenticate)bottle.run(app=app,host='0.0.0.0',port=80,server='auto')
  3. Invoke the python-script to start-uppypiserver

    python pypiserver-start.py

Note

Thepython-pam module, requiresread access to/etc/shadow file;you may add the user under whichpypiserver runs into theshadowgroup, with a command like this:sudo usermod -a -G shadow pypy-user.

Use with MicroPython

The MicroPython interpreter for embedded devices can install packages with themoduleupip.py. The module uses a specialized json-endpoint to retrievepackage information. This endpoint is supported bypypiserver.

It can be tested with the UNIX port ofmicropython

cd micropythonports/unix/micropython -m tools.upip install -i http://my-server:8080 -p /tmp/mymodules micropython-foobar

Installing packages from the REPL of an embedded device works in this way:

importnetworkimportupipsta_if=network.WLAN(network.STA_IF)sta_if.active(True)sta_if.connect('<your ESSID>','<your password>')upip.index_urls= ["http://my-server:8080"]upip.install("micropython-foobar")

Further information on micropython-packaging can be found here:https://docs.micropython.org/en/latest/reference/packages.html

Custom Health Check Endpoint

pypiserver provides a default health endpoint at/health. It always returns200 Ok if the service is up. Otherwise, it means that the service is not responsive.

In addition,pypiserver allows users to customize the health endpoint.Alphanumeric characters, hyphens, forward slashes and underscores are allowedand the endpoint should not overlap with any existing routes.Valid examples:/healthz,/health/live-1,/api_health,/action/health

Configure a custom health endpoint by CLI arguments

Run pypiserver with--health-endpoint argument:

pypi-server run --health-endpoint /action/health

Configure a custom health endpoint by script

importpypiserverfrompypiserverimportbottle_wrapperasbottleapp=pypiserver.app(root="./packages",health_endpoint="/action/health")bottle.run(app=app,host="0.0.0.0",port=8080,server="auto")

Trycurlhttp://localhost:8080/action/health

Exposingpypi-server on a URL with a custom prefix

The--server-base-url config option enables hosting yourpypi-server deployment behind a URL prefix.

It can come handy when you are exposingpypi-server through a proxy or ingress.

  1. Start the server with a custom URL prefix:

    pypi-server run --server-base-url /prefix/
  2. And it is accessible at the following URL:

    $ curl http://localhost:8080/prefix/<html lang="en"><head><meta charset="utf-8"><title>Welcome to pypiserver!</title></head><body># ...

Sources

To create a copy of the repository, use

git clone https://github.com/pypiserver/pypiserver.gitcd pypiserver

To receive any later changes, in the above folder use:

git pull

Known Limitations

Important

pypiserver does not implement the full API as seen onPyPI.It implements just enough to makeeasy_install,pip install, andsearch work.

The following limitations are known:

  • Commandpypi -U that compares uploaded packages withpypi to see ifthey are outdated, does not respect a http-proxy environment variable(see#19.
  • It accepts documentation uploads but does not save them todisk (see#47 for adiscussion)

Please use Github'sbugtrackerfor other bugs you find.

Similar Projects

There are lots of other projects, which allow you to run your ownPyPI server. Ifpypiserver doesn't work for you, the following areamong the most popular alternatives:

Unmaintained or archived

These projects were once alternatives to pypiserver but are now either unmaintained or archived.

  • pip2pia simple cmd-line tool that builds a PyPI-compatible local folder from pip requirements

  • flask-pypi-proxyA proxy for PyPI that also enables uploading custom packages.

Related Software

Though not direct alternatives forpypiserver's use as an indexserver, the following is a list of related software projects that youmay want to familiarize with:

  • pypi-uploader:A command-line utility to upload packages to yourpypiserver from pypi withouthaving to store them locally first.

  • twine:A command-line utility for interacting with PyPI orpypiserver.

  • warehouse:the software that powersPyPI itself. It is not generally intended tobe run by end-users.

Licensing

pypiserver contains a copy ofbottle which isavailable under the MIT license, and the remaining part is distributed underthe zlib/libpng license. See theLICENSE.txt file.


[8]ページ先頭

©2009-2025 Movatter.jp