+
    Bi$                     r    R t ^ RIt^ RIt^ RIt^ RIt^ RIHtHt ^ RI	H
t
 R tR tR tR t ! R R	4      tR# )
zServe GridFS files with Motor and aiohttp.

Requires Python 3.5 or later and aiohttp 3.0 or later.

See the :doc:`/examples/aiohttp_gridfs_example`.
N)AsyncIOMotorDatabaseAsyncIOMotorGridFSBucket)_hash_gridoutc                $    V P                  V4      # )a  Override to choose a GridFS file to serve at a URL.

By default, if a URL pattern like ``/fs/{filename}`` is mapped to this
:class:`AIOHTTPGridFS`, then the filename portion of the URL is used as the
filename, so a request for "/fs/image.png" results in a call to
:meth:`.AsyncIOMotorGridFSBucket.open_download_stream_by_name` with
"image.png" as the ``filename`` argument. To customize the mapping of path
to GridFS file, override ``get_gridfs_file`` and return a
:class:`asyncio.Future` that resolves to a
:class:`~motor.motor_asyncio.AsyncIOMotorGridOut`.

For example, to retrieve the file by ``_id`` instead of filename::

    def get_gridfile_by_id(bucket, filename, request):
        # "filename" is interpreted as _id instead of name.
        # Return a Future AsyncIOMotorGridOut.
        return bucket.open_download_stream(file_id=filename)

    client = AsyncIOMotorClient()
    gridfs_handler = AIOHTTPGridFS(client.my_database,
                                   get_gridfs_file=get_gridfile_by_id)

:Parameters:
  - `bucket`: An :class:`~motor.motor_asyncio.AsyncIOMotorGridFSBucket`
  - `filename`: A string, the URL portion matching {filename} in the URL
    pattern
  - `request`: An :class:`aiohttp.web.Request`
)open_download_stream_by_name)bucketfilenamerequests   &&&T/var/www/html/photoedit/myenv/lib/python3.14/site-packages/motor/aiohttp/__init__.pyget_gridfs_filer   "   s    < ..x88    c                    ^ # )a  Override to customize cache control behavior.

Return a positive number of seconds to trigger aggressive caching or 0
to mark resource as cacheable, only. 0 is the default.

For example, to allow image caching::

    def image_cache_time(filename, modified, mime_type):
        if mime_type.startswith('image/'):
            return 3600

        return 0

    client = AsyncIOMotorClient()
    gridfs_handler = AIOHTTPGridFS(client.my_database,
                                   get_cache_time=image_cache_time)

:Parameters:
  - `filename`: A string, the URL portion matching {filename} in the URL
    pattern
  - `modified`: A datetime, when the matching GridFS file was created
  - `mime_type`: The file's type, a string like "application/octet-stream"
 )r   modified	mime_types   &&&r
   get_cache_timer   C   s    0 r   c                    R# )a   Override to modify the response before sending to client.

For example, to allow image caching::

    def gzip_header(response, gridout):
        response.headers['Content-Encoding'] = 'gzip'

    client = AsyncIOMotorClient()
    gridfs_handler = AIOHTTPGridFS(client.my_database,
                                   set_extra_headers=gzip_header)

:Parameters:
  - `response`: An :class:`aiohttp.web.Response`
  - `gridout`: The :class:`~motor.motor_asyncio.AsyncIOMotorGridOut` we
    will serve to the client
Nr   )responsegridouts   &&r
   set_extra_headersr   ^   s    r   c                     V P                   P                  P                  P                  4       R ,          pRV,          p\        P                  P                  VR7      Rh  \        \
        3 d    RT ,          p L=i ; i)	formatterz<Bad AIOHTTPGridFS route "%s", requires a {filename} variablez'Bad AIOHTTPGridFS route for request: %stextN)	
match_inforouteresourceget_infoKeyErrorAttributeErroraiohttpwebHTTPInternalServerError)r	   r   msgs   &  r
   _config_errorr$   q   su    B&&,,55>>@M	LyX
 ++
-
-3
-
7TA	 n% B7'ABs   >A! !A>=A>c                   B   a  ] tR t^|t o RtR]]]3R ltR t	R t
RtV tR# )AIOHTTPGridFSa  Serve files from `GridFS`_.

This class is a :ref:`request handler <aiohttp-web-handler>` that serves
GridFS files, similar to aiohttp's built-in static file server.

.. code-block:: python

    client = AsyncIOMotorClient()
    gridfs_handler = AIOHTTPGridFS(client.my_database)

    app = aiohttp.web.Application()

    # The GridFS URL pattern must have a "{filename}" variable.
    resource = app.router.add_resource("/fs/{filename}")
    resource.add_route("GET", gridfs_handler)
    resource.add_route("HEAD", gridfs_handler)

    app_handler = app.make_handler()
    server = loop.create_server(app_handler, port=80)

By default, requests' If-Modified-Since headers are honored, but no
specific cache-control timeout is sent to clients. Thus each request for
a GridFS file requires a quick check of the file's ``uploadDate`` in
MongoDB. Pass a custom :func:`get_cache_time` to customize this.

:Parameters:
  - `database`: An :class:`AsyncIOMotorDatabase`
  - `get_gridfs_file`: Optional override for :func:`get_gridfs_file`
  - `get_cache_time`: Optional override for :func:`get_cache_time`
  - `set_extra_headers`: Optional override for :func:`set_extra_headers`

.. _GridFS: https://www.mongodb.com/docs/manual/core/gridfs/
fsc                    \        V\        4      '       g   \        R V,          4      hWn        \	        V P                  V4      V n        W0n        W@n        WPn        R# )zDFirst argument to AIOHTTPGridFS must be AsyncIOMotorDatabase, not %rN)	
isinstancer   	TypeError	_databaser   _bucket_get_gridfs_file_get_cache_time_set_extra_headers)selfdatabaseroot_collectionr   r   r   s   &&&&&&r
   __init__AIOHTTPGridFS.__init__   sS     ($899VYaa  "/P /-"3r   c                (  "    VP                   R,          pVP                  R9  d.   \        P
                  P                  VP                  RR0R7      h V P                  V P                  XV4      G Rj  xL
 p\        P
                  P                  4       p\        T4      pT P                  TP                  YST4       T P!                  YS4       TP"                  pTe\   TP%                  TP&                  P(                  R7      pTP&                  P%                  ^ R7      p	Y8  d   TP+                  R	4       T# TP,                  P/                  R
4      p
T
e*   T
P1                  R4      T8X  d   TP+                  R	4       T# TP2                  Tn        TP7                  T4      G Rj  xL
  TP                  R8X  dc   ^ pYP2                  8  dQ   TP9                  TP:                  4      G Rj  xL
 pTP=                  T4      G Rj  xL
  T\?        T4      ,          pK`  T#   \         d    \        T4        EL&i ; i EL  \        P                   d1   p\        P
                  P                  TP                  R7      ThRp?ii ; i L L L5i)z&Send filepath to client using request.r   GETHEAD)methodallowed_methodsNr   tzinfo)microsecondi0  zIf-None-Match")r6   r7   ) r   r   r$   r8   r    r!   HTTPMethodNotAllowedr-   r,   gridfsNoFileHTTPNotFoundpathStreamResponser   _set_standard_headersr/   if_modified_sincereplaceupload_dater;   
set_statusheadersgetstriplengthcontent_lengthprepareread
chunk_sizewritelen)r0   r	   r   r   erespchecksum	ims_valueif_sincer   etagwrittenchunks   &&           r
   __call__AIOHTTPGridFS.__call__   s/    	#))*5H >>0++22~~v 3  	E 11$,,'RRG {{))+ !)""7<<I 	. --	  !((0C0C0J0J(KH**22q2AH#$ ""?3

38 ;OOC K%nnll7###>>U"GNN*%ll7+=+=>>jj'''3u:%g  	#'"	# S}} 	E++***=1D	E@ 	$ ?'s   JH$ >J I 6I7I ;D/J*J+AJ0J1J	J
J$H>:J=H>>JI J	+JJ		JJJc                x   VP                   Vn        VP                  pVf   \        P                  ! V4      w  rVV'       d   WRn        RV,          VP
                  R&   V P                  WP                   VP                  4      pV^ 8  d   \        P                  P                  \        P                  P                  4      P                  R R7      \        P                  ! VR7      ,           P                  R4      VP
                  R&   R\        V4      ,           VP
                  R&   R # R	VP
                  R&   R # )
Nz"%s"Etagr:   )secondsz%a, %d %b %Y %H:%M:%S GMTExpireszmax-age=zCache-Controlpublic)rG   last_modifiedcontent_type	mimetypes
guess_typerI   r.   datetimenowtimezoneutcrF   	timedeltastrftimestr)r0   rB   rT   r   rU   rc   encoding
cache_times   &&&&&   r
   rD   #AIOHTTPGridFS._set_standard_headers   s    $00++%.%9%9$%?"L ,%0V ))$0C0CWEYEYZ
>!!%%h&7&7&;&;<DDDDQ$$Z89h23 LL#
 -7Z,HDLL),4DLL)r   )r,   r+   r.   r-   r/   N)__name__
__module____qualname____firstlineno____doc__r   r   r   r3   r[   rD   __static_attributes____classdictcell__)__classdict__s   @r
   r&   r&   |   s.      J '%+4&7r5 5r   r&   )rt   rf   rd   aiohttp.webr    r?   motor.motor_asyncior   r   motor.motor_gridfsr   r   r   r   r$   r&   r   r   r
   <module>r{      s@        N ,
9B6&BE5 E5r   