Skip to content

funnydman/pymapme

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

10 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ—ΊοΈ PyMapMe

Python 3.13+ Pydantic 2.0+ License: GPL v3 Tests

Transform Pydantic models from one structure to another with declarative field mapping.

✨ Reshape data between APIs

🎯 Flatten nested structures

πŸ”„ Aggregate complex models

All while maintaining Pydantic's validation and type safety.


πŸ“‹ Table of Contents


πŸš€ Quick Start

Map data from a source Pydantic model to a target model with a different structure, using simple field declarations:

from pydantic import BaseModel, Field
from pymapme.models.mapping import MappingModel

# Source models
class PersonalInfo(BaseModel):
    first_name: str
    last_name: str

class JobInfo(BaseModel):
    title: str
    company: str

class UserProfile(BaseModel):
    personal: PersonalInfo
    job: JobInfo

# Target model with flattened structure
class UserSummary(MappingModel):
    name: str = Field(json_schema_extra={"source": "personal.first_name"})
    title: str = Field(json_schema_extra={"source": "job.title"})

# Transform
profile = UserProfile(
    personal=PersonalInfo(first_name="John", last_name="Smith"),
    job=JobInfo(title="Developer", company="Acme")
)
summary = UserSummary.build_from_model(profile)
# UserSummary(name="John", title="Developer")

✨ Features

🎯 Nested Field Mapping

Map deeply nested fields using dot notation:

class OrderSummary(MappingModel):
    customer_name: str = Field(json_schema_extra={"source": "customer.profile.name"})
    payment_total: float = Field(json_schema_extra={"source": "payment.amount"})
    shipping_city: str = Field(json_schema_extra={"source": "shipping.address.city"})

πŸ”§ Custom Transformation Functions

Transform data using custom functions with access to the source model:

class UserDisplay(MappingModel):
    full_name: str = Field(json_schema_extra={"source_func": "_build_full_name"})
    
    @staticmethod
    def _build_full_name(source_model, default):
        return f"{source_model.first_name} {source_model.last_name}".strip()

πŸ“Š Context Data Injection

Inject additional data during transformation:

class EnrichedUser(MappingModel):
    name: str = Field(json_schema_extra={"source": "name"})
    is_premium: bool = Field(json_schema_extra={"source_func": "_check_premium"})
    
    @staticmethod
    def _check_premium(source_model, default, user_tier: str = "basic"):
        return user_tier == "premium"

# Usage with context
user = User(name="John")
enriched = EnrichedUser.build_from_model(user, context={"user_tier": "premium"})
# EnrichedUser(name="John", is_premium=True)

⚑ Automatic Field Mapping

Fields without explicit mapping use the same field name from source:

class SimpleMapping(MappingModel):
    # These map automatically by name
    name: str
    email: str
    # This uses explicit mapping
    user_id: int = Field(json_schema_extra={"source": "id"})

πŸ“¦ Installation

# Using pip
pip install pymapme

# Using Poetry
poetry add pymapme

πŸ”§ Requirements

  • Python 3.13+
  • Pydantic 2.0+

πŸ› οΈ Development

Setup

# Clone the repository
git clone https://github.com/funnydman/pymapme.git
cd pymapme

# Install dependencies
poetry install

Commands

# Run tests with coverage
make run-unit-tests

# Run static analysis (Ruff + mypy)
make run-static-analysis

# Auto-format code
make format

# Build package
make build-package

🀝 Contributing

We welcome contributions! Please follow these steps:

1. Fork and Clone

git clone https://github.com/funnydman/pymapme.git
cd pymapme

2. Create Feature Branch

git checkout -b feature/your-feature-name

3. Make Changes

  • Write tests for new functionality
  • Follow existing code patterns
  • Update documentation if needed

4. Verify Quality

# Run full test suite
make run-unit-tests

# Check code quality
make run-static-analysis

# Format code
make format

5. Submit Pull Request

  • Ensure all tests pass
  • Include clear description of changes
  • Reference any related issues

Development Guidelines

  • Tests: Write tests for all new features and bug fixes
  • Type hints: Use modern Python type annotations
  • Documentation: Update examples and docstrings as needed
  • Commit messages: Use clear, descriptive commit messages

πŸ“„ License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.

About

Transform Pydantic models from one structure to another with declarative field mapping.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •