zou 0.19.51__py3-none-any.whl → 0.19.53__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. zou/__init__.py +1 -1
  2. zou/app/__init__.py +1 -1
  3. zou/app/blueprints/assets/__init__.py +22 -0
  4. zou/app/blueprints/assets/resources.py +240 -3
  5. zou/app/blueprints/auth/resources.py +26 -22
  6. zou/app/blueprints/chats/resources.py +2 -2
  7. zou/app/blueprints/crud/base.py +10 -6
  8. zou/app/blueprints/crud/day_off.py +3 -3
  9. zou/app/blueprints/crud/entity.py +3 -3
  10. zou/app/blueprints/crud/entity_type.py +15 -0
  11. zou/app/blueprints/crud/metadata_descriptor.py +16 -3
  12. zou/app/blueprints/crud/person.py +13 -15
  13. zou/app/blueprints/crud/preview_background_file.py +3 -3
  14. zou/app/blueprints/crud/project.py +5 -5
  15. zou/app/blueprints/crud/schedule_item.py +2 -2
  16. zou/app/blueprints/crud/task_type.py +3 -3
  17. zou/app/blueprints/persons/resources.py +2 -2
  18. zou/app/blueprints/previews/resources.py +31 -6
  19. zou/app/blueprints/projects/resources.py +1 -1
  20. zou/app/blueprints/shots/resources.py +2 -2
  21. zou/app/models/base.py +6 -1
  22. zou/app/models/entity.py +3 -5
  23. zou/app/services/assets_service.py +74 -1
  24. zou/app/services/breakdown_service.py +33 -3
  25. zou/app/services/deletion_service.py +5 -0
  26. zou/app/services/exception.py +1 -5
  27. zou/app/services/preview_files_service.py +2 -2
  28. zou/app/services/tasks_service.py +1 -1
  29. zou/app/services/time_spents_service.py +4 -4
  30. zou/app/swagger.py +15 -20
  31. zou/app/utils/query.py +53 -5
  32. zou/event_stream.py +1 -0
  33. zou/migrations/versions/59a7445a966c_add_entity_is_shared.py +41 -0
  34. {zou-0.19.51.dist-info → zou-0.19.53.dist-info}/METADATA +6 -6
  35. {zou-0.19.51.dist-info → zou-0.19.53.dist-info}/RECORD +39 -38
  36. {zou-0.19.51.dist-info → zou-0.19.53.dist-info}/WHEEL +1 -1
  37. {zou-0.19.51.dist-info → zou-0.19.53.dist-info}/LICENSE +0 -0
  38. {zou-0.19.51.dist-info → zou-0.19.53.dist-info}/entry_points.txt +0 -0
  39. {zou-0.19.51.dist-info → zou-0.19.53.dist-info}/top_level.txt +0 -0
zou/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.19.51"
1
+ __version__ = "0.19.53"
zou/app/__init__.py CHANGED
@@ -96,7 +96,7 @@ def id_parameter_format_error(error):
96
96
 
97
97
  @app.errorhandler(WrongParameterException)
98
98
  def wrong_parameter(error):
99
- return jsonify(error=True, message=str(error)), 400
99
+ return jsonify(error=True, message=str(error), data=error.dict), 400
100
100
 
101
101
 
102
102
  @app.errorhandler(ExpiredSignatureError)
@@ -21,6 +21,11 @@ from zou.app.blueprints.assets.resources import (
21
21
  ProjectAssetTypeAssetsResource,
22
22
  ProjectAssetTypesResource,
23
23
  ShotAssetTypesResource,
24
+ SetSharedProjectAssetsResource,
25
+ SetSharedProjectAssetTypeAssetsResource,
26
+ SetSharedAssetsResource,
27
+ ProjectAssetsSharedUsedResource,
28
+ ProjectEpisodeAssetsSharedUsedResource,
24
29
  )
25
30
 
26
31
 
@@ -59,6 +64,23 @@ routes = [
59
64
  ("/data/projects/<project_id>/asset-types", ProjectAssetTypesResource),
60
65
  ("/data/shots/<shot_id>/asset-types", ShotAssetTypesResource),
61
66
  ("/data/projects/<project_id>/assets", ProjectAssetsResource),
67
+ ("/actions/assets/share", SetSharedAssetsResource),
68
+ (
69
+ "/actions/projects/<project_id>/assets/share",
70
+ SetSharedProjectAssetsResource,
71
+ ),
72
+ (
73
+ "/actions/projects/<project_id>/asset-types/<asset_type_id>/assets/share",
74
+ SetSharedProjectAssetTypeAssetsResource,
75
+ ),
76
+ (
77
+ "/data/projects/<project_id>/assets/shared-used",
78
+ ProjectAssetsSharedUsedResource,
79
+ ),
80
+ (
81
+ "/data/projects/<project_id>/episodes/<episode_id>/assets/shared-used",
82
+ ProjectEpisodeAssetsSharedUsedResource,
83
+ ),
62
84
  ]
63
85
 
64
86
  blueprint = Blueprint("assets", "assets")
@@ -21,7 +21,11 @@ def check_criterion_access(criterions):
21
21
  elif "episode_id" in criterions:
22
22
  episode_id = criterions.get("episode_id", None)
23
23
  project_id = shots_service.get_episode(episode_id)["project_id"]
24
- return user_service.check_project_access(project_id)
24
+
25
+ if "project_id" in criterions:
26
+ user_service.check_project_access(project_id)
27
+
28
+ return True
25
29
 
26
30
 
27
31
  class AssetResource(Resource, ArgsMixin):
@@ -106,7 +110,10 @@ class AllAssetsResource(Resource):
106
110
  criterions["assigned_to"] = persons_service.get_current_user()[
107
111
  "id"
108
112
  ]
109
- return assets_service.get_assets(criterions)
113
+ return assets_service.get_assets(
114
+ criterions,
115
+ is_admin=permissions.has_admin_permissions(),
116
+ )
110
117
 
111
118
 
112
119
  class AllAssetsAliasResource(AllAssetsResource):
@@ -431,6 +438,7 @@ class NewAssetResource(Resource, ArgsMixin):
431
438
  - name
432
439
  - description
433
440
  - data
441
+ - is_shared
434
442
  - source_id
435
443
  properties:
436
444
  name:
@@ -439,6 +447,8 @@ class NewAssetResource(Resource, ArgsMixin):
439
447
  type: string
440
448
  data:
441
449
  type: string
450
+ is_shared:
451
+ type: boolean
442
452
  source_id:
443
453
  type: string
444
454
  format: UUID
@@ -447,7 +457,7 @@ class NewAssetResource(Resource, ArgsMixin):
447
457
  201:
448
458
  description: New asset resource created
449
459
  """
450
- (name, description, data, source_id) = self.get_arguments()
460
+ (name, description, data, is_shared, source_id) = self.get_arguments()
451
461
 
452
462
  user_service.check_manager_project_access(project_id)
453
463
  asset = assets_service.create_asset(
@@ -456,6 +466,7 @@ class NewAssetResource(Resource, ArgsMixin):
456
466
  name,
457
467
  description,
458
468
  data,
469
+ is_shared,
459
470
  source_id,
460
471
  created_by=persons_service.get_current_user()["id"],
461
472
  )
@@ -471,6 +482,12 @@ class NewAssetResource(Resource, ArgsMixin):
471
482
  },
472
483
  "description",
473
484
  ("data", {}, False, dict),
485
+ (
486
+ "is_shared",
487
+ True,
488
+ False,
489
+ bool,
490
+ ),
474
491
  "episode_id",
475
492
  ]
476
493
  )
@@ -479,6 +496,7 @@ class NewAssetResource(Resource, ArgsMixin):
479
496
  args["name"],
480
497
  args.get("description", ""),
481
498
  args["data"],
499
+ args["is_shared"],
482
500
  args["episode_id"],
483
501
  )
484
502
 
@@ -658,3 +676,222 @@ class AssetAssetInstancesResource(Resource, ArgsMixin):
658
676
  asset_id, args["asset_to_instantiate_id"], args["description"]
659
677
  )
660
678
  return asset_instance, 201
679
+
680
+
681
+ class BaseSetSharedAssetsResource(Resource, ArgsMixin):
682
+
683
+ @jwt_required()
684
+ def post(self, project_id=None, asset_type_id=None, asset_ids=None):
685
+ args = self.get_args(
686
+ [
687
+ (
688
+ "is_shared",
689
+ True,
690
+ False,
691
+ bool,
692
+ ),
693
+ ]
694
+ )
695
+ return assets_service.set_shared_assets(
696
+ is_shared=args["is_shared"],
697
+ project_id=project_id,
698
+ asset_type_id=asset_type_id,
699
+ asset_ids=asset_ids,
700
+ )
701
+
702
+
703
+ class SetSharedProjectAssetsResource(BaseSetSharedAssetsResource):
704
+ """
705
+ Share or unshare all assets (or a list of assets) for given project.
706
+ """
707
+
708
+ @jwt_required()
709
+ def post(self, project_id):
710
+ """
711
+ Share or unshare all assets (or a list of assets) for given project.
712
+ ---
713
+ tags:
714
+ - Assets
715
+ consumes:
716
+ - multipart/form-data
717
+ parameters:
718
+ - in: path
719
+ name: project_id
720
+ required: True
721
+ type: string
722
+ format: UUID
723
+ x-example: a24a6ea4-ce75-4665-a070-57453082c25
724
+ - in: formData
725
+ name: asset_ids
726
+ default: None,
727
+ type: array
728
+ items:
729
+ type: UUID
730
+ x-example: ["a24a6ea4-ce75-4665-a070-57453082c25"]
731
+ - in: formData
732
+ name: is_shared
733
+ default: true
734
+ type: boolean
735
+ x-example: true
736
+ responses:
737
+ 201:
738
+ description: All assets modified.
739
+ """
740
+ args = self.get_args(
741
+ [
742
+ (
743
+ "asset_ids",
744
+ None,
745
+ False,
746
+ str,
747
+ "append",
748
+ ),
749
+ ]
750
+ )
751
+ user_service.check_manager_project_access(project_id)
752
+ return super().post(project_id=project_id, asset_ids=args["asset_ids"])
753
+
754
+
755
+ class SetSharedProjectAssetTypeAssetsResource(BaseSetSharedAssetsResource):
756
+ """
757
+ Share or unshare all assets for given project and asset type.
758
+ """
759
+
760
+ @jwt_required()
761
+ def post(self, project_id, asset_type_id):
762
+ """
763
+ Share or unshare all assets for given project and asset type.
764
+ ---
765
+ tags:
766
+ - Assets
767
+ consumes:
768
+ - multipart/form-data
769
+ parameters:
770
+ - in: path
771
+ name: project_id
772
+ required: True
773
+ type: string
774
+ format: UUID
775
+ x-example: a24a6ea4-ce75-4665-a070-57453082c25
776
+ - in: path
777
+ name: asset_type_id
778
+ required: True
779
+ type: string
780
+ format: UUID
781
+ x-example: a24a6ea4-ce75-4665-a070-57453082c25
782
+ - in: formData
783
+ name: is_shared
784
+ default: true
785
+ type: boolean
786
+ x-example: true
787
+ responses:
788
+ 201:
789
+ description: All assets modified.
790
+ """
791
+ user_service.check_manager_project_access(project_id)
792
+ return super().post(project_id=project_id, asset_type_id=asset_type_id)
793
+
794
+
795
+ class SetSharedAssetsResource(BaseSetSharedAssetsResource):
796
+ """
797
+ Share or unshare all assets (or a list of assets) for given project.
798
+ """
799
+
800
+ @jwt_required()
801
+ def post(self):
802
+ """
803
+ Share or unshare a list of assets.
804
+ ---
805
+ tags:
806
+ - Assets
807
+ consumes:
808
+ - multipart/form-data
809
+ parameters:
810
+ - in: formData
811
+ name: asset_ids
812
+ default: None,
813
+ type: array
814
+ items:
815
+ type: UUID
816
+ x-example: ["a24a6ea4-ce75-4665-a070-57453082c25"]
817
+ - in: formData
818
+ name: is_shared
819
+ default: true
820
+ type: boolean
821
+ x-example: true
822
+ responses:
823
+ 201:
824
+ description: All assets modified.
825
+ """
826
+ args = self.get_args(
827
+ [
828
+ (
829
+ "asset_ids",
830
+ [],
831
+ True,
832
+ str,
833
+ "append",
834
+ ),
835
+ ]
836
+ )
837
+ asset_ids = args["asset_ids"]
838
+ project_ids = set()
839
+ for asset_id in asset_ids:
840
+ project_ids.add(assets_service.get_asset(asset_id)["project_id"])
841
+ for project_id in project_ids:
842
+ user_service.check_manager_project_access(project_id)
843
+ return super().post(asset_ids=asset_ids)
844
+
845
+
846
+ class ProjectAssetsSharedUsedResource(Resource):
847
+ @jwt_required()
848
+ def get(self, project_id):
849
+ """
850
+ Retrieve all shared assets used in project.
851
+ ---
852
+ tags:
853
+ - Assets
854
+ parameters:
855
+ - in: path
856
+ name: project_id
857
+ required: True
858
+ type: string
859
+ format: UUID
860
+ x-example: a24a6ea4-ce75-4665-a070-57453082c25
861
+ responses:
862
+ 200:
863
+ description: All shared assets used in project
864
+ """
865
+ user_service.check_project_access(project_id)
866
+ return assets_service.get_shared_assets_used_in_project(project_id)
867
+
868
+
869
+ class ProjectEpisodeAssetsSharedUsedResource(Resource):
870
+ @jwt_required()
871
+ def get(self, project_id, episode_id):
872
+ """
873
+ Retrieve all shared assets used in project episode.
874
+ ---
875
+ tags:
876
+ - Assets
877
+ parameters:
878
+ - in: path
879
+ name: project_id
880
+ required: True
881
+ type: string
882
+ format: UUID
883
+ x-example: a24a6ea4-ce75-4665-a070-57453082c25
884
+ - in: path
885
+ name: episode_id
886
+ required: True
887
+ type: string
888
+ format: UUID
889
+ x-example: a24a6ea4-ce75-4665-a070-57453082c25
890
+ responses:
891
+ 200:
892
+ description: All shared assets used in project episode
893
+ """
894
+ user_service.check_project_access(project_id)
895
+ return assets_service.get_shared_assets_used_in_project(
896
+ project_id, episode_id
897
+ )
@@ -1376,31 +1376,35 @@ class SAMLSSOResource(Resource, ArgsMixin):
1376
1376
  email, "default".encode("utf-8"), **person_info
1377
1377
  )
1378
1378
 
1379
- access_token = create_access_token(
1380
- identity=user["id"],
1381
- additional_claims={
1382
- "identity_type": "person",
1383
- },
1384
- )
1385
- refresh_token = create_refresh_token(
1386
- identity=user["id"],
1387
- additional_claims={
1388
- "identity_type": "person",
1389
- },
1390
- )
1391
- identity_changed.send(
1392
- current_app._get_current_object(),
1393
- identity=Identity(user["id"], "person"),
1394
- )
1395
-
1396
- ip_address = request.environ.get("HTTP_X_REAL_IP", request.remote_addr)
1397
-
1398
1379
  response = make_response(
1399
1380
  redirect(f"{config.DOMAIN_PROTOCOL}://{config.DOMAIN_NAME}")
1400
1381
  )
1401
- set_access_cookies(response, access_token)
1402
- set_refresh_cookies(response, refresh_token)
1403
- events_service.create_login_log(user["id"], ip_address, "web")
1382
+
1383
+ if user["active"]:
1384
+ access_token = create_access_token(
1385
+ identity=user["id"],
1386
+ additional_claims={
1387
+ "identity_type": "person",
1388
+ },
1389
+ )
1390
+ refresh_token = create_refresh_token(
1391
+ identity=user["id"],
1392
+ additional_claims={
1393
+ "identity_type": "person",
1394
+ },
1395
+ )
1396
+ identity_changed.send(
1397
+ current_app._get_current_object(),
1398
+ identity=Identity(user["id"], "person"),
1399
+ )
1400
+
1401
+ ip_address = request.environ.get(
1402
+ "HTTP_X_REAL_IP", request.remote_addr
1403
+ )
1404
+
1405
+ set_access_cookies(response, access_token)
1406
+ set_refresh_cookies(response, refresh_token)
1407
+ events_service.create_login_log(user["id"], ip_address, "web")
1404
1408
 
1405
1409
  return response
1406
1410
 
@@ -10,7 +10,7 @@ from zou.app.services import (
10
10
  persons_service,
11
11
  user_service,
12
12
  )
13
- from zou.app.services.exception import ArgumentsException
13
+ from zou.app.services.exception import WrongParameterException
14
14
 
15
15
 
16
16
  class ChatResource(Resource):
@@ -116,7 +116,7 @@ class ChatMessagesResource(Resource):
116
116
 
117
117
  chat = chats_service.get_chat(entity_id)
118
118
  if person["id"] not in chat["participants"]:
119
- raise ArgumentsException("You are not a participant of this chat")
119
+ raise WrongParameterException("You are not a participant of this chat")
120
120
 
121
121
  return (
122
122
  chats_service.create_chat_message(
@@ -12,7 +12,7 @@ from sqlalchemy.inspection import inspect
12
12
  from zou.app.mixin import ArgsMixin
13
13
  from zou.app.utils import events, fields, permissions, query
14
14
  from zou.app.services.exception import (
15
- ArgumentsException,
15
+ WrongParameterException,
16
16
  WrongParameterException,
17
17
  )
18
18
 
@@ -79,7 +79,11 @@ class BaseModelsResource(Resource, ArgsMixin):
79
79
  ) and isinstance(
80
80
  field_key.property, orm.properties.RelationshipProperty
81
81
  )
82
- value_is_list = len(value) > 0 and value[0] == "["
82
+ value_is_list = (
83
+ hasattr(value, "__len__")
84
+ and len(value) > 0
85
+ and value[0] == "["
86
+ )
83
87
 
84
88
  if key == "name" and field_key is not None:
85
89
  name_filter.append(value)
@@ -233,7 +237,7 @@ class BaseModelsResource(Resource, ArgsMixin):
233
237
  try:
234
238
  data = request.json
235
239
  if data is None:
236
- raise ArgumentsException(
240
+ raise WrongParameterException(
237
241
  "Data are empty. Please verify that you sent JSON data and"
238
242
  " that you set the right headers."
239
243
  )
@@ -254,7 +258,7 @@ class BaseModelsResource(Resource, ArgsMixin):
254
258
  current_app.logger.error(str(exception), exc_info=1)
255
259
  return {"message": str(exception)}, 400
256
260
 
257
- except ArgumentsException as exception:
261
+ except WrongParameterException as exception:
258
262
  current_app.logger.error(str(exception), exc_info=1)
259
263
  return (
260
264
  exception.dict
@@ -402,7 +406,7 @@ class BaseModelResource(Resource, ArgsMixin):
402
406
  try:
403
407
  data = self.get_arguments()
404
408
  if data is None:
405
- raise ArgumentsException(
409
+ raise WrongParameterException(
406
410
  "Data are empty. Please verify that you sent JSON data and"
407
411
  " that you set the right headers."
408
412
  )
@@ -425,7 +429,7 @@ class BaseModelResource(Resource, ArgsMixin):
425
429
  current_app.logger.error(str(exception), exc_info=1)
426
430
  return {"message": str(exception)}, 400
427
431
 
428
- except ArgumentsException as exception:
432
+ except WrongParameterException as exception:
429
433
  current_app.logger.error(str(exception), exc_info=1)
430
434
  return (
431
435
  exception.dict
@@ -5,7 +5,7 @@ from zou.app.blueprints.crud.base import BaseModelsResource, BaseModelResource
5
5
 
6
6
  from zou.app.services import user_service, time_spents_service
7
7
 
8
- from zou.app.services.exception import ArgumentsException
8
+ from zou.app.services.exception import WrongParameterException
9
9
 
10
10
  from zou.app.utils import permissions
11
11
 
@@ -21,7 +21,7 @@ class DayOffsResource(BaseModelsResource):
21
21
  if time_spents_service.get_day_offs_between(
22
22
  data["date"], data["end_date"], data["person_id"]
23
23
  ):
24
- raise ArgumentsException("Day off already exists for this period")
24
+ raise WrongParameterException("Day off already exists for this period")
25
25
  return data
26
26
 
27
27
  def post_creation(self, instance):
@@ -67,5 +67,5 @@ class DayOffResource(BaseModelResource):
67
67
  data.get("person_id", instance_dict["person_id"]),
68
68
  exclude_id=instance_dict["id"],
69
69
  ):
70
- raise ArgumentsException("Day off already exists for this period")
70
+ raise WrongParameterException("Day off already exists for this period")
71
71
  return data
@@ -28,7 +28,7 @@ from zou.app.services import (
28
28
  )
29
29
  from zou.app.utils import date_helpers, events, permissions
30
30
 
31
- from zou.app.services.exception import ArgumentsException
31
+ from zou.app.services.exception import WrongParameterException
32
32
 
33
33
  from werkzeug.exceptions import NotFound
34
34
 
@@ -88,7 +88,7 @@ class EntitiesResource(BaseModelsResource, EntityEventMixin):
88
88
  if "status" in data:
89
89
  types = [entity_status for entity_status, _ in ENTITY_STATUSES]
90
90
  if data["status"] not in types:
91
- raise ArgumentsException("Invalid status")
91
+ raise WrongParameterException("Invalid status")
92
92
  return True
93
93
 
94
94
  def all_entries(self, query=None, relations=False):
@@ -255,5 +255,5 @@ class EntityResource(BaseModelResource, EntityEventMixin):
255
255
  if "status" in data:
256
256
  types = [entity_status for entity_status, _ in ENTITY_STATUSES]
257
257
  if data["status"] not in types:
258
- raise ArgumentsException("Invalid status")
258
+ raise WrongParameterException("Invalid status")
259
259
  return data
@@ -4,6 +4,9 @@ from zou.app.models.entity_type import EntityType
4
4
  from zou.app.utils import events
5
5
  from zou.app.services import entities_service, assets_service
6
6
 
7
+ from zou.app.services.exception import WrongParameterException
8
+
9
+
7
10
 
8
11
  class EntityTypesResource(BaseModelsResource):
9
12
  def __init__(self):
@@ -28,6 +31,18 @@ class EntityTypesResource(BaseModelsResource):
28
31
  assets_service.clear_asset_type_cache()
29
32
  return instance.serialize(relations=True)
30
33
 
34
+ def check_creation_integrity(self, data):
35
+ entity_type = (
36
+ EntityType.query
37
+ .filter(EntityType.name.ilike(data.get("name", "")))
38
+ .first()
39
+ )
40
+ if entity_type is not None:
41
+ raise WrongParameterException(
42
+ "Entity type with this name already exists"
43
+ )
44
+ return data
45
+
31
46
 
32
47
  class EntityTypeResource(BaseModelResource):
33
48
  def __init__(self):
@@ -4,9 +4,11 @@ from zou.app.models.metadata_descriptor import (
4
4
  )
5
5
 
6
6
  from zou.app.blueprints.crud.base import BaseModelResource, BaseModelsResource
7
+ from zou.app.utils import permissions
8
+ from zou.app.models.project import Project
7
9
 
8
10
  from zou.app.services.exception import (
9
- ArgumentsException,
11
+ WrongParameterException,
10
12
  )
11
13
 
12
14
 
@@ -14,6 +16,16 @@ class MetadataDescriptorsResource(BaseModelsResource):
14
16
  def __init__(self):
15
17
  BaseModelsResource.__init__(self, MetadataDescriptor)
16
18
 
19
+ def check_read_permissions(self):
20
+ return not permissions.has_vendor_permissions()
21
+
22
+ def add_project_permission_filter(self, query):
23
+ if not permissions.has_admin_permissions():
24
+ query = query.join(Project).filter(
25
+ user_service.build_related_projects_filter()
26
+ )
27
+ return query
28
+
17
29
  def all_entries(self, query=None, relations=True):
18
30
  if query is None:
19
31
  query = self.model.query
@@ -30,11 +42,12 @@ class MetadataDescriptorsResource(BaseModelsResource):
30
42
  if "data_type" in data:
31
43
  types = [type_name for type_name, _ in METADATA_DESCRIPTOR_TYPES]
32
44
  if data["data_type"] not in types:
33
- raise ArgumentsException("Invalid data_type")
45
+ raise WrongParameterException("Invalid data_type")
34
46
  return True
35
47
 
36
48
 
37
49
  class MetadataDescriptorResource(BaseModelResource):
50
+
38
51
  def __init__(self):
39
52
  BaseModelResource.__init__(self, MetadataDescriptor)
40
53
 
@@ -47,5 +60,5 @@ class MetadataDescriptorResource(BaseModelResource):
47
60
  if "data_type" in data:
48
61
  types = [type_name for type_name, _ in METADATA_DESCRIPTOR_TYPES]
49
62
  if data["data_type"] not in types:
50
- raise ArgumentsException("Invalid data_type")
63
+ raise WrongParameterException("Invalid data_type")
51
64
  return data