# Path: marathon/exceptions.py
# class InvalidChoiceError(MarathonError):
# 
#     def __init__(self, param, value, options):
#         super().__init__(
#             'Invalid choice "{value}" for param "{param}". Must be one of {options}'.format(
#                 param=param, value=value, options=options
#             )
#         )
# 
# Path: marathon/models/base.py
# class MarathonObject:
#     """Base Marathon object."""
# 
#     def __repr__(self):
#         return "{clazz}::{obj}".format(clazz=self.__class__.__name__, obj=self.to_json(minimal=False))
# 
#     def __eq__(self, other):
#         try:
#             return self.__dict__ == other.__dict__
#         except Exception:
#             return False
# 
#     def __hash__(self):
#         # Technically this class shouldn't be hashable because it often
#         # contains mutable fields, but in practice this class is used more
#         # like a record or namedtuple.
#         return hash(self.to_json())
# 
#     def json_repr(self, minimal=False):
#         """Construct a JSON-friendly representation of the object.
# 
#         :param bool minimal: Construct a minimal representation of the object (ignore nulls and empty collections)
# 
#         :rtype: dict
#         """
#         if minimal:
#             return {to_camel_case(k): v for k, v in vars(self).items() if (v or v is False or v == 0)}
#         else:
#             return {to_camel_case(k): v for k, v in vars(self).items()}
# 
#     @classmethod
#     def from_json(cls, attributes):
#         """Construct an object from a parsed response.
# 
#         :param dict attributes: object attributes from parsed response
#         """
#         return cls(**{to_snake_case(k): v for k, v in attributes.items()})
# 
#     def to_json(self, minimal=True):
#         """Encode an object as a JSON string.
# 
#         :param bool minimal: Construct a minimal representation of the object (ignore nulls and empty collections)
# 
#         :rtype: str
#         """
#         if minimal:
#             return json.dumps(self.json_repr(minimal=True), cls=MarathonMinimalJsonEncoder, sort_keys=True)
#         else:
#             return json.dumps(self.json_repr(), cls=MarathonJsonEncoder, sort_keys=True)


from ..exceptions import InvalidChoiceError
from .base import MarathonObject
                pm, MarathonContainerPortMapping) else MarathonContainerPortMapping().from_json(pm)
            for pm in (port_mappings or [])
        ]
        self.parameters = parameters or []
        self.privileged = privileged or False
        self.force_pull_image = force_pull_image or False


class MarathonContainerPortMapping(MarathonObject):

    """Container port mapping.

    See https://mesosphere.github.io/marathon/docs/native-docker.html

    :param str name:
    :param int container_port:
    :param int host_port:
    :param str protocol:
    :param object labels:
    """

    PROTOCOLS = ['tcp', 'udp', 'udp,tcp']
    """Valid protocols"""

    def __init__(self, name=None, container_port=None, host_port=None, service_port=None, protocol='tcp', labels=None):
        self.name = name
        self.container_port = container_port
        self.host_port = host_port
        self.service_port = service_port
        if protocol not in self.PROTOCOLS:

# Path: marathon/exceptions.py
# class InvalidChoiceError(MarathonError):
# 
#     def __init__(self, param, value, options):
#         super().__init__(
#             'Invalid choice "{value}" for param "{param}". Must be one of {options}'.format(
#                 param=param, value=value, options=options
#             )
#         )
# 
# Path: marathon/models/base.py
# class MarathonObject:
#     """Base Marathon object."""
# 
#     def __repr__(self):
#         return "{clazz}::{obj}".format(clazz=self.__class__.__name__, obj=self.to_json(minimal=False))
# 
#     def __eq__(self, other):
#         try:
#             return self.__dict__ == other.__dict__
#         except Exception:
#             return False
# 
#     def __hash__(self):
#         # Technically this class shouldn't be hashable because it often
#         # contains mutable fields, but in practice this class is used more
#         # like a record or namedtuple.
#         return hash(self.to_json())
# 
#     def json_repr(self, minimal=False):
#         """Construct a JSON-friendly representation of the object.
# 
#         :param bool minimal: Construct a minimal representation of the object (ignore nulls and empty collections)
# 
#         :rtype: dict
#         """
#         if minimal:
#             return {to_camel_case(k): v for k, v in vars(self).items() if (v or v is False or v == 0)}
#         else:
#             return {to_camel_case(k): v for k, v in vars(self).items()}
# 
#     @classmethod
#     def from_json(cls, attributes):
#         """Construct an object from a parsed response.
# 
#         :param dict attributes: object attributes from parsed response
#         """
#         return cls(**{to_snake_case(k): v for k, v in attributes.items()})
# 
#     def to_json(self, minimal=True):
#         """Encode an object as a JSON string.
# 
#         :param bool minimal: Construct a minimal representation of the object (ignore nulls and empty collections)
# 
#         :rtype: str
#         """
#         if minimal:
#             return json.dumps(self.json_repr(minimal=True), cls=MarathonMinimalJsonEncoder, sort_keys=True)
#         else:
#             return json.dumps(self.json_repr(), cls=MarathonJsonEncoder, sort_keys=True)


# Path: marathon/models/container.py
from ..exceptions import InvalidChoiceError
from .base import MarathonObject

                pm, MarathonContainerPortMapping) else MarathonContainerPortMapping().from_json(pm)
            for pm in (port_mappings or [])
        ]
        self.parameters = parameters or []
        self.privileged = privileged or False
        self.force_pull_image = force_pull_image or False


class MarathonContainerPortMapping(MarathonObject):

    """Container port mapping.

    See https://mesosphere.github.io/marathon/docs/native-docker.html

    :param str name:
    :param int container_port:
    :param int host_port:
    :param str protocol:
    :param object labels:
    """

    PROTOCOLS = ['tcp', 'udp', 'udp,tcp']
    """Valid protocols"""

    def __init__(self, name=None, container_port=None, host_port=None, service_port=None, protocol='tcp', labels=None):
        self.name = name
        self.container_port = container_port
        self.host_port = host_port
        self.service_port = service_port
        if protocol not in self.PROTOCOLS:

            raise InvalidChoiceError('protocol', protocol, self.PROTOCOLS)