Skip to content

Commit

Permalink
Merge pull request #1 from brainelectronics/feature/initial-implement…
Browse files Browse the repository at this point in the history
…ation

Initial implementation
  • Loading branch information
brainelectronics authored Oct 22, 2022
2 parents 98e1622 + 9c75022 commit f24e5b0
Show file tree
Hide file tree
Showing 6 changed files with 294 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# created files based on README examples
data/*
.htpasswd
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 Jones
Copyright (c) 2022 brainelectronics

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
236 changes: 235 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,236 @@
# test-pypiserver
# Test PyPi Server

PyPi Server for test deployments of MicroPython packages

---------------

## General

PyPi Server for testing and deploy of MicroPython packages

<!-- MarkdownTOC -->

- [Installation](#installation)
- [Install required tools](#install-required-tools)
- [Python](#python)
- [Docker Compose](#docker-compose)
- [htpasswd](#htpasswd)
- [Setup](#setup)
- [Directories](#directories)
- [Password file](#password-file)
- [pypirc file](#pypirc-file)
- [Usage](#usage)
- [Start PyPi server](#start-pypi-server)
- [Upload](#upload)
- [Download](#download)
- [Python](#python-1)
- [MicroPython](#micropython)
- [Connect to a network](#connect-to-a-network)
- [Install latest package version](#install-latest-package-version)
- [Install specific package version](#install-specific-package-version)
- [Credits](#credits)

<!-- /MarkdownTOC -->

## Installation
### Install required tools
#### Python

Python3 must be installed on your system. Check the current Python version
with the following command

```bash
python --version
python3 --version
```

Depending on which command `Python 3.x.y` (with x.y as some numbers) is
returned, use that command to proceed.

```bash
python3 -m venv .venv
source .venv/bin/activate

pip install -r requirements.txt
```

#### Docker Compose

See [Install Docker Compose][ref-docker-compose-install]

```bash
docker compose version
# Docker Compose version v2.10.2
```

#### htpasswd

See [htpasswd docs][ref-htpasswd-usage]

```bash
sudo apt-get install apache2-utils
```

## Setup
### Directories

Create the required directories to store the uploaded artifacts

```bash
mkdir -p data/auth
mkdir -p data/packages
```

### Password file

```bash
htpasswd -sc data/auth/.htpasswd upload-bot-0

New password: asdf
Re-type new password: asdf
Adding password for user upload-bot-0
```

### pypirc file

This file is used to authenticate the client at the PyPi Server. Edit or create
a `~/.pypirc` file on your system with a similar content

```
[distutils]
index-servers =
pypi
mypypiserver
[pypi]
username:<your_pypi_username>
password:<your_pypi_passwd>
[mypypiserver]
repository: http://localhost:8089
username: upload-bot-0
password: asdf
```

## Usage
### Start PyPi server

Run the following command in the directory of the `docker-compose.yml` file

```bash
docker compose up
```

The PyPi server will be available on `http://localhost:8089`. The port `8089`
is choosen as maybe other web servers or services are already running on the
system and using the general default port `8080`.

### Upload

In order to upload an already created distribution file use this command

```bash
# if specified in pypirc file
twine upload --repository mypypiserver path/to/my-custom-package.tar.gz

# use a URL instead of a keyword
twine upload --repository http://localhost:8089 path/to/my-custom-package.tar.gz
```

### Download
#### Python

```bash
# if specified in pypirc file
pip install 'my-custom-package==0.1.0'

# otherwise use the raw URL to the PyPi server
pip install --index-url http://localhost:8089 --trusted-host http://localhost:8089 'my-custom-package==0.1.0'
```

#### MicroPython

To use the PyPi server with MicroPython and it's `upip` package, a specialized
JSON endpoint is used, which is supported by pypiserver to provide the package
informations. The JSON data can be inspected at
`http://localhost:8089/PACKAGE_NAME/json`. It contains similar data as the
following example depending on the IP address running the PyPi server and of
course the uploaded packages.

```JSON
{
"info": {
"version": "0.2.0rc99+dev42"
},
"releases": {
"0.2.0rc99+dev42": [
{
"url": "http://192.168.178.105:8089/packages/my-micropython-package-0.2.0rc99+dev42.tar.gz"
}
],
"0.1.0rc1+dev1": [
{
"url": "http://192.168.178.105:8089/packages/my-micropython-package-0.1.0rc1+dev1.tar.gz"
}
]
}
}
```

MicroPython will [get this JSON][ref-upy-get-package-data] and install either
the latest version, taken specified by `['info']['version']` and then looked
up in `['releases'][VERSION]` or from a specific version. In either case the
`url` value of the specified release will be used to download the archive file.

##### Connect to a network

```python
import network
import upip

station = network.WLAN(network.STA_IF)
station.active(True)
station.connect('SSID', 'PASSWORD')
```

##### Install latest package version

To install the latest version of the hosted `my-micropython-package` use
this set of commands on a MicroPython board

```python
upip.index_urls = ["http://IP-ADDRESS-OF-PYPISERVER:8089"]
upip.install("my-micropython-package")
```

Which will produce the following output on the MicroPython board

```
Installing my-micropython-package 0.2.0rc99+dev42 from http://192.168.178.105:8089/packages/my-micropython-package-0.2.0rc99+dev42.tar.gz
```

##### Install specific package version

To install a specific version of the hosted `my-micropython-package` use
this set of commands on a MicroPython board

```python
upip.index_urls = ["http://IP-ADDRESS-OF-PYPISERVER:8089"]
upip.install("my-micropython-package==0.1.0rc1+dev1")
```

Which will produce the following output on the MicroPython board

```
Installing my-micropython-package 0.1.0rc1+dev1 from http://192.168.178.105:8089/packages/my-micropython-package-0.1.0rc1+dev1.tar.gz
```

## Credits

Based on the [PyPiServer instructions][ref-pypiserver].

<!-- Links -->
[ref-docker-compose-install]: https://docs.docker.com/compose/install/
[ref-htpasswd-usage]: https://httpd.apache.org/docs/2.4/programs/htpasswd.html
[ref-upy-get-package-data]: https://github.com/micropython/micropython/blob/da4b38e7562dfa451917f9d7f344a7f26de8c7bd/tools/upip.py#L196
[ref-pypa-pypiserver]: https://github.com/pypiserver/pypiserver
33 changes: 33 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

<!--
## [x.y.z] - yyyy-mm-dd
### Added
### Changed
### Removed
### Fixed
-->
<!--
RegEx for release version from file
r"^\#\# \[\d{1,}[.]\d{1,}[.]\d{1,}\] \- \d{4}\-\d{2}-\d{2}$"
-->

## Released
## [0.1.0] - 2022-10-22
### Added
- This changelog file
- [`.gitignore`](.gitignore) file respecting custom content in `data` folder
- [`docker-compose.yml`](docker-compose.yml) file for the PyPi server
- [`requirements.txt`](requirements.txt) file
- Initial root [`README`](README.md)

<!-- Links -->
[Unreleased]: https://github.com/brainelectronics/test-pypiserver/compare/0.1.0...main

[0.1.0]: https://github.com/brainelectronics/test-pypiserver/tree/0.1.0

<!-- [ref-issue-1]: https://github.com/brainelectronics/test-pypiserver/issues/1 -->
18 changes: 18 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: '3.8'

services:
pypi-server:
image: pypiserver/pypiserver:v1.5.1
restart: unless-stopped
ports:
# PyPi server is available at http://localhost:8089 to avoid conflicts
# with other webservices running on 8080
- 8089:8080
container_name: pypi-server
volumes:
- $PWD/data/packages:/data/packages
- $PWD/data/auth:/data/auth
# require a authentication on uploading/updating packages
# use "/data/auth/.htpasswd" as lookup for passwords
# do not forward to real PyPI index if packages are not found in the local index
command: run --passwords /data/auth/.htpasswd --authenticate update --disable-fallback -vvv
4 changes: 4 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# List external packages here
# Avoid fixed versions
passlib>=1.6,<2
twine>=4.0.1,<5

0 comments on commit f24e5b0

Please sign in to comment.