From d9e86bdc6d08cf36224c681ba843704d21818419 Mon Sep 17 00:00:00 2001 From: Imron Reviady Date: Sat, 3 Oct 2026 13:30:33 +0700 Subject: [PATCH] CI: run the test suite and checks on every pull request Adds .github/workflows/ci.yml running the test suite and the type checker or analyzer on every pull request and push to main. Also fixes the five existing mypy errors (the FacesResource.list method shadowed the builtin list in later annotations), so the type check can block. --- .github/workflows/ci.yml | 24 ++++++++++++++++++++++++ livexface/client.py | 11 ++++++----- 2 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..0129b56 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,24 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +jobs: + test: + name: Test (Python ${{ matrix.python }}) + runs-on: ubuntu-latest + strategy: + matrix: + python: ["3.10", "3.12"] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + - run: pip install -e ".[dev]" + - name: Type-check + run: mypy livexface + - name: Test + run: pytest -q tests diff --git a/livexface/client.py b/livexface/client.py index 0ec09bc..2677878 100644 --- a/livexface/client.py +++ b/livexface/client.py @@ -2,6 +2,7 @@ from __future__ import annotations +import builtins import json from pathlib import Path from typing import Any, IO, Sequence, Union @@ -291,7 +292,7 @@ def compare( def batch_register( self, collection_id: str, - items: list[dict[str, Any]], + items: builtins.list[dict[str, Any]], ) -> BatchResponse: """ Batch register up to 20 faces in a single request. @@ -308,7 +309,7 @@ def batch_register( ]) """ files: dict[str, Any] = {} - entries = [] + entries: builtins.list[dict[str, Any]] = [] for i, item in enumerate(items): fname, fbytes, ftype = _to_bytes_tuple(item["image"]) files[f"images[{i}]"] = (fname, fbytes, ftype) @@ -327,7 +328,7 @@ def batch_register( ) return BatchResponse.from_dict(resp) - def batch_delete(self, collection_id: str, face_ids: list[str]) -> BatchDeleteResponse: + def batch_delete(self, collection_id: str, face_ids: builtins.list[str]) -> BatchDeleteResponse: """Batch delete up to 100 faces by their IDs.""" resp = self._c._request( "DELETE", @@ -349,7 +350,7 @@ def attributes(self, collection_id: str, image: ImageInput) -> AttributesResult: def batch_register_async( self, collection_id: str, - items: list[dict[str, Any]], + items: builtins.list[dict[str, Any]], ) -> BatchJob: """ Submit up to 100 faces for asynchronous registration. Returns a job @@ -361,7 +362,7 @@ def batch_register_async( :meth:`active_liveness`) are also supported. """ files: dict[str, Any] = {} - entries = [] + entries: builtins.list[dict[str, Any]] = [] for i, item in enumerate(items): fname, fbytes, ftype = _to_bytes_tuple(item["image"]) files[f"images[{i}]"] = (fname, fbytes, ftype)