Source code for aiohttp_tus.tus

import json
from pathlib import Path

from aiohttp import web

from . import views
from .annotations import Decorator, Handler, JsonDumps, JsonLoads
from .constants import APP_TUS_CONFIG_KEY
from .data import Config, get_resource_url, ResourceCallback, set_config


[docs]def setup_tus( app: web.Application, *, upload_path: Path, upload_url: str = "/uploads", upload_resource_name: str = None, allow_overwrite_files: bool = False, decorator: Decorator = None, on_upload_done: ResourceCallback = None, json_dumps: JsonDumps = json.dumps, json_loads: JsonLoads = json.loads, ) -> web.Application: """Setup tus protocol server implementation for aiohttp.web application. It is a cornerstone of ``aiohttp-tus`` library and in most cases only thing developers need to know for setting up tus.io server for aiohttp.web application. :param app: :class:`aiohttp.web.Application` instance :param upload_path: :class:`pathlib.Path` instance to point the directory where to store uploaded files. Please, esnure that given directory is exists before application start and is writeable for current user. It is possible to prepend any ``match_info`` param from named URL. :param upload_url: tus.io upload URL. Can be plain as ``/uploads`` or named as ``/users/{username}/uploads``. By default: ``"/uploads"`` :param upload_resource_name: By default ``aiohttp-tus`` will provide auto name for the upload resource, as well as for the chunk resource. But sometimes it might be useful to provide exact name, which can lately be used for URL reversing. :param allow_overwrite_files: When enabled allow to overwrite already uploaded files. This may harm consistency of stored data, cause please use this param with caution. By default: ``False`` :param decorator: In case of guarding upload views it might be useful to decorate them with given decorator function. By default: ``None`` (which means **ANY** client will able to upload files) :param on_upload_done: Coroutine to call after upload is done. Coroutine will receive three arguments: ``request``, ``resource`` & ``file_path``. Request is current :class:`aiohttp.web.Request` instance. Resource will contain all data about uploaded resource such as file name, file size (:class:`aiohttp_tus.data.Resource` instance). While file path will contain :class:`pathlib.Path` instance of uploaded file. :param json_dumps: To store resource metadata between chunk uploads ``aiohttp-tus`` using JSON files, stored into ``upload_path / ".metadata"`` directory. To dump the data builtin Python function used: :func:`json.dumps`, but you might customize things if interested in using ``ujson``, ``orjson``, ``rapidjson`` or other implementation. :param json_loads: Similarly to ``json_dumps``, but for loading data from JSON metadata files. By default: :func:`json.loads` """ def decorate(handler: Handler) -> Handler: if decorator is None: return handler return decorator(handler) # Ensure support of multiple tus upload URLs for one application app.setdefault(APP_TUS_CONFIG_KEY, {}) # Need to find out canonical dynamic resource URL if any and use it for storing # tus config into the app canonical_upload_url = web.DynamicResource(upload_url).canonical # Store tus config in application config = Config( upload_path=upload_path, upload_url=upload_url, upload_resource_name=upload_resource_name, allow_overwrite_files=allow_overwrite_files, on_upload_done=on_upload_done, json_dumps=json_dumps, json_loads=json_loads, ) set_config(app, canonical_upload_url, config) # Views for upload management upload_resource = app.router.add_resource( upload_url, name=config.resource_tus_upload_name ) upload_resource.add_route("OPTIONS", views.upload_options) upload_resource.add_route("GET", decorate(views.upload_details)) upload_resource.add_route("POST", decorate(views.start_upload)) # Views for resource management resource_resource = app.router.add_resource( get_resource_url(upload_url), name=config.resource_tus_resource_name ) resource_resource.add_route("HEAD", decorate(views.resource_details)) resource_resource.add_route("DELETE", decorate(views.delete_resource)) resource_resource.add_route("PATCH", decorate(views.upload_resource)) return app