Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

The Duper logo, with a confident spectacled mole wearing a flailing blue cape.

duper-python

PyPI version GitHub license

Duper support for Python.

Check out the official website for Duper.

Installation

uv add duper-python
# -- or --
pip install duper-python

Examples

The basic json/pickle-like interface:

import duper

DUPER_DATA = """
APIResponse({
  status: 200,
  headers: {
    content_type: "application/duper",
    cache_control: "max-age=3600",
  },
  body: {
    users: [
      User({
        id: Uuid("7039311b-02d2-4849-a6de-900d4dbe9acb"),
        name: "Alice",
        email: Email("alice@example.com"),
        roles: ["admin", "user"],
        metadata: {
          last_login: DateTime("2024-01-15T10:30:00Z"),
          ip: IPV4("173.255.230.79"),
        },
      }),
    ],
  },
})
"""

python_dict = duper.loads(DUPER_DATA)  # Actually a Pydantic BaseModel!

with open("out.duper", "w") as f:
    duper.dump(DUPER_DATA)

Using Pydantic:

from datetime import datetime
import re
import uuid

from duper import BaseModel


class RegisteredRegex(BaseModel):
    regex_id: uuid.UUID
    created_at: datetime
    pattern: re.Pattern
    matches: list[str] | None = None

data = RegisteredRegex(
    regex_id=uuid.uuid4(),
    created_at=datetime.now(),
    pattern=re.compile(r"^Hello w.rld!$"),
)

data_str = data.model_dump(mode="duper")
print(data_str)

reconstituted_data = RegisteredRegex.model_validate_duper(data_str)
assert data == reconstituted_data

Using FastAPI:

from typing import Annotated
from duper.fastapi import DuperBody, DuperResponse
from duper import BaseModel
from fastapi import FastAPI

class DuplicatableData(BaseModel):
    tup: tuple[str, bytes]
    value: int

app = FastAPI()

@app.post("/double", response_class=DuperResponse)
async def double_the_data(
    body: Annotated[DuplicatableData, DuperBody(DuplicatableData)],
) -> DuperResponse:
    return DuperResponse(
        DuplicatableData(
            tup=(body.tup[0] + body.tup[0], body.tup[1] + body.tup[1]),
            value=2 * body.value,
        )
    )