Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix tests fixup #158

Merged
merged 16 commits into from
Aug 2, 2024
20 changes: 9 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
- published

env:
MINIMUM_PYTHON_VERSION: '3.8'
MINIMUM_PYTHON_VERSION: '3.9'

concurrency:
group: ${{ github.head_ref || github.run_id }}
Expand All @@ -19,10 +19,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Install Python ${{ env.MINIMUM_PYTHON_VERSION }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ env.MINIMUM_PYTHON_VERSION }}
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Install pre-commit
run: |
python -m pip install --upgrade pip
Expand All @@ -40,19 +40,19 @@ jobs:
strategy:
fail-fast: false # Try to work around ECS errors
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install tox-gh-actions poetry
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
Expand All @@ -66,8 +66,6 @@ jobs:
retry -t 5 -- docker pull public.ecr.aws/diag-nijmegen/grand-challenge/http:latest
- name: Add gc.localhost to /etc/hosts
run: sudo echo "127.0.0.1 gc.localhost\n127.0.0.1 minio.localhost" | sudo tee -a /etc/hosts
- name: Find the docker compose version (should be at least 2.1.1 for --wait, everything works locally with 2.5.1, 2.4.1+azure-1 does not work)
run: docker compose version
- name: Run tox
run: tox

Expand All @@ -77,10 +75,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Install Python ${{ env.MINIMUM_PYTHON_VERSION }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ env.MINIMUM_PYTHON_VERSION }}
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
14 changes: 7 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.6.0
hooks:
- id: check-docstring-first
- id: debug-statements
- id: end-of-file-fixer
- id: mixed-line-ending
- id: trailing-whitespace
- repo: https://github.com/asottile/pyupgrade
rev: v3.3.1
rev: v3.17.0
hooks:
- id: pyupgrade
language: python
args: [--py38-plus, --keep-runtime-typing]
args: [--py39-plus, --keep-runtime-typing]
- repo: https://github.com/pycqa/isort
rev: 5.12.0
rev: 5.13.2
hooks:
- id: isort
- repo: https://github.com/ambv/black
rev: 23.1.0
rev: 24.4.2
hooks:
- id: black
language: python
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
rev: 7.1.0
hooks:
- id: flake8
language: python
Expand All @@ -35,7 +35,7 @@ repos:
- mccabe
- yesqa
- repo: https://github.com/pre-commit/mirrors-mypy
rev: 'v1.0.0'
rev: 'v1.11.1'
hooks:
- id: mypy
additional_dependencies:
Expand Down
5 changes: 3 additions & 2 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

## 0.12.0 (UNRELEASED)

- Removed support for Python 3.6 and 3.7
- Added support for Python 3.11
- Removed support for Python 3.6, 3.7 and 3.8
- Added support for Python 3.11 and 3.12
- Removed the retina endpoints
- Migrated to use Pydantic models for request and response validation

## 0.11.0 (2022-12-14)

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ Challenge](https://grand-challenge.org/documentation/grand-challenge-api/).
This client is tested using the `tox` framework. This enables testing
the client in various python-version environments.

For example, running a specific `your_test` for only the python 3.8
For example, running a specific `your_test` for only the python 3.9
environment can be done as follows:
```bash
tox -e py38 -- -k your_test
tox -e py39 -- -k your_test
```
39 changes: 12 additions & 27 deletions gcapi/apibase.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
import collections
from typing import (
Any,
Dict,
Generator,
Generic,
Iterator,
List,
Sequence,
Type,
TypeVar,
overload,
)
from collections.abc import Generator, Iterator, Sequence
from typing import Any, Generic, TypeVar, overload
from urllib.parse import urljoin

from httpx import URL, HTTPStatusError
Expand All @@ -28,15 +18,12 @@

class ClientInterface:
@property
def base_url(self) -> URL:
...
def base_url(self) -> URL: ...

@base_url.setter
def base_url(self, v: URLTypes):
...
def base_url(self, v: URLTypes): ...

def validate_url(self, url):
...
def validate_url(self, url): ...

def __call__(
self,
Expand All @@ -59,7 +46,7 @@ def __init__(
offset: int,
limit: int,
total_count: int,
results: List[T],
results: list[T],
**kwargs,
) -> None:
super().__init__(**kwargs)
Expand All @@ -69,12 +56,10 @@ def __init__(
self._results = results

@overload
def __getitem__(self, key: int) -> T:
...
def __getitem__(self, key: int) -> T: ...

@overload
def __getitem__(self, key: slice) -> Sequence[T]:
...
def __getitem__(self, key: slice) -> Sequence[T]: ...

def __getitem__(self, key):
return self._results[key]
Expand All @@ -96,15 +81,15 @@ def total_count(self) -> int:


class Common(Generic[T]):
model: Type[T]
model: type[T]
_client: ClientInterface
base_path: str

yield_request = CallCapture()


class APIBase(Generic[T], Common[T]):
sub_apis: Dict[str, Type["APIBase"]] = {}
sub_apis: dict[str, type["APIBase"]] = {}

def __init__(self, client) -> None:
if isinstance(self, ModifiableMixin):
Expand All @@ -123,7 +108,7 @@ def list(self, params=None):

def page(
self, offset=0, limit=100, params=None
) -> Generator[T, Dict[Any, Any], PageResult[T]]:
) -> Generator[T, dict[Any, Any], PageResult[T]]:
if params is None:
params = {}

Expand Down Expand Up @@ -158,7 +143,7 @@ def iterate_all(self, params=None) -> Iterator[T]:
yield from current_list
offset += req_count

def detail(self, pk=None, **params) -> Generator[T, Dict[Any, Any], T]:
def detail(self, pk=None, **params) -> Generator[T, dict[Any, Any], T]:
if all((pk, params)):
raise ValueError("Only one of pk or params must be specified")

Expand Down
26 changes: 9 additions & 17 deletions gcapi/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,12 @@
import os
import re
import uuid
from collections.abc import Generator
from io import BytesIO
from pathlib import Path
from random import randint
from time import sleep
from typing import (
TYPE_CHECKING,
Any,
Callable,
Dict,
Generator,
List,
Optional,
Union,
)
from typing import TYPE_CHECKING, Any, Callable, Optional, Union
from urllib.parse import urljoin

import httpx
Expand Down Expand Up @@ -351,7 +343,7 @@ class WorkstationConfigsAPI(APIBase[gcapi.models.WorkstationConfig]):
model = gcapi.models.WorkstationConfig


def _generate_auth_header(token: str = "") -> Dict:
def _generate_auth_header(token: str = "") -> dict:
if not token:
try:
token = str(os.environ["GRAND_CHALLENGE_AUTHORIZATION"])
Expand Down Expand Up @@ -524,7 +516,7 @@ def _upload_file(self, value):
def upload_cases( # noqa: C901
self,
*,
files: List[str],
files: list[str],
archive: Optional[str] = None,
answer: Optional[str] = None,
archive_item: Optional[str] = None,
Expand Down Expand Up @@ -622,7 +614,7 @@ def upload_cases( # noqa: C901

return raw_image_upload_session

def run_external_job(self, *, algorithm: str, inputs: Dict[str, Any]):
def run_external_job(self, *, algorithm: str, inputs: dict[str, Any]):
"""
Starts an algorithm job with the provided inputs.
You will need to provide the slug of the algorithm. You can find this in the
Expand Down Expand Up @@ -702,7 +694,7 @@ def run_external_job(self, *, algorithm: str, inputs: Dict[str, Any]):
return (yield from self.__org_api_meta.algorithm_jobs.create(**job))

def update_archive_item(
self, *, archive_item_pk: str, values: Dict[str, Any]
self, *, archive_item_pk: str, values: dict[str, Any]
):
"""
This function updates an existing archive item with the provided values
Expand Down Expand Up @@ -739,7 +731,7 @@ def update_archive_item(
item = yield from self.__org_api_meta.archive_items.detail(
pk=archive_item_pk
)
civs: Dict[str, list] = {"values": []}
civs: dict[str, list] = {"values": []}

for civ_slug, value in values.items():
try:
Expand Down Expand Up @@ -831,7 +823,7 @@ def _validate_display_set_values(self, values, interfaces):
return interfaces

def add_cases_to_reader_study(
self, *, reader_study: str, display_sets: List[Dict[str, Any]]
self, *, reader_study: str, display_sets: list[dict[str, Any]]
):
"""
This function takes a reader study slug and a list of diplay sets
Expand Down Expand Up @@ -862,7 +854,7 @@ def add_cases_to_reader_study(
The pks of the newly created display sets.
"""
res = []
interfaces: Dict[str, Dict] = {}
interfaces: dict[str, dict] = {}
for display_set in display_sets:
new_interfaces = yield from self._validate_display_set_values(
display_set.items(), interfaces
Expand Down
13 changes: 3 additions & 10 deletions gcapi/gcapi.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
import inspect
import logging
from collections.abc import AsyncGenerator, Generator
from functools import wraps
from typing import (
Any,
AsyncGenerator,
Callable,
Dict,
Generator,
NamedTuple,
Union,
)
from typing import Any, Callable, NamedTuple, Union

import httpx

Expand Down Expand Up @@ -72,7 +65,7 @@ def wrap(*args, **kwargs):

def _wrap_client_base_interfaces(self):
def wrap_api(api: APIBase):
attrs: Dict[str, Any] = {"__init__": lambda *_, **__: None}
attrs: dict[str, Any] = {"__init__": lambda *_, **__: None}

for name in dir(api):
if name.startswith("__"):
Expand Down
Loading