o
    FDi%#                     @  s   d Z ddlmZ ddlZddlZddlmZ ddlmZ ddl	m
Z
mZ ddlmZmZmZ dd	lmZ dd
lmZ dddZG dd deZdS )a
  marshmallow plugin for apispec. Allows passing a marshmallow
`Schema` to `spec.components.schema <apispec.core.Components.schema>`,
`spec.components.parameter <apispec.core.Components.parameter>`,
`spec.components.response <apispec.core.Components.response>`
(for response and headers schemas) and
`spec.path <apispec.APISpec.path>` (for responses and response headers).

Requires marshmallow>=3.13.0.

``MarshmallowPlugin`` maps marshmallow ``Field`` classes with OpenAPI types and
formats.

It inspects field attributes to automatically document properties
such as read/write-only, range and length constraints, etc.

OpenAPI properties can also be passed as metadata to the ``Field`` instance
if they can't be inferred from the field attributes (`description`,...), or to
override automatic documentation (`readOnly`,...). A metadata attribute is used
in the documentation either if it is a valid OpenAPI property, or if it starts
with `"x-"` (vendor extension).

.. warning::

    ``MarshmallowPlugin`` infers the ``default`` property from the
    ``load_default`` attribute of the ``Field`` (unless ``load_default`` is a
    callable). Since default values are entered in deserialized form,
    the value displayed in the doc is serialized by the ``Field`` instance.
    This may lead to inaccurate documentation in very specific cases.
    The default value to display in the documentation can be
    specified explicitly by passing ``default`` as field metadata.

::

    from pprint import pprint
    import datetime as dt

    from apispec import APISpec
    from apispec.ext.marshmallow import MarshmallowPlugin
    from marshmallow import Schema, fields

    spec = APISpec(
        title="Example App",
        version="1.0.0",
        openapi_version="3.0.2",
        plugins=[MarshmallowPlugin()],
    )


    class UserSchema(Schema):
        id = fields.Int(dump_only=True)
        name = fields.Str(metadata={"description": "The user's name"})
        created = fields.DateTime(
            dump_only=True,
            dump_default=dt.datetime.utcnow,
            metadata={"default": "The current datetime"},
        )


    spec.components.schema("User", schema=UserSchema)
    pprint(spec.to_dict()["components"]["schemas"])
    # {'User': {'properties': {'created': {'default': 'The current datetime',
    #                                      'format': 'date-time',
    #                                      'readOnly': True,
    #                                      'type': 'string'},
    #                          'id': {'readOnly': True,
    #                                 'type': 'integer'},
    #                          'name': {'description': "The user's name",
    #                                   'type': 'string'}},
    #           'type': 'object'}}

    )annotationsN)Schema)Version)APISpec
BasePlugin   )make_schema_keyresolve_schema_clsresolve_schema_instance)OpenAPIConverter)SchemaResolverschematype[Schema]returnstrc                 C  sF   t | }t|tr|d n|}|j}|dr|dd p|}| S )zZDefault schema name resolver function that strips 'Schema' from the end of the class name.r   r   Ni)r	   
isinstancelist__name__endswithstrip)r   resolved
schema_clsname r   Y/var/www/Datamplify/venv/lib/python3.10/site-packages/apispec/ext/marshmallow/__init__.pyresolverY   s   
r   c                      s   e Zd ZdZeZeZ	d%d& fddZd' fddZ	dd Z
d%ddZdd Zdd Zd(ddZ		d)d*dd Zd+d#d$Z  ZS ),MarshmallowPlugina  APISpec plugin for translating marshmallow schemas to OpenAPI/JSONSchema format.

    :param callable schema_name_resolver: Callable to generate the schema definition name.
        Receives the `Schema` class and returns the name to be used in refs within
        the generated spec. When working with circular referencing this function
        must must not return `None` for schemas in a circular reference chain.

        Example: ::

            from apispec.ext.marshmallow.common import resolve_schema_cls


            def schema_name_resolver(schema):
                schema_cls = resolve_schema_cls(schema)
                return schema_cls.__name__
    Nschema_name_resolver+typing.Callable[[type[Schema]], str] | Noner   Nonec                   s0   t    |pt| _d | _d | _d | _d | _d S N)super__init__r   r   specopenapi_version	converter)selfr   	__class__r   r   r"   x   s   


zMarshmallowPlugin.__init__r#   r   c                   sH   t  | || _|j| _| j|j| j|d| _| j|j| jd| _d S )N)r$   r   r#   )r$   r%   )	r!   	init_specr#   r$   	Converterr   r%   Resolverr   )r&   r#   r'   r   r   r)      s   zMarshmallowPlugin.init_specc                 G  s&   | j dus	J d| j j|g|R  S )a|  Set mapping for custom field class.

        :param type field_cls: Field class to set mapping for.

        ``*args`` can be:

        - a pair of the form ``(type, format)``
        - a core marshmallow field type (in which case we reuse that type's mapping)

        Examples: ::

            # Override Integer mapping
            class Int32(Integer):
                # ...

            ma_plugin.map_to_openapi_type(Int32, 'string', 'int32')

            # Map to ('integer', None) like Integer
            class IntegerLike(Integer):
                # ...

            ma_plugin.map_to_openapi_type(IntegerLike, Integer)
        N!init_spec has not yet been called)r%   map_to_openapi_type)r&   	field_clsargsr   r   r   r-      s   z%MarshmallowPlugin.map_to_openapi_typec                 K  sT   |du rdS t |}t|}| | | jdusJ d|| jj|< | j|}|S )zDefinition helper that allows using a marshmallow
        :class:`Schema <marshmallow.Schema>` to provide OpenAPI
        metadata.

        :param type|Schema schema: A marshmallow Schema class or instance.
        Nr,   )r
   r   warn_if_schema_already_in_specr%   refsschema2jsonschema)r&   r   _r   kwargsschema_instance
schema_keyjson_schemar   r   r   schema_helper   s   
zMarshmallowPlugin.schema_helperc                 K  "   | j dus	J d| j | |S )zParameter component helper that allows using a marshmallow
        :class:`Schema <marshmallow.Schema>` in parameter definition.

        :param dict parameter: parameter fields. May contain a marshmallow
            Schema class or instance.
        Nr,   r   resolve_schema)r&   	parameterr4   r   r   r   parameter_helper      z"MarshmallowPlugin.parameter_helperc                 K  r9   )zResponse component helper that allows using a marshmallow
        :class:`Schema <marshmallow.Schema>` in response definition.

        :param dict parameter: response fields. May contain a marshmallow
            Schema class or instance.
        Nr,   )r   resolve_response)r&   responser4   r   r   r   response_helper   r>   z!MarshmallowPlugin.response_helperheaderdictr4   
typing.Anyc                 K  s   | j sJ | j | |S )zHeader component helper that allows using a marshmallow
        :class:`Schema <marshmallow.Schema>` in header definition.

        :param dict header: header fields. May contain a marshmallow
            Schema class or instance.
        r:   )r&   rB   r4   r   r   r   header_helper   s   
zMarshmallowPlugin.header_helperpath
str | None
operationsdict | Nonec                 K  s   | j sJ | j | d S r    )r   resolve_operations)r&   rF   rH   r4   r   r   r   operation_helper   s   
z"MarshmallowPlugin.operation_helperr6   tuplec                 C  s8   | j sJ || j jv rtj|d  dtdd dS dS )zZMethod to warn the user if the schema has already been added to the
        spec.
        r   zb has already been added to the spec. Adding it twice may cause references to not resolve properly.   )
stacklevelN)r%   r1   warningswarnUserWarning)r&   r6   r   r   r   r0      s   

z0MarshmallowPlugin.warn_if_schema_already_in_specr    )r   r   r   r   )r#   r   r   r   )rB   rC   r4   rD   )NN)rF   rG   rH   rI   r4   rD   r   r   )r6   rL   r   r   )r   
__module____qualname____doc__r   r*   r   r+   r"   r)   r-   r8   r=   rA   rE   rK   r0   __classcell__r   r   r'   r   r   c   s     

	r   )r   r   r   r   )rT   
__future__r   typingrO   marshmallowr   packaging.versionr   apispecr   r   commonr   r	   r
   openapir   schema_resolverr   r   r   r   r   r   r   <module>   s    I

