
    h%#                        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Z G d de      Zy)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)SchemaResolverc                    t        |       }t        |t              r|d   n|}|j                  }|j	                  d      r	|dd xs |}|j                         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)schemaresolved
schema_clsnames       Z/var/www/html/engine/venv/lib/python3.12/site-packages/apispec/ext/marshmallow/__init__.pyresolverr   Y   sS    !&)H *8T :!JD}}XCRy D::<    c                       e Zd ZdZeZeZ	 d	 	 	 d fdZd fdZ	d Z
ddZd Zd ZddZ	 	 d	 	 	 	 	 	 	 dd	Zdd
Z x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__
    c                x    t         |           |xs t        | _        d | _        d | _        d | _        d | _        y N)super__init__r   schema_name_resolverspecopenapi_version	converter)selfr!   	__class__s     r   r    zMarshmallowPlugin.__init__x   s:     	$8$DH!$(	/326/3r   c                   t         |   |       || _        |j                  | _        | j	                  |j                  | j
                  |      | _        | j                  |j                  | j                        | _        y )N)r#   r!   r"   )r#   r$   )	r   	init_specr"   r#   	Converterr!   r$   Resolverr   )r%   r"   r&   s     r   r(   zMarshmallowPlugin.init_spec   su    $	#33 00!%!:!: ( 

  00DNN & 
r   c                b    | j                   J d        | j                   j                  |g| 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)
        !init_spec has not yet been called)r$   map_to_openapi_type)r%   	field_clsargss      r   r-   z%MarshmallowPlugin.map_to_openapi_type   s6    0 ~~)N+NN)1t~~11)CdCCr   c                    |yt        |      }t        |      }| j                  |       | j                  J d       || j                  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_schemas           r   schema_helperzMarshmallowPlugin.schema_helper   sr     >1&9$_5
++J7~~)N+NN)*.J'nn66Gr   c                b    | j                   J d       | j                   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.
        r,   r   resolve_schema)r%   	parameterr5   s      r   parameter_helperz"MarshmallowPlugin.parameter_helper   s2     }}(M*MM($$Y/r   c                b    | j                   J d       | j                   j                  |       |S )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.
        r,   )r   resolve_response)r%   responser5   s      r   response_helperz!MarshmallowPlugin.response_helper   s1     }}(M*MM(&&x0r   c                X    | j                   sJ | 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%   headerr5   s      r   header_helperzMarshmallowPlugin.header_helper   s'     }}}$$V,r   c                V    | j                   sJ | j                   j                  |       y r   )r   resolve_operations)r%   path
operationsr5   s       r   operation_helperz"MarshmallowPlugin.operation_helper   s"     }}}((4r   c                    | j                   sJ || j                   j                  v r#t        j                  |d    dt        d       yy)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$   r2   warningswarnUserWarning)r%   r7   s     r   r1   z0MarshmallowPlugin.warn_if_schema_already_in_spec   sL     ~~~,,,MMa=/ "< <	 -r   r   )r!   z+typing.Callable[[type[Schema]], str] | NonereturnNone)r"   r   rQ   rR   )rD   dictr5   
typing.Any)NN)rH   z
str | NonerI   zdict | Noner5   rT   rQ   rR   )r7   tuplerQ   rR   )r   
__module____qualname____doc__r   r)   r   r*   r    r(   r-   r9   r>   rB   rE   rJ   r1   __classcell__)r&   s   @r   r   r   c   s    " !IH MQ	4I	4 
	4
D6*			  "&55  5 	5
 
5r   r   )r   ztype[Schema]rQ   str)rX   
__future__r   typingrN   marshmallowr   packaging.versionr   apispecr   r   commonr	   r
   r   openapir   schema_resolverr   r   r    r   r   <module>rd      s?   FR #    % ' P P % +R
 Rr   