• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SwissDataScienceCenter / renku-data-services / 10486788022

21 Aug 2024 08:59AM UTC coverage: 90.438% (-0.1%) from 90.561%
10486788022

push

github

web-flow
fix: backgroundjob should continue if project is missing (#359)

3 of 7 new or added lines in 1 file covered. (42.86%)

10 existing lines in 6 files now uncovered.

9184 of 10155 relevant lines covered (90.44%)

1.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.15
/components/renku_data_services/base_api/misc.py
1
"""Common blueprints."""
2✔
2

3
from collections.abc import Awaitable, Callable, Coroutine
2✔
4
from dataclasses import dataclass
2✔
5
from functools import wraps
2✔
6
from typing import Any, Concatenate, NoReturn, ParamSpec, TypeVar, cast
2✔
7

8
from pydantic import BaseModel
2✔
9
from sanic import Request, json
2✔
10
from sanic.response import JSONResponse
2✔
11
from sanic_ext import validate
2✔
12

13
from renku_data_services import errors
2✔
14
from renku_data_services.base_api.blueprint import BlueprintFactoryResponse, CustomBlueprint
2✔
15

16

17
@dataclass(kw_only=True)
2✔
18
class MiscBP(CustomBlueprint):
2✔
19
    """Server contains all handlers for CRC and the configuration."""
2✔
20

21
    apispec: dict[str, Any]
2✔
22
    version: str
2✔
23

24
    def get_apispec(self) -> BlueprintFactoryResponse:
2✔
25
        """Servers the OpenAPI specification."""
26

27
        async def _get_apispec(_: Request) -> JSONResponse:
2✔
28
            return json(self.apispec)
1✔
29

30
        return "/spec.json", ["GET"], _get_apispec
2✔
31

32
    def get_error(self) -> BlueprintFactoryResponse:
2✔
33
        """Returns a sample error response."""
34

35
        async def _get_error(_: Request) -> NoReturn:
2✔
36
            raise errors.ValidationError(message="Sample validation error")
1✔
37

38
        return "/error", ["GET"], _get_error
2✔
39

40
    def get_version(self) -> BlueprintFactoryResponse:
2✔
41
        """Returns the version."""
42

43
        async def _get_version(_: Request) -> JSONResponse:
2✔
44
            return json({"version": self.version})
2✔
45

46
        return "/version", ["GET"], _get_version
2✔
47

48

49
_T = TypeVar("_T")
2✔
50
_P = ParamSpec("_P")
2✔
51

52

53
def validate_db_ids(f: Callable[_P, Awaitable[_T]]) -> Callable[_P, Coroutine[Any, Any, _T]]:
2✔
54
    """Decorator for a Sanic handler that errors out if passed in IDs are outside of the valid range for postgres."""
55

56
    @wraps(f)
2✔
57
    async def decorated_function(*args: _P.args, **kwargs: _P.kwargs) -> _T:
2✔
58
        resource_pool_id = cast(int | None, kwargs.get("resource_pool_id"))
2✔
59
        class_id = cast(int | None, kwargs.get("class_id"))
2✔
60
        min_val = 1  # postgres primary keys start at 1
2✔
61
        max_val = 2_147_483_647  # the max value for a default postgres primary key sequence
2✔
62
        if resource_pool_id and not min_val <= resource_pool_id <= max_val:
2✔
63
            raise errors.ValidationError(
1✔
64
                message=f"The provided resource pool ID is outside of the allowed range [{min_val}, {max_val}]"
65
            )
66
        if class_id and not min_val <= class_id <= max_val:
2✔
UNCOV
67
            raise errors.ValidationError(
×
68
                message=f"The provided resource class ID is outside of the allowed range [{min_val}, {max_val}]"
69
            )
70
        response = await f(*args, **kwargs)
2✔
71
        return response
2✔
72

73
    return decorated_function
2✔
74

75

76
def validate_query(
2✔
77
    query: type[BaseModel],
78
) -> Callable[
79
    [Callable[Concatenate[Request, _P], Awaitable[_T]]],
80
    Callable[Concatenate[Request, _P], Coroutine[Any, Any, _T]],
81
]:
82
    """Decorator for sanic query parameter validation.
83

84
    Should be removed once sanic fixes this error in their validation code.
85
    """
86

87
    def decorator(
2✔
88
        f: Callable[Concatenate[Request, _P], Awaitable[_T]],
89
    ) -> Callable[Concatenate[Request, _P], Coroutine[Any, Any, _T]]:
90
        @wraps(f)
2✔
91
        async def decorated_function(request: Request, *args: _P.args, **kwargs: _P.kwargs) -> _T:
2✔
92
            try:
2✔
93
                return await validate(query=query)(f)(request, *args, **kwargs)
2✔
94
            except KeyError:
2✔
95
                raise errors.ValidationError(message="Failed to validate the query parameters")
1✔
96

97
        return decorated_function
2✔
98

99
    return decorator
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc