Source code for swh.web.api.serializers
# Copyright (C) 2025 The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU Affero General Public License version 3, or any later version
# See top-level LICENSE file for more information
import rfc3987
from rest_framework import serializers
from swh.model.exceptions import ValidationError
from swh.model.swhids import QualifiedSWHID
[docs]
class SoftLimitsIntegerField(serializers.IntegerField):
    """An IntegerField that soft-enforce min/max values."""
[docs]
    def to_internal_value(self, data) -> int:
        """Before returning `data` limit its value to min_value & max_value.
        Args:
            data: a string representation of a value
        Returns:
            An integer between min_value & max_value
        """
        data = super().to_internal_value(data)
        if self.min_value:
            data = max(data, self.min_value)
        if self.max_value:
            data = min(data, self.max_value)
        return data 
 
[docs]
class SWHIDField(serializers.CharField):
    """A SWHID field."""
[docs]
    def to_internal_value(self, data: str) -> str:
        """Validate a SWHID.
        Args:
            value: a string
        Raises:
            serializers.ValidationError: invalid SWHID
        Returns:
            a string
        """
        data = super().to_internal_value(data)
        try:
            QualifiedSWHID.from_string(data)
        except ValidationError as e:
            raise serializers.ValidationError(
                f"Invalid target SWHID {data}: {e.message}."
            )
        return data 
 
[docs]
class IRIField(serializers.CharField):
    """An Internationalized Resource Identifier field.
    Requires a valid IRI value and limits its length to 4096, can be used to handle
    origin URLS.
    """
    def __init__(self, **kwargs):
        """Defaults max_length to 4096."""
        if "max_length" not in kwargs:
            kwargs["max_length"] = 4096
        super().__init__(**kwargs)
[docs]
    def to_internal_value(self, data: str) -> str:
        """Validate the IRI.
        Args:
            data: a string
        Raises:
            serializers.ValidationError: invalid IRI
        Returns:
            an URI
        """
        data = super().to_internal_value(data)
        try:
            rfc3987.parse(data, rule="IRI")
        except ValueError as e:
            raise serializers.ValidationError(str(e))
        return data