Repackage to latest Python boilerplate.

Deprecate "ST7735" and rename module to "st7735".
This commit is contained in:
Phil Howard
2023-11-03 13:26:22 +00:00
parent c0733d678a
commit f6599b1854
26 changed files with 576 additions and 290 deletions

41
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Build
on:
pull_request:
push:
branches:
- main
jobs:
test:
name: Python ${{ matrix.python }}
runs-on: ubuntu-latest
strategy:
matrix:
python: ['3.9', '3.10', '3.11']
env:
RELEASE_FILE: ${{ github.event.repository.name }}-${{ github.event.release.tag_name || github.sha }}-py${{ matrix.python }}
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python }}
- name: Install Dependencies
run: |
make dev-deps
- name: Build Packages
run: |
make build
- name: Upload Packages
uses: actions/upload-artifact@v3
with:
name: ${{ env.RELEASE_FILE }}
path: dist/

36
.github/workflows/qa.yml vendored Normal file
View File

@@ -0,0 +1,36 @@
name: QA
on:
pull_request:
push:
branches:
- main
jobs:
test:
name: linting & spelling
runs-on: ubuntu-latest
env:
TERM: xterm-256color
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Set up Python '3,11'
uses: actions/setup-python@v3
with:
python-version: '3.11'
- name: Install Dependencies
run: |
make dev-deps
- name: Run Quality Assurance
run: |
make qa
- name: Run Code Checks
run: |
make check

View File

@@ -1,37 +1,41 @@
name: Python Tests name: Tests
on: on:
pull_request: pull_request:
push: push:
branches: branches:
- master - main
jobs: jobs:
test: test:
name: Python ${{ matrix.python }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
python: ['3.9', '3.10', '3.11'] python: ['3.9', '3.10', '3.11']
steps: steps:
- uses: actions/checkout@v2 - name: Checkout Code
uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python }} - name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v2 uses: actions/setup-python@v3
with: with:
python-version: ${{ matrix.python }} python-version: ${{ matrix.python }}
- name: Install Dependencies - name: Install Dependencies
run: | run: |
python -m pip install --upgrade setuptools tox make dev-deps
- name: Run Tests - name: Run Tests
working-directory: library
run: | run: |
tox -e py make pytest
- name: Coverage - name: Coverage
if: ${{ matrix.python == '3.9' }}
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
working-directory: library
run: | run: |
python -m pip install coveralls python -m pip install coveralls
coveralls --service=github coveralls --service=github
if: ${{ matrix.python == '3.11' }}

View File

@@ -1,70 +1,60 @@
LIBRARY_VERSION=$(shell grep version library/setup.cfg | awk -F" = " '{print $$2}') LIBRARY_NAME := $(shell hatch project metadata name 2> /dev/null)
LIBRARY_NAME=$(shell grep name library/setup.cfg | awk -F" = " '{print $$2}') LIBRARY_VERSION := $(shell hatch version 2> /dev/null)
.PHONY: usage install uninstall .PHONY: usage install uninstall check pytest qa build-deps check tag wheel sdist clean dist testdeploy deploy
usage: usage:
ifdef LIBRARY_NAME
@echo "Library: ${LIBRARY_NAME}" @echo "Library: ${LIBRARY_NAME}"
@echo "Version: ${LIBRARY_VERSION}\n" @echo "Version: ${LIBRARY_VERSION}\n"
else
@echo "WARNING: You should 'make dev-deps'\n"
endif
@echo "Usage: make <target>, where target is one of:\n" @echo "Usage: make <target>, where target is one of:\n"
@echo "install: install the library locally from source" @echo "install: install the library locally from source"
@echo "uninstall: uninstall the local library" @echo "uninstall: uninstall the local library"
@echo "check: peform basic integrity checks on the codebase" @echo "dev-deps: install Python dev dependencies"
@echo "python-readme: generate library/README.md from README.md + library/CHANGELOG.txt" @echo "check: perform basic integrity checks on the codebase"
@echo "python-wheels: build python .whl files for distribution" @echo "qa: run linting and package QA"
@echo "python-sdist: build python source distribution" @echo "pytest: run Python test fixtures"
@echo "python-clean: clean python build and dist directories" @echo "clean: clean Python build and dist directories"
@echo "python-dist: build all python distribution files" @echo "build: build Python distribution files"
@echo "python-testdeploy: build all and deploy to test PyPi" @echo "testdeploy: build and upload to test PyPi"
@echo "tag: tag the repository with the current version" @echo "deploy: build and upload to PyPi"
@echo "tag: tag the repository with the current version\n"
install: install:
./install.sh ./install.sh --unstable
uninstall: uninstall:
./uninstall.sh ./uninstall.sh
dev-deps:
python3 -m pip install -r requirements-dev.txt
sudo apt install dos2unix
check: check:
@echo "Checking for trailing whitespace" @bash check.sh
@! grep -IUrn --color "[[:blank:]]$$" --exclude-dir=sphinx --exclude-dir=.tox --exclude-dir=.git --exclude=PKG-INFO
@echo "Checking for DOS line-endings" qa:
@! grep -IlUrn --color " tox -e qa
" --exclude-dir=sphinx --exclude-dir=.tox --exclude-dir=.git --exclude=Makefile
@echo "Checking library/CHANGELOG.txt" pytest:
@cat library/CHANGELOG.txt | grep ^${LIBRARY_VERSION} tox -e py
@echo "Checking library/${LIBRARY_NAME}/__init__.py"
nopost:
@bash check.sh --nopost
tag: tag:
git tag -a "v${LIBRARY_VERSION}" -m "Version ${LIBRARY_VERSION}" git tag -a "v${LIBRARY_VERSION}" -m "Version ${LIBRARY_VERSION}"
build: check
@hatch build
clean:
-rm -r dist
testdeploy: build
library/README.md: README.md library/CHANGELOG.txt twine upload --repository testpypi dist/*
cp README.md library/README.md
printf "\n# Changelog\n" >> library/README.md
deploy: nopost build
library/LICENSE.txt: LICENSE twine upload dist/*
cp LICENSE library/LICENSE.txt
python-wheels: python-readme python-license
cd library; python3 setup.py bdist_wheel
cd library; python setup.py bdist_wheel
python-sdist: python-readme python-license
cd library; python setup.py sdist
python-clean:
-rm -r library/dist
-rm -r library/build
-rm -r library/*.egg-info
python-dist: python-clean python-wheels python-sdist
ls library/dist
python-testdeploy: python-dist
twine upload --repository-url https://test.pypi.org/legacy/ library/dist/*
python-deploy: check python-dist

4
ST7735.py Normal file
View File

@@ -0,0 +1,4 @@
from st7735 import * # noqa F403
from warnings import warn
warn("Using \"import ST7735\" is deprecated. Please \"import st7735\" (all lowercase)!", DeprecationWarning, stacklevel=2)

87
check.sh Executable file
View File

@@ -0,0 +1,87 @@
#!/bin/bash
# This script handles some basic QA checks on the source
NOPOST=$1
LIBRARY_NAME=`hatch project metadata name`
LIBRARY_VERSION=`hatch version | awk -F "." '{print $1"."$2"."$3}'`
POST_VERSION=`hatch version | awk -F "." '{print substr($4,0,length($4))}'`
success() {
echo -e "$(tput setaf 2)$1$(tput sgr0)"
}
inform() {
echo -e "$(tput setaf 6)$1$(tput sgr0)"
}
warning() {
echo -e "$(tput setaf 1)$1$(tput sgr0)"
}
while [[ $# -gt 0 ]]; do
K="$1"
case $K in
-p|--nopost)
NOPOST=true
shift
;;
*)
if [[ $1 == -* ]]; then
printf "Unrecognised option: $1\n";
exit 1
fi
POSITIONAL_ARGS+=("$1")
shift
esac
done
inform "Checking $LIBRARY_NAME $LIBRARY_VERSION\n"
inform "Checking for trailing whitespace..."
grep -IUrn --color "[[:blank:]]$" --exclude-dir=dist --exclude-dir=.tox --exclude-dir=.git --exclude=PKG-INFO
if [[ $? -eq 0 ]]; then
warning "Trailing whitespace found!"
exit 1
else
success "No trailing whitespace found."
fi
printf "\n"
inform "Checking for DOS line-endings..."
grep -lIUrn --color $'\r' --exclude-dir=dist --exclude-dir=.tox --exclude-dir=.git --exclude=Makefile
if [[ $? -eq 0 ]]; then
warning "DOS line-endings found!"
exit 1
else
success "No DOS line-endings found."
fi
printf "\n"
inform "Checking CHANGELOG.md..."
cat CHANGELOG.md | grep ^${LIBRARY_VERSION} > /dev/null 2>&1
if [[ $? -eq 1 ]]; then
warning "Changes missing for version ${LIBRARY_VERSION}! Please update CHANGELOG.md."
exit 1
else
success "Changes found for version ${LIBRARY_VERSION}."
fi
printf "\n"
inform "Checking for git tag ${LIBRARY_VERSION}..."
git tag -l | grep -E "${LIBRARY_VERSION}$"
if [[ $? -eq 1 ]]; then
warning "Missing git tag for version ${LIBRARY_VERSION}"
fi
printf "\n"
if [[ $NOPOST ]]; then
inform "Checking for .postN on library version..."
if [[ "$POST_VERSION" != "" ]]; then
warning "Found .$POST_VERSION on library version."
inform "Please only use these for testpypi releases."
exit 1
else
success "OK"
fi
fi

View File

@@ -1,26 +1,29 @@
#!/bin/bash #!/bin/bash
LIBRARY_NAME=`grep -m 1 name pyproject.toml | awk -F" = " '{print substr($2,2,length($2)-2)}'`
CONFIG=/boot/config.txt CONFIG=/boot/config.txt
DATESTAMP=`date "+%Y-%M-%d-%H-%M-%S"` DATESTAMP=`date "+%Y-%m-%d-%H-%M-%S"`
CONFIG_BACKUP=false CONFIG_BACKUP=false
APT_HAS_UPDATED=false APT_HAS_UPDATED=false
USER_HOME=/home/$SUDO_USER RESOURCES_TOP_DIR=$HOME/Pimoroni
RESOURCES_TOP_DIR=$USER_HOME/Pimoroni VENV_BASH_SNIPPET=$RESOURCES_DIR/auto_venv.sh
VENV_DIR=$HOME/.virtualenvs/pimoroni
WD=`pwd` WD=`pwd`
USAGE="sudo ./install.sh (--unstable)" USAGE="./install.sh (--unstable)"
POSITIONAL_ARGS=() POSITIONAL_ARGS=()
FORCE=false
UNSTABLE=false UNSTABLE=false
PYTHON3=`which python3` PYTHON="python"
user_check() { user_check() {
if [ $(id -u) -ne 0 ]; then if [ $(id -u) -eq 0 ]; then
printf "Script must be run as root. Try 'sudo ./install.sh'\n" printf "Script should not be run as root. Try './install.sh'\n"
exit 1 exit 1
fi fi
} }
confirm() { confirm() {
if [ "$FORCE" == '-y' ]; then if $FORCE; then
true true
else else
read -r -p "$1 [y/N] " response < /dev/tty read -r -p "$1 [y/N] " response < /dev/tty
@@ -53,12 +56,52 @@ warning() {
echo -e "$(tput setaf 1)$1$(tput sgr0)" echo -e "$(tput setaf 1)$1$(tput sgr0)"
} }
venv_bash_snippet() {
if [ ! -f $VENV_BASH_SNIPPET ]; then
cat << EOF > $VENV_BASH_SNIPPET
# Add `source $RESOURCES_DIR/auto_venv.sh` to your ~/.bashrc to activate
# the Pimoroni virtual environment automagically!
VENV_DIR="$VENV_DIR"
if [ ! -f \$VENV_DIR/bin/activate ]; then
printf "Creating user Python environment in \$VENV_DIR, please wait...\n"
mkdir -p \$VENV_DIR
python3 -m venv --system-site-packages \$VENV_DIR
fi
printf " ↓ ↓ ↓ ↓ Hello, we've activated a Python venv for you. To exit, type \"deactivate\".\n"
source \$VENV_DIR/bin/activate
EOF
fi
}
venv_check() {
PYTHON_BIN=`which $PYTHON`
if [[ $VIRTUAL_ENV == "" ]] || [[ $PYTHON_BIN != $VIRTUAL_ENV* ]]; then
printf "This script should be run in a virtual Python environment.\n"
if confirm "Would you like us to create one for you?"; then
if [ ! -f $VENV_DIR/bin/activate ]; then
inform "Creating virtual Python environment in $VENV_DIR, please wait...\n"
mkdir -p $VENV_DIR
/usr/bin/python3 -m venv $VENV_DIR --system-site-packages
venv_bash_snippet
else
inform "Found existing virtual Python environment in $VENV_DIR\n"
fi
inform "Activating virtual Python environment in $VENV_DIR..."
inform "source $VENV_DIR/bin/activate\n"
source $VENV_DIR/bin/activate
else
exit 1
fi
fi
}
function do_config_backup { function do_config_backup {
if [ ! $CONFIG_BACKUP == true ]; then if [ ! $CONFIG_BACKUP == true ]; then
CONFIG_BACKUP=true CONFIG_BACKUP=true
FILENAME="config.preinstall-$LIBRARY_NAME-$DATESTAMP.txt" FILENAME="config.preinstall-$LIBRARY_NAME-$DATESTAMP.txt"
inform "Backing up $CONFIG to /boot/$FILENAME\n" inform "Backing up $CONFIG to /boot/$FILENAME\n"
cp $CONFIG /boot/$FILENAME sudo cp $CONFIG /boot/$FILENAME
mkdir -p $RESOURCES_TOP_DIR/config-backups/ mkdir -p $RESOURCES_TOP_DIR/config-backups/
cp $CONFIG $RESOURCES_TOP_DIR/config-backups/$FILENAME cp $CONFIG $RESOURCES_TOP_DIR/config-backups/$FILENAME
if [ -f "$UNINSTALLER" ]; then if [ -f "$UNINSTALLER" ]; then
@@ -83,16 +126,20 @@ function apt_pkg_install {
if ! [ "$PACKAGES" == "" ]; then if ! [ "$PACKAGES" == "" ]; then
echo "Installing missing packages: $PACKAGES" echo "Installing missing packages: $PACKAGES"
if [ ! $APT_HAS_UPDATED ]; then if [ ! $APT_HAS_UPDATED ]; then
apt update sudo apt update
APT_HAS_UPDATED=true APT_HAS_UPDATED=true
fi fi
apt install -y $PACKAGES sudo apt install -y $PACKAGES
if [ -f "$UNINSTALLER" ]; then if [ -f "$UNINSTALLER" ]; then
echo "apt uninstall -y $PACKAGES" echo "apt uninstall -y $PACKAGES" >> $UNINSTALLER
fi fi
fi fi
} }
function pip_pkg_install {
PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring $PYTHON -m pip install --upgrade "$@"
}
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
K="$1" K="$1"
case $K in case $K in
@@ -100,6 +147,15 @@ while [[ $# -gt 0 ]]; do
UNSTABLE=true UNSTABLE=true
shift shift
;; ;;
-f|--force)
FORCE=true
shift
;;
-p|--python)
PYTHON=$2
shift
shift
;;
*) *)
if [[ $1 == -* ]]; then if [[ $1 == -* ]]; then
printf "Unrecognised option: $1\n"; printf "Unrecognised option: $1\n";
@@ -112,31 +168,33 @@ while [[ $# -gt 0 ]]; do
done done
user_check user_check
venv_check
apt_pkg_install python-configparser if [ ! -f `which $PYTHON` ]; then
printf "Python path $PYTHON not found!\n"
exit 1
fi
CONFIG_VARS=`python - <<EOF PYTHON_VER=`$PYTHON --version`
from configparser import ConfigParser
c = ConfigParser() printf "$LIBRARY_NAME Python Library: Installer\n\n"
c.read('library/setup.cfg')
p = dict(c['pimoroni']) inform "Checking Dependencies. Please wait..."
# Convert multi-line config entries into bash arrays
for k in p.keys(): pip_pkg_install toml
fmt = '"{}"'
if '\n' in p[k]: CONFIG_VARS=`$PYTHON - <<EOF
p[k] = "'\n\t'".join(p[k].split('\n')[1:]) import toml
fmt = "('{}')" config = toml.load("pyproject.toml")
p[k] = fmt.format(p[k]) p = dict(config['tool']['pimoroni'])
# Convert list config entries into bash arrays
for k, v in p.items():
v = "'\n\t'".join(v)
p[k] = f"('{v}')"
print(""" print("""
LIBRARY_NAME="{name}" APT_PACKAGES={apt_packages}
LIBRARY_VERSION="{version}"
""".format(**c['metadata']))
print("""
PY3_DEPS={py3deps}
PY2_DEPS={py2deps}
SETUP_CMDS={commands} SETUP_CMDS={commands}
CONFIG_TXT={configtxt} CONFIG_TXT={configtxt}
PY3_ONLY={py3only}
""".format(**p)) """.format(**p))
EOF` EOF`
@@ -150,6 +208,13 @@ eval $CONFIG_VARS
RESOURCES_DIR=$RESOURCES_TOP_DIR/$LIBRARY_NAME RESOURCES_DIR=$RESOURCES_TOP_DIR/$LIBRARY_NAME
UNINSTALLER=$RESOURCES_DIR/uninstall.sh UNINSTALLER=$RESOURCES_DIR/uninstall.sh
RES_DIR_OWNER=`stat -c "%U" $RESOURCES_TOP_DIR`
if [[ "$RES_DIR_OWNER" == "root" ]]; then
warning "\n\nFixing $RESOURCES_TOP_DIR permissions!\n\n"
sudo chown -R $USER:$USER $RESOURCES_TOP_DIR
fi
mkdir -p $RESOURCES_DIR mkdir -p $RESOURCES_DIR
cat << EOF > $UNINSTALLER cat << EOF > $UNINSTALLER
@@ -157,49 +222,25 @@ printf "It's recommended you run these steps manually.\n"
printf "If you want to run the full script, open it in\n" printf "If you want to run the full script, open it in\n"
printf "an editor and remove 'exit 1' from below.\n" printf "an editor and remove 'exit 1' from below.\n"
exit 1 exit 1
source $VIRTUAL_ENV/bin/activate
EOF EOF
printf "$LIBRARY_NAME $LIBRARY_VERSION Python Library: Installer\n\n"
if $UNSTABLE; then if $UNSTABLE; then
warning "Installing unstable library from source.\n\n" warning "Installing unstable library from source.\n\n"
else else
printf "Installing stable library from pypi.\n\n" printf "Installing stable library from pypi.\n\n"
fi fi
cd library inform "Installing for $PYTHON_VER...\n"
apt_pkg_install "${APT_PACKAGES[@]}"
if ! $PY3_ONLY; then if $UNSTABLE; then
printf "Installing for Python 2..\n" pip_pkg_install .
apt_pkg_install "${PY2_DEPS[@]}"
if $UNSTABLE; then
python setup.py install > /dev/null
else
pip install --upgrade $LIBRARY_NAME
fi
if [ $? -eq 0 ]; then
success "Done!\n"
echo "pip uninstall $LIBRARY_NAME" >> $UNINSTALLER
fi
fi
if [ -f "$PYTHON3" ]; then
printf "Installing for Python 3..\n"
apt_pkg_install "${PY3_DEPS[@]}"
if $UNSTABLE; then
python3 setup.py install > /dev/null
else
pip3 install --upgrade $LIBRARY_NAME
fi
if [ $? -eq 0 ]; then
success "Done!\n"
echo "pip3 uninstall $LIBRARY_NAME" >> $UNINSTALLER
fi
else else
if $PY3_ONLY; then pip_pkg_install $LIBRARY_NAME
warning "Python 3 is required to install this library...\n" fi
exit 1 if [ $? -eq 0 ]; then
fi success "Done!\n"
echo "$PYTHON -m pip uninstall $LIBRARY_NAME" >> $UNINSTALLER
fi fi
cd $WD cd $WD
@@ -218,9 +259,9 @@ for ((i = 0; i < ${#CONFIG_TXT[@]}; i++)); do
if ! [ "$CONFIG_LINE" == "" ]; then if ! [ "$CONFIG_LINE" == "" ]; then
do_config_backup do_config_backup
inform "Adding $CONFIG_LINE to $CONFIG\n" inform "Adding $CONFIG_LINE to $CONFIG\n"
sed -i "s/^#$CONFIG_LINE/$CONFIG_LINE/" $CONFIG sudo sed -i "s/^#$CONFIG_LINE/$CONFIG_LINE/" $CONFIG
if ! grep -q "^$CONFIG_LINE" $CONFIG; then if ! grep -q "^$CONFIG_LINE" $CONFIG; then
printf "$CONFIG_LINE\n" >> $CONFIG printf "$CONFIG_LINE\n" | sudo tee --append $CONFIG
fi fi
fi fi
done done
@@ -236,13 +277,12 @@ fi
printf "\n" printf "\n"
if [ -f "/usr/bin/pydoc" ]; then if confirm "Would you like to generate documentation?"; then
pip_pkg_install pdoc
printf "Generating documentation.\n" printf "Generating documentation.\n"
pydoc -w $LIBRARY_NAME > /dev/null $PYTHON -m pdoc $LIBRARY_NAME -o $RESOURCES_DIR/docs > /dev/null
if [ -f "$LIBRARY_NAME.html" ]; then if [ $? -eq 0 ]; then
cp $LIBRARY_NAME.html $RESOURCES_DIR/docs.html inform "Documentation saved to $RESOURCES_DIR/docs"
rm -f $LIBRARY_NAME.html
inform "Documentation saved to $RESOURCES_DIR/docs.html"
success "Done!" success "Done!"
else else
warning "Error: Failed to generate documentation." warning "Error: Failed to generate documentation."

View File

@@ -1,4 +0,0 @@
[run]
source = ST7735
omit =
.tox/*

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2018 Pimoroni Ltd.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,5 +0,0 @@
include CHANGELOG.txt
include LICENSE.txt
include README.md
include setup.py
recursive-include ST7735 *.py

View File

@@ -1,100 +0,0 @@
# Python ST7735
[![Build Status](https://travis-ci.com/pimoroni/st7735-python.svg?branch=master)](https://travis-ci.com/pimoroni/st7735-python)
[![Coverage Status](https://coveralls.io/repos/github/pimoroni/st7735-python/badge.svg?branch=master)](https://coveralls.io/github/pimoroni/st7735-python?branch=master)
[![PyPi Package](https://img.shields.io/pypi/v/st7735.svg)](https://pypi.python.org/pypi/st7735)
[![Python Versions](https://img.shields.io/pypi/pyversions/st7735.svg)](https://pypi.python.org/pypi/st7735)
Python library to control an ST7735 TFT LCD display. Allows simple drawing on the display without installing a kernel module.
Designed specifically to work with a ST7735 based 160x80 pixel TFT SPI display. (Specifically the 0.96" SPI LCD from Pimoroni).
## Installing
### Python 2
Make sure you have the following dependencies:
````
sudo apt update
sudo apt install python-rpi.gpio python-spidev python-pip python-pil python-numpy
````
Install this library by running:
````
sudo pip install st7735
````
### Python 3
Make sure you have the following dependencies:
````
sudo apt update
sudo apt install python3-rpi.gpio python3-spidev python3-pip python3-pil python3-numpy
````
Install this library by running:
````
sudo python3 -m pip install st7735
````
See example of usage in the examples folder.
# Licensing & History
This library is a modification of a modification of code originally written by Tony DiCola for Adafruit Industries, and modified to work with the ST7735 by Clement Skau.
It has been modified by Pimoroni to include support for their 160x80 SPI LCD breakout, and hopefully also generalised enough so that it will support other ST7735-powered displays.
## Modifications include:
* PIL/Pillow has been removed from the underlying display driver to separate concerns- you should create your own PIL image and display it using `display(image)`
* `width`, `height`, `rotation`, `invert`, `offset_left` and `offset_top` parameters can be passed into `__init__` for alternate displays
* `Adafruit_GPIO` has been replaced with `RPi.GPIO` and `spidev` to closely align with our other software (IE: Raspberry Pi only)
* Test fixtures have been added to keep this library stable
Pimoroni invests time and resources forking and modifying this open source code, please support Pimoroni and open-source software by purchasing products from us, too!
Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
Modified from 'Modified from 'Adafruit Python ILI9341' written by Tony DiCola for Adafruit Industries.' written by Clement Skau.
MIT license, all text above must be included in any redistribution
# Changelog
0.0.4-post1
-----------
* Repackage with Markdown README/setup.cfg
* Fix `__version__` to 0.0.4
* Update dependencies in README
0.0.4
-----
* Depend upon spidev==3.4.0 for stability fixes
* Switch from manual data chunking to spidev.xfer3()
0.0.3
-----
* Fixed backlight pin
* Added `set_backlight`
* Added constants BG_SPI_CS_FRONT and BG_SPI_CS_BACK
* Added module `__version__`
0.0.2
-----
* Support for multiple display sizes/orientations
0.0.1
-----
* Initial Release

View File

@@ -1,24 +0,0 @@
[tox]
envlist = py,qa
skip_missing_interpreters = True
[testenv]
commands =
python setup.py install
coverage run -m pytest -v -r wsx
coverage report
deps =
mock
pytest>=3.1
pytest-cov
[testenv:qa]
commands =
check-manifest --ignore tox.ini,tests/*,.coveragerc
python setup.py sdist bdist_wheel
twine check dist/*
flake8 --ignore E501
deps =
check-manifest
flake8
twine

120
pyproject.toml Normal file
View File

@@ -0,0 +1,120 @@
[build-system]
requires = ["hatchling", "hatch-fancy-pypi-readme"]
build-backend = "hatchling.build"
[project]
name = "st7735"
dynamic = ["version", "readme"]
description = "Library to control an ST7735 168x80 TFT LCD display."
license = {file = "LICENSE"}
requires-python = ">= 3.7"
authors = [
{ name = "Philip Howard", email = "phil@pimoroni.com" },
]
maintainers = [
{ name = "Philip Howard", email = "phil@pimoroni.com" },
]
keywords = [
"Pi",
"Raspberry",
"displays"
]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3 :: Only",
"Topic :: Software Development",
"Topic :: Software Development :: Libraries",
"Topic :: System :: Hardware",
]
dependencies = [
"spidev"
]
[project.urls]
GitHub = "https://www.github.com/pimoroni/st7735-python"
Homepage = "https://www.pimoroni.com"
[tool.hatch.version]
path = "st7735/__init__.py"
[tool.hatch.build]
include = [
"st7735",
"ST7735.py",
"README.md",
"CHANGELOG.md",
"LICENSE"
]
[tool.hatch.build.targets.sdist]
include = [
"*"
]
exclude = [
".*",
"dist"
]
[tool.hatch.metadata.hooks.fancy-pypi-readme]
content-type = "text/markdown"
fragments = [
{ path = "README.md" },
{ text = "\n" },
{ path = "CHANGELOG.md" }
]
[tool.ruff]
exclude = [
'.tox',
'.egg',
'.git',
'__pycache__',
'build',
'dist'
]
line-length = 200
[tool.codespell]
skip = """
./.tox,\
./.egg,\
./.git,\
./__pycache__,\
./build,\
./dist.\
"""
[tool.isort]
line_length = 200
[tool.check-manifest]
ignore = [
'.stickler.yml',
'boilerplate.md',
'check.sh',
'install.sh',
'uninstall.sh',
'Makefile',
'tox.ini',
'tests/*',
'examples/*',
'.coveragerc',
'requirements-dev.txt'
]
[tool.pimoroni]
apt_packages = []
configtxt = []
commands = [
"printf \"Setting up SPI...\n\"",
"sudo raspi-config nonint do_spi 0"
]

9
requirements-dev.txt Normal file
View File

@@ -0,0 +1,9 @@
check-manifest
ruff
codespell
isort
twine
hatch
hatch-fancy-pypi-readme
tox
pdoc

3
requirements.txt Normal file
View File

@@ -0,0 +1,3 @@
pillow
numpy
spidev

View File

@@ -26,7 +26,7 @@ import spidev
import RPi.GPIO as GPIO import RPi.GPIO as GPIO
__version__ = '0.0.5' __version__ = "0.0.5"
BG_SPI_CS_BACK = 0 BG_SPI_CS_BACK = 0
BG_SPI_CS_FRONT = 1 BG_SPI_CS_FRONT = 1

34
tox.ini Normal file
View File

@@ -0,0 +1,34 @@
[tox]
envlist = py,qa
skip_missing_interpreters = True
isolated_build = true
minversion = 4.0.0
[testenv]
commands =
coverage run -m pytest -v -r wsx
coverage report
deps =
mock
pytest>=3.1
pytest-cov
build
[testenv:qa]
commands =
check-manifest
python -m build --no-isolation
python -m twine check dist/*
isort --check .
ruff .
codespell .
deps =
check-manifest
ruff
codespell
isort
twine
build
hatch
hatch-fancy-pypi-readme

72
uninstall.sh Executable file
View File

@@ -0,0 +1,72 @@
#!/bin/bash
FORCE=false
LIBRARY_NAME=`grep -m 1 name pyproject.toml | awk -F" = " '{print substr($2,2,length($2)-2)}'`
RESOURCES_DIR=$HOME/Pimoroni/$LIBRARY_NAME
PYTHON="python"
venv_check() {
PYTHON_BIN=`which $PYTHON`
if [[ $VIRTUAL_ENV == "" ]] || [[ $PYTHON_BIN != $VIRTUAL_ENV* ]]; then
printf "This script should be run in a virtual Python environment.\n"
exit 1
fi
}
user_check() {
if [ $(id -u) -eq 0 ]; then
printf "Script should not be run as root. Try './uninstall.sh'\n"
exit 1
fi
}
confirm() {
if $FORCE; then
true
else
read -r -p "$1 [y/N] " response < /dev/tty
if [[ $response =~ ^(yes|y|Y)$ ]]; then
true
else
false
fi
fi
}
prompt() {
read -r -p "$1 [y/N] " response < /dev/tty
if [[ $response =~ ^(yes|y|Y)$ ]]; then
true
else
false
fi
}
success() {
echo -e "$(tput setaf 2)$1$(tput sgr0)"
}
inform() {
echo -e "$(tput setaf 6)$1$(tput sgr0)"
}
warning() {
echo -e "$(tput setaf 1)$1$(tput sgr0)"
}
printf "$LIBRARY_NAME Python Library: Uninstaller\n\n"
user_check
venv_check
printf "Uninstalling for Python 3...\n"
$PYTHON -m pip uninstall $LIBRARY_NAME
if [ -d $RESOURCES_DIR ]; then
if confirm "Would you like to delete $RESOURCES_DIR?"; then
rm -r $RESOURCES_DIR
fi
fi
printf "Done!\n"