Update Python tools

This commit is contained in:
ajp_anton
2026-08-09 02:31:54 +00:00
parent b0c707d624
commit 6d28257b54
10 changed files with 362 additions and 12 deletions
+50
View File
@@ -4,11 +4,28 @@ from __future__ import annotations
import re
from collections.abc import Mapping, Sequence
from dataclasses import dataclass
from datetime import date, datetime
from pathlib import Path
from typing import BinaryIO, Protocol
from .discovery import InputField
class Upload(Protocol):
filename: str | None
content_length: int | None
stream: BinaryIO
@dataclass(frozen=True)
class PendingUpload:
field_name: str
extension: str
maximum_bytes: int | None
stream: BinaryIO
def validate_inputs(
fields: Sequence[InputField],
values: Mapping[str, list[str]],
@@ -16,6 +33,8 @@ def validate_inputs(
result: dict[str, str | int | list[str]] = {}
errors: dict[str, str] = {}
for field in fields:
if field.type == "file":
continue
raw_values = values.get(field.name, [])
value, error = validate_field(field, raw_values)
if error:
@@ -25,6 +44,37 @@ def validate_inputs(
return result, errors
def validate_uploads(
fields: Sequence[InputField],
uploads: Mapping[str, Upload],
) -> tuple[dict[str, PendingUpload], dict[str, str]]:
result: dict[str, PendingUpload] = {}
errors: dict[str, str] = {}
for field in fields:
if field.type != "file":
continue
upload = uploads.get(field.name)
filename = upload.filename if upload is not None else None
if upload is None or not filename:
if field.required:
errors[field.name] = "Choose a file."
continue
extension = Path(filename).suffix.lower()
if field.accept and extension not in field.accept:
errors[field.name] = f"Choose a file with one of: {', '.join(field.accept)}."
continue
if upload.content_length is not None and field.maximum_bytes is not None and upload.content_length > field.maximum_bytes:
errors[field.name] = f"Choose a file no larger than {field.maximum_bytes} bytes."
continue
result[field.name] = PendingUpload(
field_name=field.name,
extension=extension,
maximum_bytes=field.maximum_bytes,
stream=upload.stream,
)
return result, errors
def validate_field(
field: InputField,
raw_values: list[str],