Skip to main content

A versatile library for transforming and serializing data models into multiple formats.

Project description

DOI

Transmutate

Transmutate is a Python library designed to handle dataclass serialization and deserialization across various formats such as JSON, JSONB, and Protocol Buffers (Proto). The library supports both conversion to these formats and validation of dataclass fields.

Features

  • JSON Serialization: Convert dataclasses to and from JSON format.
  • JSONB Serialization: Convert dataclasses to and from JSONB format, a compact version of JSON.
  • Protocol Buffers Serialization: Generate Proto definitions from dataclasses.
  • Field Validation: Custom validation for dataclass fields using validation_<field> methods.
  • Service Definitions: Define gRPC services with customizable RPC methods.
  • Proto Generator: Automatically generate Proto files including service and message definitions.
  • Easy Integration: Built on top of Python's dataclasses, allowing seamless integration with existing codebases.

Installation

You can install Transmutate via Poetry by adding it to your pyproject.toml file or by using the following command:

poetry add transmutate

Alternatively, if you're using pip, you can install it with:

pip install transmutate

Usage

Below are some examples demonstrating how to use Transmutate with simple dataclasses.

Defining a Dataclass

You can define your dataclasses using the BaseModel from Transmutate, which provides built-in serialization and validation capabilities.

from dataclasses import dataclass, field
from typing import List, Optional
from transmutate.base_model import BaseModel

class Person(BaseModel):
    name: str
    age: int
    email: Optional[str] = None
    phone_numbers: List[str] = field(default_factory=list)

    def validation_age(self):
        if not (0 <= self.age <= 120):
            raise ValueError("Age must be between 0 and 120.")

    def validation_email(self):
        if self.email and "@" not in self.email:
            raise ValueError("Invalid email address.")

JSON Serialization

Convert a dataclass instance to JSON:

person = Person(name="John Doe", age=30, email="john.doe@example.com")
json_data = person.to_json()
print(json_data)

Output:

{
    "name": "John Doe",
    "age": 30,
    "email": "john.doe@example.com",
    "phone_numbers": []
}

Parse a JSON string back to a dataclass instance:

person_from_json = Person.from_json(json_data)
print(person_from_json)

JSONB Serialization

Convert a dataclass instance to JSONB:

jsonb_data = person.to_jsonb()
print(jsonb_data)

Output:

{"name":"John Doe","age":30,"email":"john.doe@example.com","phone_numbers":[]}

Parse a JSONB string back to a dataclass instance:

person_from_jsonb = Person.from_jsonb(jsonb_data)
print(person_from_jsonb)

Proto Serialization

Generate a Proto definition from a dataclass:

proto_definition = person.to_proto()
print(proto_definition)

Output:

syntax = "proto3";

message Person {
  string name = 1;
  int32 age = 2;
  string email = 3;
  repeated string phone_numbers = 4;
}

Custom Validation

You can define custom validation logic for fields in your dataclasses using validation_<field> methods. These methods will automatically be called during initialization.

@dataclass
class Address(BaseModel):
    street: str
    city: str
    zip_code: str

    def validation_zip_code(self):
        if not self.zip_code.isdigit() or len(self.zip_code) != 5:
            raise ValueError("Zip code must be a 5-digit number.")

Defining a gRPC Service

The Service class allows you to define gRPC services with various RPC types.

from transmutate.service import Service, RpcType
from typing import List

class TestMessage(BaseModel):
    name: str
    age: int
    email: str
    phone_numbers: List[str]

class AnotherMessage(BaseModel):
    status: str
    message: str

service = Service(
    name="TestService",
    types=[RpcType.UNARY, RpcType.SERVER_STREAMING],
    method_names=["GetInfo", "StreamInfo"],
    request_dataclass=TestMessage,
    response_dataclass=AnotherMessage
)

Proto File Generation

Use ProtoGenerator to automatically generate Proto files for services and messages.

from transmutate.proto_generator import ProtoGenerator

services = [
    Service(
        name="TestService",
        types=[RpcType.UNARY, RpcType.SERVER_STREAMING],
        method_names=["GetInfo", "StreamInfo"],
        request_dataclass=TestMessage,
        response_dataclass=AnotherMessage
    )
]

proto_generator = ProtoGenerator(service_name="TestService", services=services)
proto_generator.generate_proto()

Output Proto file will be saved in the specified directory:

syntax = "proto3";

package testservice;

service TestService {
  rpc GetInfo (TestMessage) returns (AnotherMessage);
  rpc StreamInfo (TestMessage) returns (stream AnotherMessage);
}

message TestMessage {
  string name = 1;
  int32 age = 2;
  string email = 3;
  repeated string phone_numbers = 4;
}

message AnotherMessage {
  string status = 1;
  string message = 2;
}

Testing

Transmutate includes a suite of unit tests to ensure functionality. You can run the tests using unittest or pytest.

# Using unittest
poetry run python -m unittest discover tests

# Using pytest
poetry run pytest tests

Contributing

Contributions to Transmutate are welcome! Please feel free to open issues or submit pull requests on the GitHub repository.

License

Transmutate is open-source software licensed under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

transmutate-0.2.2.tar.gz (8.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

transmutate-0.2.2-py3-none-any.whl (9.4 kB view details)

Uploaded Python 3

File details

Details for the file transmutate-0.2.2.tar.gz.

File metadata

  • Download URL: transmutate-0.2.2.tar.gz
  • Upload date:
  • Size: 8.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.7.1 CPython/3.10.12 Linux/5.15.153.1-microsoft-standard-WSL2

File hashes

Hashes for transmutate-0.2.2.tar.gz
Algorithm Hash digest
SHA256 74d32b2a8adfa2cfaa69bbaca4af8627a7929e9322e8d117e450f9755cc68962
MD5 2d387db04b3bac744795baa186dbcf0e
BLAKE2b-256 a7f66c3ee48fb86b25a9b74c8eeaf2db0e84425a0e6a037a8df3aa51b2e04bc2

See more details on using hashes here.

File details

Details for the file transmutate-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: transmutate-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 9.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.7.1 CPython/3.10.12 Linux/5.15.153.1-microsoft-standard-WSL2

File hashes

Hashes for transmutate-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 43c9138ef040b7b5b9fe9af1ff766ba3a2a256755281fb40a726ad30400b4fd9
MD5 0fed2efe296bad2bcdc8251e1da9d82a
BLAKE2b-256 3720d66708034f6cddca44638b83cb9e58906e375461f268966faf5782cef780

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page