Commit 06ead1f6 authored by Mickaël Desfrênes's avatar Mickaël Desfrênes
Browse files

Add pydantic to rpc methods. Move RPC logging to wen context.

parent d43f1dee
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -9,3 +9,4 @@ python-dotenv
unidecode
django-ranged-fileresponse
pyvips
pydantic
 No newline at end of file
+0 −75
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ import pyvips
import tempfile
from resources.helpers import handle_local_file as _handle_local_file


logger = logging.getLogger(__name__)


@@ -160,7 +159,6 @@ def _user_has_permission(
# ALL RPC functions receive a User instance as first argument


@_log_call
@_rpc_groups(["Utilities"])
def ping(user: User) -> str:
    """
@@ -176,7 +174,6 @@ def ping(user: User) -> str:
    return "pong {}".format(user.username)


@_log_call
@_rpc_groups(["Metadatas"])
def metadatasets(user: User, project_id: int) -> List[Dict]:
    """
@@ -208,7 +205,6 @@ def metadatasets(user: User, project_id: int) -> List[Dict]:
        raise ServiceException(NO_SUCH_PROJECT)


@_log_call
@_rpc_groups(["Metadatas"])
def metadatas(user: User, metadata_set_id: int) -> List[Dict]:
    """
@@ -253,7 +249,6 @@ def metadatas(user: User, metadata_set_id: int) -> List[Dict]:
    return data


@_log_call
@_rpc_groups(["Metadatas"])
def metadata(user: User, metadata_id: int) -> Dict:
    """
@@ -283,7 +278,6 @@ def metadata(user: User, metadata_id: int) -> Dict:
    return serializers.metadata(metadata_instance, cache=SerializerCache())


@_log_call
@_rpc_groups(["Collections"])
def collections(
    user: User,
@@ -388,7 +382,6 @@ def collections(
    return data


@_log_call
@_rpc_groups(["Collections"])
def collection(user: User, collection_id: int) -> Dict:
    """
@@ -427,7 +420,6 @@ def collection(user: User, collection_id: int) -> Dict:
    )


@_log_call
@_rpc_groups(["Collections"])
def add_collection(user: User, title: str, parent_id: int) -> Dict:
    """
@@ -477,7 +469,6 @@ def add_collection(user: User, title: str, parent_id: int) -> Dict:
    return serializers.collection(collection_instance, cache=SerializerCache())


@_log_call
@_rpc_groups(["Collections"])
def add_collection_from_path(user: User, path: str, project_id: int) -> List[Dict]:
    """
@@ -565,7 +556,6 @@ def add_collection_from_path(user: User, path: str, project_id: int) -> List[Dic
    return hierarchy


@_log_call
@_rpc_groups(["Metadatas"])
def delete_metadata(user: User, metadata_id: int) -> bool:
    """
@@ -583,7 +573,6 @@ def delete_metadata(user: User, metadata_id: int) -> bool:
        raise ServiceException(NO_SUCH_METADATA)


@_log_call
@_rpc_groups(["Metadatas"])
def delete_metadataset(
    user: User, metadataset_id: int, recursive: bool = False
@@ -622,7 +611,6 @@ def delete_metadataset(
        }


@_log_call
@_rpc_groups(["Collections"])
def delete_collection(user: User, collection_id: int, recursive: bool = False) -> Dict:
    """
@@ -668,7 +656,6 @@ def delete_collection(user: User, collection_id: int, recursive: bool = False) -
    return {"success": True, "status": "all good"}


@_log_call
@_rpc_groups(["Collections"])
def rename_collection(user: User, collection_id: int, title: str) -> bool:
    """
@@ -686,7 +673,6 @@ def rename_collection(user: User, collection_id: int, title: str) -> bool:
    return True


@_log_call
@_rpc_groups(["Resources"])
def rename_resource(user: User, resource_id: int, title: str) -> bool:
    """
@@ -704,7 +690,6 @@ def rename_resource(user: User, resource_id: int, title: str) -> bool:
    return True


@_log_call
@_rpc_groups(["Metadatas"])
def rename_meta(user: User, meta_id: int, title: str) -> bool:
    """
@@ -720,7 +705,6 @@ def rename_meta(user: User, meta_id: int, title: str) -> bool:
    return True


@_log_call
@_rpc_groups(["Resources"])
def resources(
    user: User,
@@ -808,7 +792,6 @@ def resources(
    return data


@_log_call
@_rpc_groups(["Resources"])
def resource(user: User, resource_id: int) -> Dict:
    """
@@ -846,7 +829,6 @@ def resource(user: User, resource_id: int) -> Dict:
    return serializers.resource(resource_instance, cache=SerializerCache())


@_log_call
@_rpc_groups(["Resources", "Collections"])
def add_resource_to_collection(
    user: User, resource_id: int, collection_id: int
@@ -877,7 +859,6 @@ def add_resource_to_collection(
        raise ServiceException(NO_SUCH_RESOURCE)


@_log_call
@_rpc_groups(["Resources", "Collections"])
def remove_resource_from_collection(
    user: User, resource_id: int, collection_id: int
@@ -908,7 +889,6 @@ def remove_resource_from_collection(
        raise ServiceException(NO_SUCH_RESOURCE)


@_log_call
@_rpc_groups(["Resources"])
def delete_resource(user: User, resource_id: int) -> bool:
    """
@@ -930,7 +910,6 @@ def delete_resource(user: User, resource_id: int) -> bool:
    return True


@_log_call
@_rpc_groups(["Search"])
def simple_search(
    user: User,
@@ -1028,7 +1007,6 @@ def simple_search(
    return results


@_log_call
@_rpc_groups(["Search"])
def advanced_search_terms(user: User) -> List[str]:
    """
@@ -1047,7 +1025,6 @@ def advanced_search_terms(user: User) -> List[str]:
    return ["is", "contains", "does_not_contain"]


@_log_call
@_rpc_groups(["Search"])
def advanced_search(
    user: User,
@@ -1254,7 +1231,6 @@ def advanced_search(
    return results


@_log_call
@_rpc_groups(["Search", "Collections", "Resources"])
def project_items(
    user: User,
@@ -1281,7 +1257,6 @@ def project_items(
    )


@_log_call
@_rpc_groups(["Utilities"])
def upload_infos(user: User, sha256_hash: str, project_id: int) -> Dict:
    """
@@ -1321,7 +1296,6 @@ def upload_infos(user: User, sha256_hash: str, project_id: int) -> Dict:
    return infos


@_log_call
@_rpc_groups(["Utilities"])
def supported_file_types(user: User) -> List[Dict]:
    """
@@ -1346,7 +1320,6 @@ def supported_file_types(user: User) -> List[Dict]:
    return ftypes


@_log_call
@_rpc_groups(["Metadatas"])
def add_metadataset(user: User, title: str, project_id: int) -> int:
    """
@@ -1360,7 +1333,6 @@ def add_metadataset(user: User, title: str, project_id: int) -> int:
    return metadataset_instance.id


@_log_call
@_rpc_groups(["Metadatas"])
def add_metadata(
    user: User, title: str, metas_set_id: int, metadata_type_id: int = None
@@ -1393,7 +1365,6 @@ def add_metadata(
        raise ServiceException(NO_SUCH_METADATATYPE)


@_log_call
@_rpc_groups(["Metadatas", "Resources"])
def remove_meta_from_resource(user: User, resource_id: int, meta_value_id: int) -> bool:
    """
@@ -1414,7 +1385,6 @@ def remove_meta_from_resource(user: User, resource_id: int, meta_value_id: int)
    return False


@_log_call
@_rpc_groups(["Metadatas", "Resources"])
def set_metas_to_resource(user: User, resource_id: int, metas: List[dict]) -> bool:
    """
@@ -1455,7 +1425,6 @@ def set_metas_to_resource(user: User, resource_id: int, metas: List[dict]) -> bo
    return True


@_log_call
@_rpc_groups(["Metadatas", "Collections"])
def set_metas_to_collection(
    user: User, collection_id: int, metas: List[dict], cascade: bool = False
@@ -1509,7 +1478,6 @@ def set_metas_to_collection(
    return True


@_log_call
@_rpc_groups(["Metadatas", "Resources"])
def add_meta_to_resource(
    user: User, resource_id: int, meta_id: int, meta_value: str
@@ -1552,7 +1520,6 @@ def add_meta_to_resource(
        raise ServiceException(NO_SUCH_METADATA)


@_log_call
@_rpc_groups(["Deprecated"])
def remove_meta_from_collection(
    user: User, collection_id: int, meta_value_id: int
@@ -1574,7 +1541,6 @@ def remove_meta_from_collection(
    return False


@_log_call
@_rpc_groups(["Metadatas", "Collections"])
def remove_meta_value_from_collection(
    user: User, collection_id: int, meta_value_id: int
@@ -1585,7 +1551,6 @@ def remove_meta_value_from_collection(
    return remove_meta_from_collection(user, collection_id, meta_value_id)


@_log_call
@_rpc_groups(["Metadatas", "Collections"])
def add_meta_to_collection(
    user: User, collection_id: int, meta_id: int, meta_value: str, cascade: bool = False
@@ -1638,7 +1603,6 @@ def add_meta_to_collection(
        raise ServiceException(NO_SUCH_METADATA)


@_log_call
@_rpc_groups(["Metadatas", "Collections"])
def change_collection_meta_value(
    user: User, meta_value_id: int, meta_value: str
@@ -1658,7 +1622,6 @@ def change_collection_meta_value(
        return False


@_log_call
@_rpc_groups(["Metadatas", "Resources"])
def change_resource_meta_value(user: User, meta_value_id: int, meta_value: str) -> bool:
    """
@@ -1676,7 +1639,6 @@ def change_resource_meta_value(user: User, meta_value_id: int, meta_value: str)
        return False


@_log_call
@_rpc_groups(["Collections"])
def ancestors_from_collection(
    user: User, collection_id: int, include_self: bool = False
@@ -1771,7 +1733,6 @@ def ancestors_from_collection(
    return breadcrumb


@_log_call
@_rpc_groups(["Collections", "Resources"])
def ancestors_from_resource(user: User, resource_id: int) -> List[List[dict]]:
    """
@@ -1845,7 +1806,6 @@ def ancestors_from_resource(user: User, resource_id: int) -> List[List[dict]]:
    return ancestors


@_log_call
@_rpc_groups(["Metadatas"])
def metadatatypes(user: User) -> List[dict]:
    """
@@ -1867,7 +1827,6 @@ def metadatatypes(user: User) -> List[dict]:
    return types


@_log_call
@_rpc_groups(["Collections"])
def publish_collection(user: User, collection_id: int) -> bool:
    """
@@ -1885,7 +1844,6 @@ def publish_collection(user: User, collection_id: int) -> bool:
    return True


@_log_call
@_rpc_groups(["Collections"])
def unpublish_collection(user: User, collection_id: int) -> bool:
    """
@@ -1903,7 +1861,6 @@ def unpublish_collection(user: User, collection_id: int) -> bool:
    return True


@_log_call
@_rpc_groups(["Collections"])
def move_collection(
    user: User, child_collection_id: int, parent_collection_id: int
@@ -1947,7 +1904,6 @@ def move_collection(
    return True


@_log_call
@_rpc_groups(["Tags"])
def set_tag(
    user: User, uid: str, project_id: int, label: str = None, ark: str = None
@@ -1975,7 +1931,6 @@ def set_tag(
    return serializers.tag(tag_instance, cache=SerializerCache())


@_log_call
@_rpc_groups(["Tags"])
def delete_tag(user: User, uid: str) -> bool:
    """
@@ -1992,7 +1947,6 @@ def delete_tag(user: User, uid: str) -> bool:
        raise ServiceException(NO_SUCH_TAG)


@_log_call
@_rpc_groups(["Tags"])
def tags(user: User, project_id: int) -> List[dict]:
    """
@@ -2026,7 +1980,6 @@ def tags(user: User, project_id: int) -> List[dict]:
    return tags_list


@_log_call
@_rpc_groups(["Tags", "Collections"])
def add_tag_to_collection(user: User, tag_uid: str, collection_id: int) -> bool:
    """
@@ -2047,7 +2000,6 @@ def add_tag_to_collection(user: User, tag_uid: str, collection_id: int) -> bool:
        raise ServiceException(NO_SUCH_TAG)


@_log_call
@_rpc_groups(["Tags", "Collections"])
def remove_tag_from_collection(user: User, tag_uid: str, collection_id: int) -> bool:
    """
@@ -2068,7 +2020,6 @@ def remove_tag_from_collection(user: User, tag_uid: str, collection_id: int) ->
        raise ServiceException(NO_SUCH_TAG)


@_log_call
@_rpc_groups(["Tags", "Resources"])
def add_tag_to_resource(user: User, tag_uid: str, resource_id: int) -> bool:
    """
@@ -2089,7 +2040,6 @@ def add_tag_to_resource(user: User, tag_uid: str, resource_id: int) -> bool:
        raise ServiceException(NO_SUCH_TAG)


@_log_call
@_rpc_groups(["Tags", "Resources"])
def remove_tag_from_resource(user: User, tag_uid: str, resource_id: int) -> bool:
    """
@@ -2110,7 +2060,6 @@ def remove_tag_from_resource(user: User, tag_uid: str, resource_id: int) -> bool
        raise ServiceException(NO_SUCH_TAG)


@_log_call
@_rpc_groups(["Collections", "Resources"])
def set_representative_resource(
    user: User, collection_id: int, resource_id: int = None
@@ -2152,7 +2101,6 @@ def set_representative_resource(
        raise ServiceException(NO_SUCH_RESOURCE)


@_log_call
@_rpc_groups(["Utilities", "Resources"])
def replace_file(user: User, from_resource_id: int, to_resource_id: int) -> bool:
    """
@@ -2220,7 +2168,6 @@ def replace_file(user: User, from_resource_id: int, to_resource_id: int) -> bool
        raise ServiceException(NO_SUCH_RESOURCE)


@_log_call
@_rpc_groups(["Collections"])
def set_is_oai_record(
    user: User, collection_id: int, is_oai_record: bool = True
@@ -2242,7 +2189,6 @@ def set_is_oai_record(
        raise ServiceException(NO_SUCH_COLLECTION)


@_log_call
@_rpc_groups(["Access"])
@_require_superuser
def activate_rpc_access(user: User, user_name: str, api_key: str) -> bool:
@@ -2259,7 +2205,6 @@ def activate_rpc_access(user: User, user_name: str, api_key: str) -> bool:
    return True


@_log_call
@_rpc_groups(["Access"])
@_require_superuser
def deactivate_rpc_access(user: User, user_name: str, api_key: str) -> bool:
@@ -2281,7 +2226,6 @@ def deactivate_rpc_access(user: User, user_name: str, api_key: str) -> bool:
        raise ServiceException(NO_SUCH_USER)


@_log_call
@_rpc_groups(["Access"])
@_require_superuser
def create_project(user: User, project_label: str, project_description: str) -> dict:
@@ -2296,7 +2240,6 @@ def create_project(user: User, project_label: str, project_description: str) ->
    return serializers.project(project, cache=SerializerCache())


@_log_call
@_rpc_groups(["Access"])
def list_permissions(user: User) -> List[Dict]:
    """
@@ -2339,7 +2282,6 @@ def list_permissions(user: User) -> List[Dict]:
    return data


@_log_call
@_rpc_groups(["Access"])
def projects_user_permissions(user: User) -> List[Dict]:
    """
@@ -2366,7 +2308,6 @@ def projects_user_permissions(user: User) -> List[Dict]:
    return access_list


@_log_call
@_rpc_groups(["Access"])
def has_permission(user: User, project_id: int, permission: str) -> bool:
    """
@@ -2380,7 +2321,6 @@ def has_permission(user: User, project_id: int, permission: str) -> bool:
    return False


@_log_call
@_rpc_groups(["Access"])
def list_roles(user: User, project_id: int) -> List[Dict]:
    """
@@ -2394,7 +2334,6 @@ def list_roles(user: User, project_id: int) -> List[Dict]:
    return data


@_log_call
@_rpc_groups(["Access"])
@_require_superuser
def set_role(
@@ -2419,7 +2358,6 @@ def set_role(
    return serializers.role(role, cache=SerializerCache())


@_log_call
@_require_superuser
@_rpc_groups(["Access"])
def delete_role(user: User, project_id: int, role_label: str) -> bool:
@@ -2432,7 +2370,6 @@ def delete_role(user: User, project_id: int, role_label: str) -> bool:
    return True


@_log_call
@_rpc_groups(["Collections", "Resources"])
def move_items(
    user: User,
@@ -2461,7 +2398,6 @@ def move_items(
    return results


@_log_call
@_rpc_groups(["Projects"])
def project_stats(user: User, project_id: int) -> dict:
    """
@@ -2503,7 +2439,6 @@ def project_stats(user: User, project_id: int) -> dict:
        raise ServiceException(NO_SUCH_PROJECT)


@_log_call
@_rpc_groups(["Collections", "Resources"])
def collection_stats(user: User, collection_id: int) -> dict:
    """
@@ -2532,7 +2467,6 @@ def collection_stats(user: User, collection_id: int) -> dict:
    }


@_log_call
@_rpc_groups(["Utilities", "Collections", "Resources"])
def recycle_bin(user: User, project_id: int) -> List[Dict]:
    """
@@ -2571,7 +2505,6 @@ def recycle_bin(user: User, project_id: int) -> List[Dict]:
    return results


@_log_call
@_rpc_groups(["Resources"])
def restore_resource(
    user: User, resource_id: int, destination_collection_id: int
@@ -2603,7 +2536,6 @@ def restore_resource(
    return True


@_log_call
@_rpc_groups(["Collections"])
def restore_collection(
    user: User, collection_id: int, destination_collection_id: int
@@ -2628,7 +2560,6 @@ def restore_collection(
    return True


@_log_call
@_rpc_groups(["Metadatas"])
def meta_count(user: User, metadata_id: int, collection_id: int) -> dict:
    """
@@ -2662,7 +2593,6 @@ def meta_count(user: User, metadata_id: int, collection_id: int) -> dict:
    return return_dict


@_log_call
@_rpc_groups(["Collections"])
def public_collections(user: User, project_id: int) -> List[dict]:
    """
@@ -2676,7 +2606,6 @@ def public_collections(user: User, project_id: int) -> List[dict]:
    return data


@_log_call
@_rpc_groups(["Projects"])
def set_project_property(
    user: User, project_id: int, property_key: str, property_value: dict
@@ -2699,7 +2628,6 @@ def set_project_property(
    return serializers.project_property(prop)


@_log_call
@_rpc_groups(["Projects"])
def delete_project_property(user: User, project_id: int, property_key: str) -> bool:
    """
@@ -2722,7 +2650,6 @@ def delete_project_property(user: User, project_id: int, property_key: str) -> b
    raise ServiceException(NO_SUCH_PROJECT_PROPERTY)


@_log_call
@_rpc_groups(["Projects"])
def project_property(user: User, project_id: int, property_key: str) -> dict:
    """
@@ -2746,7 +2673,6 @@ def project_property(user: User, project_id: int, property_key: str) -> dict:
    raise ServiceException(NO_SUCH_PROJECT_PROPERTY)


@_log_call
@_rpc_groups(["Projects"])
def project_properties(user: User, project_id: int) -> List[dict]:
    """
@@ -2759,7 +2685,6 @@ def project_properties(user: User, project_id: int) -> List[dict]:
    return data


@_log_call
@_rpc_groups(["Resources"])
def picture_rotate_crop(
    user: User,
+21 −2
Original line number Diff line number Diff line
@@ -31,6 +31,12 @@ from .fileresponse import RangedFileResponse
from django.views.decorators.gzip import gzip_page
import logging
from functools import lru_cache
import pydantic
from pydantic import validate_arguments


validate_arguments = validate_arguments(config=dict(arbitrary_types_allowed=True))


importlib = __import__("importlib")

@@ -165,14 +171,18 @@ def _get_rpc_methods() -> dict:
    for fn_name, _ in getmembers(rpc_methods, isfunction):
        if fn_name[0:1] == "_":
            continue
        methods[fn_name] = getattr(rpc_methods, fn_name)
        methods[fn_name] = rpc_methods._log_call(
            validate_arguments(getattr(rpc_methods, fn_name))
        )
    for app_name in settings.AUTO_REGISTER_APPS:
        try:
            rpc_module = importlib.import_module("{}.rpc.methods".format(app_name))
            for fn_name, _ in getmembers(rpc_module, isfunction):
                if fn_name[0:1] == "_":
                    continue
                methods[fn_name] = getattr(rpc_module, fn_name)
                methods[fn_name] = rpc_methods._log_call(
                    validate_arguments(getattr(rpc_module, fn_name))
                )
        except ModuleNotFoundError:
            continue
    return methods
@@ -201,6 +211,15 @@ def rpc(request: HttpRequest) -> HttpResponse:
        result = methods[method](*params)
        _debug_sql()
        return JsonResponse({"result": result, "error": None, "id": req_id})
    except pydantic.ValidationError as e:
        logger.warning("Pydantic validation error")
        return JsonResponse(
            {
                "result": None,
                "error": {"message": "type errors", "details": e.errors()},
                "id": req_id,
            }
        )
    except json.JSONDecodeError:
        logger.warning("could not decode json request")
        return HttpResponse("Bad Request", status=400)