CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-flask-restplus

Fully featured framework for fast, easy and documented API development with Flask

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

models-marshalling.mddocs/

Models and Marshalling

Data model definition and automatic marshalling system for request/response handling. Flask-RESTPlus provides model classes for defining data structures and marshalling functions for automatic serialization and validation.

Capabilities

Model Classes

Base classes for defining data models used in request validation and response marshalling.

class Model(dict):
    def __init__(self, name, *args, mask=None, **kwargs):
        """
        Initialize a field-based model.
        
        Args:
            name (str): Model name for documentation
            *args: Additional positional arguments
            mask (str or Mask, optional): Default model mask
            **kwargs: Field definitions
        """
    
    @classmethod
    def inherit(cls, name, *parents):
        """
        Create a new model inheriting from parent models using Swagger composition.
        
        Args:
            name (str): New model name
            *parents (Model): Parent models to inherit from
        
        Returns:
            Model: New inherited model
        """
    
    def clone(self, name=None, *parents):
        """
        Clone this model by duplicating all fields.
        
        Args:
            name (str, optional): New model name
            *parents (Model): Additional parent models
        
        Returns:
            Model: Cloned model
        """
    
    def validate(self, data, resolver=None, format_checker=None):
        """
        Validate data against the model schema.
        
        Args:
            data: Data to validate
            resolver: JSON schema resolver
            format_checker: JSON schema format checker
            
        Raises:
            ValidationError: If validation fails
        """
    
    def get_parent(self, name):
        """
        Get a parent model by name.
        
        Args:
            name (str): Parent model name
            
        Returns:
            Model: Parent model instance
        """
    
    @property
    def ancestors(self):
        """
        Return the inheritance tree as a set.
        
        Returns:
            set: Set of ancestor model names
        """
    
    @property
    def __schema__(self):
        """
        Return the JSON Schema representation.
        
        Returns:
            dict: JSON Schema with inheritance support
        """
    
    @property
    def resolved(self):
        """
        Get the resolved model definition.
        
        Returns:
            dict: Resolved field definitions
        """

class OrderedModel(Model):
    def __init__(self, name, *args, mask=None, **kwargs):
        """
        Initialize an ordered model that preserves field insertion order.
        Inherits all methods from Model but maintains field ordering.
        
        Args:
            name (str): Model name for documentation
            *args: Additional positional arguments
            mask (str or Mask, optional): Default model mask
            **kwargs: Field definitions in order
        """

class SchemaModel:
    def __init__(self, name, schema=None):
        """
        Initialize a model based on a JSON schema definition.
        Unlike Model/OrderedModel, this doesn't manage fields directly.
        
        Args:
            name (str): Model name for documentation
            schema (dict, optional): JSON schema definition
        """
    
    @classmethod
    def inherit(cls, name, *parents):
        """
        Create a new schema model inheriting from parent models.
        
        Args:
            name (str): New model name
            *parents (SchemaModel): Parent models to inherit from
        
        Returns:
            SchemaModel: New inherited model
        """
    
    def validate(self, data, resolver=None, format_checker=None):
        """
        Validate data against the schema.
        
        Args:
            data: Data to validate
            resolver: JSON schema resolver
            format_checker: JSON schema format checker
            
        Raises:
            ValidationError: If validation fails
        """
    
    @property
    def __schema__(self):
        """
        Return the stored JSON schema.
        
        Returns:
            dict: JSON Schema definition
        """
    
    @property
    def ancestors(self):
        """
        Return the inheritance tree as a set.
        
        Returns:
            set: Set of ancestor model names
        """

Marshalling Functions

Functions for serializing Python objects to JSON responses using field definitions.

def marshal(data, fields, envelope=None, skip_none=False, mask=None, ordered=False):
    """
    Marshal data using field definitions.
    
    Args:
        data: The data to marshal (dict, list, or object)
        fields (dict): Field definitions for marshalling
        envelope (str, optional): Envelope key for response wrapping
        skip_none (bool): Skip None values in output
        mask (str, optional): Field mask for partial responses
        ordered (bool): Preserve field ordering
    
    Returns:
        dict or list: Marshalled data
    """

def marshal_with(fields, as_list=False, code=200, description=None, **kwargs):
    """
    Decorator for automatic response marshalling.
    
    Args:
        fields (dict or Model): Fields for marshalling
        as_list (bool): Marshal response as a list
        code (int): HTTP status code for successful response
        description (str, optional): Response description
        **kwargs: Additional marshal options (envelope, skip_none, mask, ordered)
    
    Returns:
        callable: Decorator function
    """

def marshal_with_field(field, **kwargs):
    """
    Decorator for marshalling with a single field.
    
    Args:
        field (Field): Single field for marshalling
        **kwargs: Additional marshal options
    
    Returns:
        callable: Decorator function
    """

Response Masking

Response field masking system for partial responses and field filtering.

class Mask:
    def __init__(self, mask=None, skip=False, **kwargs):
        """
        Initialize a field mask.
        
        Args:
            mask (str, optional): Mask string (e.g., "field1,field2{subfield}")
            skip (bool): Skip masked fields instead of including them
            **kwargs: Additional mask options
        """
    
    def parse(self, mask):
        """
        Parse a mask string.
        
        Args:
            mask (str): Mask string to parse
        
        Returns:
            dict: Parsed mask structure
        """
    
    def apply(self, data):
        """
        Apply the mask to data.
        
        Args:
            data: Data to mask
        
        Returns:
            Masked data
        """
    
    def filter_data(self, data):
        """
        Filter data according to the mask.
        
        Args:
            data: Data to filter
        
        Returns:
            Filtered data
        """

def apply_mask(data, mask, skip=False):
    """
    Apply a field mask to data.
    
    Args:
        data: Data to mask
        mask (str or Mask): Field mask
        skip (bool): Skip masked fields
    
    Returns:
        Masked data
    """

Usage Examples

Basic Model Definition

from flask_restplus import Api, fields

api = Api()

# Define a simple model
user_model = api.model('User', {
    'id': fields.Integer(required=True, description='User ID'),
    'name': fields.String(required=True, description='User name'),
    'email': fields.String(required=True, description='Email address'),
    'active': fields.Boolean(description='Account status')
})

# Define a nested model
post_model = api.model('Post', {
    'id': fields.Integer(required=True, description='Post ID'),
    'title': fields.String(required=True, description='Post title'),
    'content': fields.String(description='Post content'),
    'author': fields.Nested(user_model, description='Post author'),
    'tags': fields.List(fields.String, description='Post tags'),
    'created_at': fields.DateTime(description='Creation timestamp')
})

Model Inheritance

from flask_restplus import Api, fields

api = Api()

# Base model
base_model = api.model('BaseModel', {
    'id': fields.Integer(required=True, description='Resource ID'),
    'created_at': fields.DateTime(description='Creation timestamp'),
    'updated_at': fields.DateTime(description='Last update timestamp')
})

# Inherited model
user_model = api.inherit('User', base_model, {
    'name': fields.String(required=True, description='User name'),
    'email': fields.String(required=True, description='Email address'),
})

# Multiple inheritance
admin_model = api.inherit('Admin', user_model, {
    'permissions': fields.List(fields.String, description='Admin permissions'),
    'is_super_admin': fields.Boolean(description='Super admin status')
})

Model Cloning

from flask_restplus import Api, fields

api = Api()

user_model = api.model('User', {
    'id': fields.Integer(required=True),
    'name': fields.String(required=True),
    'email': fields.String(required=True),
    'password': fields.String(required=True)
})

# Clone model without password field for responses
user_public = api.clone('UserPublic', user_model)
del user_public['password']

# Or create a new model with modifications
user_update = api.clone('UserUpdate', user_model, {
    'password': fields.String(description='New password (optional)')
})
# Make all fields optional for updates
for field_name, field in user_update.items():
    field.required = False

Response Marshalling

from flask_restplus import Api, Resource, fields, marshal_with

api = Api()

user_model = api.model('User', {
    'id': fields.Integer,
    'name': fields.String,
    'email': fields.String
})

@api.route('/users/<int:user_id>')
class User(Resource):
    @api.marshal_with(user_model)
    def get(self, user_id):
        # Return raw data - will be automatically marshalled
        user_data = {
            'id': user_id,
            'name': 'John Doe',
            'email': 'john@example.com',
            'internal_field': 'hidden'  # Not in model, will be filtered out
        }
        return user_data

@api.route('/users')
class UserList(Resource):
    @api.marshal_list_with(user_model)
    def get(self):
        # Return list of raw data
        users = [
            {'id': 1, 'name': 'John', 'email': 'john@example.com'},
            {'id': 2, 'name': 'Jane', 'email': 'jane@example.com'}
        ]
        return users

Manual Marshalling

from flask_restplus import Api, fields, marshal

api = Api()

user_fields = {
    'id': fields.Integer,
    'name': fields.String,
    'email': fields.String
}

# Manual marshalling
user_data = {'id': 1, 'name': 'John', 'email': 'john@example.com', 'secret': 'hidden'}
marshalled = marshal(user_data, user_fields)
# Result: {'id': 1, 'name': 'John', 'email': 'john@example.com'}

# Marshal with envelope
marshalled_with_envelope = marshal(user_data, user_fields, envelope='user')
# Result: {'user': {'id': 1, 'name': 'John', 'email': 'john@example.com'}}

# Marshal list
users_data = [
    {'id': 1, 'name': 'John', 'email': 'john@example.com'},
    {'id': 2, 'name': 'Jane', 'email': 'jane@example.com'}
]
marshalled_list = marshal(users_data, user_fields)

# Skip None values
data_with_none = {'id': 1, 'name': None, 'email': 'john@example.com'}
marshalled_skip_none = marshal(data_with_none, user_fields, skip_none=True)
# Result: {'id': 1, 'email': 'john@example.com'}

Field Masking

from flask_restplus import Api, Resource, fields, marshal_with

api = Api()

user_model = api.model('User', {
    'id': fields.Integer,
    'name': fields.String,
    'email': fields.String,
    'profile': fields.Nested({
        'bio': fields.String,
        'avatar_url': fields.String,
        'preferences': fields.Nested({
            'theme': fields.String,
            'notifications': fields.Boolean
        })
    })
})

@api.route('/users/<int:user_id>')
class User(Resource):
    @api.marshal_with(user_model)
    def get(self, user_id):
        # Client can request specific fields with ?mask= parameter
        # Examples:
        # ?mask=id,name - returns only id and name
        # ?mask=id,name,profile{bio} - includes id, name, and profile.bio
        # ?mask=profile{preferences{theme}} - nested field selection
        
        user_data = {
            'id': user_id,
            'name': 'John Doe',
            'email': 'john@example.com',
            'profile': {
                'bio': 'Software developer',
                'avatar_url': 'http://example.com/avatar.jpg',
                'preferences': {
                    'theme': 'dark',
                    'notifications': True
                }
            }
        }
        return user_data

Ordered Models

from flask_restplus import Api, fields, OrderedModel

api = Api()

# Regular model - field order not guaranteed
regular_model = api.model('Regular', {
    'name': fields.String,
    'id': fields.Integer,
    'email': fields.String
})

# Ordered model - preserves field order
ordered_model = api.model('Ordered', OrderedModel('OrderedUser', {
    'id': fields.Integer,      # Will appear first
    'name': fields.String,     # Will appear second
    'email': fields.String     # Will appear third
}))

Schema-based Models

from flask_restplus import Api, SchemaModel

api = Api()

# JSON schema definition
user_schema = {
    "type": "object",
    "properties": {
        "id": {"type": "integer"},
        "name": {"type": "string"},
        "email": {"type": "string", "format": "email"}
    },
    "required": ["id", "name"]
}

# Create model from JSON schema
user_model = api.model('User', SchemaModel('User', schema=user_schema))

Install with Tessl CLI

npx tessl i tessl/pypi-flask-restplus

docs

api-resources.md

documentation.md

error-handling.md

fields.md

index.md

input-validation.md

models-marshalling.md

request-parsing.md

tile.json