Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Git and version control
.git
.gitignore

# Virtual environments
.venv

# Python cache and bytecode
__pycache__
*.py[cod]
*$py.class
*.so
*.egg-info
*.egg

# Testing
tests
.pytest_cache
.coverage
.coverage.*
htmlcov
.tox
.nox
.hypothesis

# Development tools and docs
Makefile
.pre-commit-config.yaml
CHANGELOG.md
README.md

# IDE and editor files
.vscode
.idea
*.swp
*.swo
*~

# OS files
.DS_Store
Thumbs.db

# Build artifacts
build
dist
*.whl
*.tar.gz

# Linting and type checking caches
.ruff_cache
.mypy_cache
.dmypy.json

# Misc
*.bak
.cache

# Docker files
Dockerfile
.dockerignore
2 changes: 1 addition & 1 deletion .github/workflows/actions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:

unit-tests:
name: Run unit tests
uses: EO-DataHub/github-actions/.github/workflows/unit-tests-python.yaml@main
uses: EO-DataHub/github-actions/.github/workflows/unit-tests-python-uv.yaml@main

get-tag-name:
runs-on: ubuntu-latest
Expand Down
27 changes: 14 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
# syntax=docker/dockerfile:1
FROM python:3.11-slim-bullseye
FROM ghcr.io/astral-sh/uv:python3.13-trixie-slim

RUN rm -f /etc/apt/apt.conf.d/docker-clean; \
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache

RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update -y && apt-get upgrade -y
ENV UV_NO_DEV=1

WORKDIR /app
ADD LICENSE requirements.txt ./
ADD pyproject.toml ./
RUN --mount=type=cache,target=/root/.cache/pip pip3 install -r requirements.txt .

ADD static ./static/
ADD resource_catalogue_fastapi ./resource_catalogue_fastapi/
# Install dependencies
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --frozen --no-install-project

COPY . /app

# Sync the project
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen

CMD ["uvicorn", "resource_catalogue_fastapi:app", "--host", "0.0.0.0", "--port", "8000"]
CMD ["uv", "run", "--no-sync", "uvicorn", "resource_catalogue_fastapi:app", "--host", "0.0.0.0", "--port", "8000"]
39 changes: 11 additions & 28 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
VERSION ?= latest
IMAGENAME = resource-catalogue-fastapi
DOCKERREPO ?= public.ecr.aws/eodh
uv-run ?= uv run --no-sync

dockerbuild:
DOCKER_BUILDKIT=1 docker build -t ${IMAGENAME}:${VERSION} .
Expand All @@ -11,48 +12,30 @@ dockerpush: dockerbuild
docker push ${DOCKERREPO}/${IMAGENAME}:${VERSION}

test:
./venv/bin/ptw resource_catalogue_fastapi
${uv-run} ptw resource_catalogue_fastapi

testonce:
./venv/bin/pytest
${uv-run} pytest

ruff:
./venv/bin/ruff check .
${uv-run} ruff check .

black:
./venv/bin/black .
${uv-run} black .

isort:
./venv/bin/isort . --profile black
${uv-run} isort . --profile black

validate-pyproject:
validate-pyproject pyproject.toml
${uv-run} validate-pyproject pyproject.toml

lint: ruff black isort validate-pyproject

requirements.txt: venv pyproject.toml
./venv/bin/pip-compile

requirements-dev.txt: venv pyproject.toml
./venv/bin/pip-compile --extra dev -o requirements-dev.txt

requirements: requirements.txt requirements-dev.txt

requirements-update: venv
./venv/bin/pip-compile -U
./venv/bin/pip-compile --extra dev -o requirements-dev.txt -U

venv:
virtualenv -p python3.11 venv
./venv/bin/python -m ensurepip -U
./venv/bin/pip3 install pip-tools

.make-venv-installed: venv requirements.txt requirements-dev.txt
./venv/bin/pip3 install -r requirements.txt -r requirements-dev.txt
touch .make-venv-installed
uv-sync:
${uv-run} sync --frozen

.git/hooks/pre-commit:
./venv/bin/pre-commit install
${uv-run} pre-commit install
curl -o .pre-commit-config.yaml https://raw.githubusercontent.com/EO-DataHub/github-actions/main/.pre-commit-config-python.yaml

setup: venv requirements .make-venv-installed .git/hooks/pre-commit
setup: uv-sync .git/hooks/pre-commit
47 changes: 6 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,47 +25,25 @@ PULSAR_URL
```
## Getting started

### Prerequisites

Install the `uv` package manager by following the [official documentation](https://docs.astral.sh/uv/getting-started/installation/).

### Install via makefile

```commandline
make setup
```

This will create a virtual environment called `venv`, build `requirements.txt` and
`requirements-dev.txt` from `pyproject.toml` if they're out of date, install the Python
This will create a Python virtual environment, install the Python
and Node dependencies and install `pre-commit`.

It's safe and fast to run `make setup` repeatedly as it will only update these things if
they have changed.
It's safe and fast to run `make setup` repeatedly.

After `make setup` you can run `pre-commit` to run pre-commit checks on staged changes and
`pre-commit run --all-files` to run them on all files. This replicates the linter checks that
run from GitHub actions.


### Alternative installation

You will need Python 3.11. On Debian you may need:
* `sudo add-apt-repository -y 'deb http://ppa.launchpad.net/deadsnakes/ppa/ubuntu focal main'` (or `jammy` in place of `focal` for later Debian)
* `sudo apt update`
* `sudo apt install python3.11 python3.11-venv`

and on Ubuntu you may need
* `sudo add-apt-repository -y 'ppa:deadsnakes/ppa'`
* `sudo apt update`
* `sudo apt install python3.11 python3.11-venv`

To prepare running it:

* `virtualenv venv -p python3.11`
* `. venv/bin/activate`
* `rehash`
* `python -m ensurepip -U`
* `pip3 install -r requirements.txt`
* `pip3 install -r requirements-dev.txt`

You should also configure your IDE to use black so that code is automatically reformatted on save.

## Building and testing

This component uses `pytest` tests and the `ruff` and `black` linters. `black` will reformat your code in an opinionated way.
Expand All @@ -80,19 +58,6 @@ A number of `make` targets are defined:
* `make dockerpush`: push a `latest` Docker image (again, you can add `VERSION=1.2.3`) - normally this should be done
only via the build system and its GitHub actions.

## Managing requirements

Requirements are specified in `pyproject.toml`, with development requirements listed separately. Specify version
constraints as necessary but not specific versions. After changing them:

* Run `pip-compile` (or `pip-compile -U` to upgrade requirements within constraints) to regenerate `requirements.txt`
* Run `pip-compile --extra dev -o requirements-dev.txt` (again, add `-U` to upgrade) to regenerate
`requirements-dev.txt`.
* Run the `pip3 install -r requirements.txt` and `pip3 install -r requirements-dev.txt` commands again and test.
* Commit these files.

If you see the error

```commandline
Backend subprocess exited when trying to invoke get_requires_for_build_wheel
Failed to parse /.../template-python/pyproject.toml
Expand Down
31 changes: 19 additions & 12 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ dynamic = ["version"]
description = "A FastApi deployment to handle requests to update the resource catalogue"
readme = "README.md"

# Our target version is Python 3.11, but it may work with earlier versions.
requires-python = ">=3.11"
# Our target version is Python 3.13.
requires-python = ">=3.13,<3.14"

license = {file = "LICENSE"}

Expand Down Expand Up @@ -86,16 +86,23 @@ dependencies = [
"kubernetes",
]

# List additional groups of dependencies here (e.g. development
# dependencies). Users will be able to install these using the "extras"
# syntax, for example:
#
# $ pip install sampleproject[dev]
#
# Similar to `dependencies` above, these must be valid existing
# projects.
[project.optional-dependencies] # Optional
dev = ["pip-tools", "pytest", "pytest-xdist", "pytest-mock", "pytest-watcher", "black", "ruff", "isort", "pre-commit", "httpx", "requests-mock"]
[dependency-groups] # Optional
dev = [
"pytest",
"pytest-xdist",
"pytest-mock",
"pytest-watcher",
"black",
"ruff",
"isort",
"pre-commit",
"httpx",
"requests-mock",
"validate-pyproject>=0.24.1",
]

[tool.uv]
constraint-dependencies = ["urllib3>=2.6.0"]

# List URLs that are relevant to your project
#
Expand Down
Loading