Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a marshmallow module with validation tools #108

Open
llucax opened this issue Jan 15, 2025 · 0 comments
Open

Add a marshmallow module with validation tools #108

llucax opened this issue Jan 15, 2025 · 0 comments
Labels
part:code Affects the code in general type:enhancement New feature or enhancement visitble to users

Comments

@llucax
Copy link
Contributor

llucax commented Jan 15, 2025

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

@llucax llucax added part:code Affects the code in general type:enhancement New feature or enhancement visitble to users labels Jan 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
part:code Affects the code in general type:enhancement New feature or enhancement visitble to users
Projects
None yet
Development

No branches or pull requests

1 participant