Skip to content

Add a marshmallow module with validation tools #108

Description

@llucax

What's needed?

We need to provide an easy way to load configuration for API clients using marshmallow.

Proposed solution

Add the following types:

from typing import Annotated
from marshmallow.fields import String
from marshmallow.validate import URL, Length


class GrpcUrlField(String):
    """A marshmallow field for a gRPC URL."""

    def __init__(self, *_: Any, **kwargs: Any) -> None:
        """Initialize this instance."""
        validators = kwargs.pop("validate", [])
        if not isinstance(validators, list):
            validators = [validators]
        validators.append(URL(schemes=["grpc"], error="Not a valid gRPC URL."))
        super().__init__(validate=validators, **kwargs)


class ApiKeyField(String):
    """A marshmallow field for an API key."""

    def __init__(self, *_: Any, **kwargs: Any) -> None:
        """Initialize this instance."""
        validators = kwargs.pop("validate", [])
        if not isinstance(validators, list):
            validators = [validators]
        validators.append(Length(min=1, error="API key must be non-empty."))
        super().__init__(validate=validators, **kwargs)

GrpcUrl = Annotated[str, GrpcUrlField]
]
"""A marshmallow field for a gRPC URL."""

ApiKey = Annotated[str, ApiKeyField]
"""A marshmallow field for an API key."""

Use cases

Validating environment variables, for example:

from dataclasses import dataclass
from frequenz.sdk.config import load_config

@dataclass(frozen=True, kw_only=True)
class EnvironmentConfig:
    API_URL: GrpcUrl
    DISPATCH_API_KEY: ApiKey | None = None

env_config = load_config(EnvironmentConfig, os.environ, unknown=marshmallow.EXCLUDE)

Alternatives and workarounds

No response

Additional context

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    part:codeAffects the code in generaltype:enhancementNew feature or enhancement visitble to users

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions