Coverage for src/bioimageio/spec/_internal/field_validation.py: 74%
43 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-16 10:20 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-16 10:20 +0000
1from __future__ import annotations
3from datetime import date, datetime
4from typing import (
5 Any,
6 Hashable,
7 Mapping,
8 Sequence,
9)
11import httpx
12from typing_extensions import TypeGuard
14from ._settings import settings
15from .constants import KNOWN_GITHUB_USERS, KNOWN_INVALID_GITHUB_USERS
16from .field_warning import issue_warning
17from .io import YamlKey, YamlLeafValue, YamlValue
18from .type_guards import is_mapping, is_sequence, is_tuple
19from .validation_context import get_validation_context
22def is_valid_yaml_leaf_value(
23 value: Any,
24) -> TypeGuard[YamlLeafValue]:
25 return value is None or isinstance(value, (bool, date, datetime, int, float, str))
28def is_valid_yaml_key(value: Any | Sequence[Any]) -> TypeGuard[YamlKey]:
29 return (
30 is_valid_yaml_leaf_value(value)
31 or is_tuple(value)
32 and all(is_valid_yaml_leaf_value(v) for v in value)
33 )
36def is_valid_yaml_mapping(value: Any) -> TypeGuard[Mapping[YamlKey, YamlValue]]:
37 return is_mapping(value) and all(
38 is_valid_yaml_key(k) and is_valid_yaml_value(v) for k, v in value.items()
39 )
42def is_valid_yaml_sequence(value: Any) -> TypeGuard[Sequence[YamlValue]]:
43 return is_sequence(value) and all(is_valid_yaml_value(v) for v in value)
46def is_valid_yaml_value(value: Any) -> TypeGuard[YamlValue]:
47 return any(
48 is_valid(value)
49 for is_valid in (
50 is_valid_yaml_key,
51 is_valid_yaml_mapping,
52 is_valid_yaml_sequence,
53 )
54 )
57def validate_unique_entries(seq: Sequence[Hashable]):
58 if len(seq) != len(set(seq)):
59 raise ValueError("Entries are not unique.")
60 return seq
63def validate_github_user(
64 username: str, hotfix_known_errorenous_names: bool = True
65) -> str:
66 if hotfix_known_errorenous_names and username == "Constantin Pape":
67 return "constantinpape"
69 if (
70 username.lower() in KNOWN_GITHUB_USERS
71 or not get_validation_context().perform_io_checks
72 ):
73 return username
75 if username.lower() in KNOWN_INVALID_GITHUB_USERS:
76 raise ValueError(f"Known invalid GitHub user '{username}'")
78 try:
79 r = httpx.get(
80 f"https://api.github.com/users/{username}",
81 auth=settings.github_auth,
82 timeout=settings.http_timeout,
83 )
84 except httpx.TimeoutException:
85 issue_warning(
86 "Could not verify GitHub user '{value}' due to connection timeout",
87 value=username,
88 )
89 else:
90 if r.status_code == 403 and r.reason_phrase == "rate limit exceeded":
91 issue_warning(
92 "Could not verify GitHub user '{value}' due to GitHub API rate limit",
93 value=username,
94 )
95 elif r.status_code != 200:
96 KNOWN_INVALID_GITHUB_USERS.add(username.lower())
97 raise ValueError(f"Could not find GitHub user '{username}'")
99 KNOWN_GITHUB_USERS.add(username.lower())
101 return username