Skip to content

Commit bc7dc94

Browse files
MayNiklasnonchris
andauthored
Add API unit tests & bump dependencies / packaging (#36)
* flake.lock: Update * bump requirements.txt * fix woodpecker pipeline * build docker image on PR * fix direnv logic * update Docker image * modernize nix setup * fix nix check * add API unit tests * pin nixpkgs * compose: use CDI for nvidia by default * update nixpkgs * test/test_api.py: more accurate docstring Co-authored-by: Chris G <git@chris-ge.de> --------- Co-authored-by: Chris G <git@chris-ge.de>
1 parent 8ef2789 commit bc7dc94

13 files changed

Lines changed: 290 additions & 48 deletions

File tree

.envrc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export using_direnv=true
33

44
# Check if the NVIDIA kernel module is loaded
55
if [ "$(lsmod | grep nvidia | wc -l)" -ne 0 ]; then
6-
use flake #withCUDA
6+
use flake .#withCUDA
77
else
8-
use flake #withoutCUDA
8+
use flake .#withoutCUDA
99
fi

.github/workflows/image.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name: Create and publish a Docker image
22

33
on:
4+
pull_request:
45
push:
56
branches:
67
- 'main'
@@ -31,6 +32,7 @@ jobs:
3132

3233
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
3334
- name: Log in to the Container registry
35+
if: github.event_name != 'pull_request'
3436
uses: docker/login-action@v3
3537
with:
3638
registry: ${{ env.REGISTRY }}
@@ -52,14 +54,15 @@ jobs:
5254
uses: docker/build-push-action@v6
5355
with:
5456
context: .
55-
push: true
57+
push: ${{ github.event_name != 'pull_request' }}
5658
tags: ${{ steps.meta.outputs.tags }}
5759
labels: ${{ steps.meta.outputs.labels }}
5860
cache-from: type=gha
5961
cache-to: type=gha,mode=max
6062

6163
# This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see "[AUTOTITLE](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds)."
6264
- name: Generate artifact attestation
65+
if: github.event_name != 'pull_request'
6366
uses: actions/attest-build-provenance@v1
6467
with:
6568
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}

.woodpecker/build-amd64.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ steps:
77
image: bash
88
commands:
99
- attic login lounge-rocks https://cache.lounge.rocks $ATTIC_KEY --set-default
10-
secrets: [attic_key]
10+
environment:
11+
ATTIC_KEY:
12+
from_secret: attic_key
1113

1214
- name: build whisper_api
1315
image: bash

Dockerfile

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,22 @@
11
# newest version:
22
# https://hub.docker.com/r/nvidia/cuda/tags?page=1&name=-base-ubuntu22.04&ordering=name
33

4-
ARG CUDA_VERSION=12.4.1
5-
FROM nvidia/cuda:${CUDA_VERSION}-base-ubuntu22.04
6-
7-
ARG PYTHON_VERSION=3.10
4+
ARG CUDA_VERSION=12.6.2
5+
FROM nvidia/cuda:${CUDA_VERSION}-base-ubuntu24.04
86

97
WORKDIR /workspace
108

119
RUN export DEBIAN_FRONTEND=noninteractive && \
1210
apt-get -qq update && \
1311
apt-get -qq install --no-install-recommends \
1412
ffmpeg \
15-
python${PYTHON_VERSION} \
16-
python${PYTHON_VERSION}-venv \
13+
python3 \
14+
python3-venv \
1715
python3-pip && \
18-
rm -rf /var/lib/apt/lists/* && \
19-
pip3 install --upgrade pip setuptools
16+
rm -rf /var/lib/apt/lists/*
2017

2118
COPY requirements.txt requirements.txt
22-
RUN pip3 install --no-build-isolation -r requirements.txt
19+
RUN pip3 install -r requirements.txt --break-system-packages
2320

2421
# disabled by default since GitHub Actions do not have enough space
2522
ARG PREFETCH_MODEL=0
@@ -32,7 +29,7 @@ RUN if [ "$PREFETCH_MODEL" != 0 ]; then \
3229
COPY . /workspace/code
3330

3431
RUN cd /workspace/code && \
35-
pip3 install .
32+
pip3 install . --break-system-packages
3633

3734
ENV PORT=3001 \
3835
LISTEN=0.0.0.0 \

docker-compose.yml

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,22 @@ services:
1212
- LOAD_MODEL_ON_STARTUP=1
1313
# - UNLOAD_MODEL_AFTER_S=300
1414
# - DEVELOP_MODE=0
15-
# include the following lines when using a NVIDIA GPU!
16-
# make sure to have the NVIDIA Container Toolkit installed
17-
# for more information visit:
18-
# https://github.com/NVIDIA/nvidia-container-toolkit
19-
deploy:
20-
resources:
21-
reservations:
22-
devices:
23-
- driver: nvidia
24-
capabilities: [gpu]
15+
# NVIDIA GPU access — enable exactly one of the two blocks below.
16+
#
17+
# Option A (preferred): CDI (Container Device Interface). Vendor-neutral
18+
# standard where the NVIDIA Container Toolkit installs a spec at
19+
# /etc/cdi/nvidia.yaml and the device is addressed by name. Requires
20+
# Docker >=25 and Compose >=v2.30. This is what modern setups use.
21+
devices:
22+
- nvidia.com/gpu=all
23+
#
24+
# Option B (legacy): the old `nvidia` OCI runtime registered in
25+
# /etc/docker/daemon.json by older versions of the NVIDIA Container
26+
# Toolkit. Being phased out, but still works on hosts that have the
27+
# runtime registered and no CDI spec installed.
28+
# deploy:
29+
# resources:
30+
# reservations:
31+
# devices:
32+
# - driver: nvidia
33+
# capabilities: [gpu]

flake.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
description = "A simple API for OpenAI's Whisper";
44

5-
inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; };
5+
inputs = {
6+
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
7+
};
68

79
outputs = { self, nixpkgs, ... }:
810
let
@@ -33,8 +35,8 @@
3335
(system: nixpkgsFor.${system}.nixpkgs-fmt);
3436

3537
overlays.default = final: prev: {
36-
devShell = final.callPackage nixos/devShell { inherit self; };
37-
whisper_api = final.callPackage nixos/pkgs/whisper_api { inherit self; };
38+
devShell = final.python3Packages.callPackage nixos/devShell { };
39+
whisper_api = final.python3Packages.callPackage nixos/pkgs/whisper_api { inherit self; };
3840
# Our code is not compatible with pydantic version 2 yet.
3941
python3 = prev.python3.override {
4042
packageOverrides = python-self: python-super: {

nixos/checks/default.nix

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ in {
8282
server.succeed("chown -R whisper_api:whisper_api /var/lib/whisper_api/.cache/whisper")
8383
8484
# wait until the server is up
85-
server.wait_for_unit("network-online.target")
8685
server.wait_for_unit("whisper_api")
8786
8887
# check if server can reach API

nixos/devShell/default.nix

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
{ self, pkgs, ... }:
1+
{ pkgs, ... }:
22
let
3+
whisper_api = pkgs.whisper_api;
34
python-with-packages = pkgs.python3.withPackages (p: with p; [
45
# only needed for development
56
autopep8
67
black
78
httpx
89
isort
9-
pylint
1010
pip
11-
] ++ self.packages.${pkgs.system}.whisper_api.propagatedBuildInputs);
11+
pylint
12+
pytest
13+
] ++ whisper_api.propagatedBuildInputs);
1214
in
1315
pkgs.mkShell {
16+
inputsFrom = [ whisper_api ];
1417
buildInputs = with pkgs; [
1518
# only needed for development
1619
nixpkgs-fmt

nixos/pkgs/whisper_api/default.nix

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
1-
{ self
2-
, lib
3-
, python3
4-
,
1+
{
2+
self,
3+
lib,
4+
buildPythonApplication,
5+
6+
# build-system
7+
setuptools,
8+
pythonRelaxDepsHook,
9+
10+
# dependencies
11+
fastapi,
12+
ffmpeg-python,
13+
openai-whisper,
14+
python-multipart,
15+
uvicorn,
16+
17+
# tests
18+
pytestCheckHook,
19+
httpx,
520
}:
6-
python3.pkgs.buildPythonApplication {
21+
buildPythonApplication {
722

823
pname = "whisper_api";
924

@@ -18,24 +33,28 @@ python3.pkgs.buildPythonApplication {
1833

1934
pythonRelaxDeps = [ ];
2035

21-
nativeBuildInputs = with python3.pkgs; [
36+
nativeBuildInputs = [
2237
setuptools
2338
pythonRelaxDepsHook
2439
];
2540

26-
propagatedBuildInputs = with python3.pkgs; [
41+
propagatedBuildInputs = [
2742
fastapi
2843
ffmpeg-python
2944
openai-whisper
3045
python-multipart
3146
uvicorn
3247
];
3348

34-
nativeCheckInputs = with python3.pkgs; [
35-
unittestCheckHook
49+
nativeCheckInputs = [
50+
pytestCheckHook
3651
httpx
3752
];
3853

54+
disabledTestPaths = [
55+
"test/test_api.py"
56+
];
57+
3958
pythonImportsCheck = [ "whisper_api" ];
4059

4160
meta = with lib; {

0 commit comments

Comments
 (0)