Ayon-Python-Api 0.1.18__tar.gz → 0.2.1__tar.gz

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 (24) hide show
  1. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/PKG-INFO +1 -1
  2. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_api/__init__.py +74 -22
  3. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_api/_api.py +141 -24
  4. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_api/constants.py +11 -4
  5. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_api/entity_hub.py +91 -3
  6. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_api/graphql_queries.py +72 -27
  7. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_api/operations.py +61 -44
  8. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_api/server_api.py +1100 -501
  9. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_api/utils.py +1 -1
  10. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_api/version.py +1 -1
  11. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_python_api.egg-info/PKG-INFO +1 -1
  12. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/pyproject.toml +4 -3
  13. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/LICENSE +0 -0
  14. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/README.md +0 -0
  15. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_api/events.py +0 -0
  16. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_api/exceptions.py +0 -0
  17. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_api/graphql.py +0 -0
  18. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_api/thumbnails.py +0 -0
  19. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_python_api.egg-info/SOURCES.txt +0 -0
  20. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_python_api.egg-info/dependency_links.txt +0 -0
  21. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_python_api.egg-info/requires.txt +0 -0
  22. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/ayon_python_api.egg-info/top_level.txt +0 -0
  23. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/setup.cfg +0 -0
  24. {ayon-python-api-0.1.18 → ayon-python-api-0.2.1}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ayon-python-api
3
- Version: 0.1.18
3
+ Version: 0.2.1
4
4
  Summary: AYON Python API
5
5
  Home-page: https://github.com/ynput/ayon-python-api
6
6
  Author: ynput.io
@@ -59,13 +59,31 @@ from ._api import (
59
59
  get_addon_url,
60
60
  download_addon_private_file,
61
61
 
62
+ get_installers,
63
+ create_installer,
64
+ update_installer,
65
+ delete_installer,
66
+ download_installer,
67
+ upload_installer,
68
+
62
69
  get_dependencies_info,
63
70
  update_dependency_info,
71
+ get_dependency_packages,
72
+ create_dependency_package,
73
+ update_dependency_package,
74
+ delete_dependency_package,
64
75
 
65
76
  download_dependency_package,
66
77
  upload_dependency_package,
67
- delete_dependency_package,
68
78
 
79
+ get_bundles,
80
+ create_bundle,
81
+ update_bundle,
82
+ delete_bundle,
83
+
84
+ get_info,
85
+ get_server_version,
86
+ get_server_version_tuple,
69
87
  get_user,
70
88
  get_users,
71
89
 
@@ -87,9 +105,11 @@ from ._api import (
87
105
  get_addons_project_settings,
88
106
  get_addons_settings,
89
107
 
108
+ get_project_names,
90
109
  get_projects,
91
110
  get_project,
92
111
  create_project,
112
+ update_project,
93
113
  delete_project,
94
114
 
95
115
  get_folder_by_id,
@@ -99,22 +119,24 @@ from ._api import (
99
119
 
100
120
  get_tasks,
101
121
 
102
- get_folder_ids_with_subsets,
103
- get_subset_by_id,
104
- get_subset_by_name,
105
- get_subsets,
106
- get_subset_families,
122
+ get_folder_ids_with_products,
123
+ get_product_by_id,
124
+ get_product_by_name,
125
+ get_products,
126
+ get_product_types,
127
+ get_project_product_types,
128
+ get_product_type_names,
107
129
 
108
130
  get_version_by_id,
109
131
  get_version_by_name,
110
132
  version_is_latest,
111
133
  get_versions,
112
- get_hero_version_by_subset_id,
134
+ get_hero_version_by_product_id,
113
135
  get_hero_version_by_id,
114
136
  get_hero_versions,
115
137
  get_last_versions,
116
- get_last_version_by_subset_id,
117
- get_last_version_by_subset_name,
138
+ get_last_version_by_product_id,
139
+ get_last_version_by_product_name,
118
140
  get_representation_by_id,
119
141
  get_representation_by_name,
120
142
  get_representations,
@@ -122,6 +144,10 @@ from ._api import (
122
144
  get_representation_parents,
123
145
  get_repre_ids_by_context_filters,
124
146
 
147
+ get_workfiles_info,
148
+ get_workfile_info,
149
+ get_workfile_info_by_id,
150
+
125
151
  get_thumbnail,
126
152
  get_folder_thumbnail,
127
153
  get_version_thumbnail,
@@ -143,8 +169,8 @@ from ._api import (
143
169
  get_folders_links,
144
170
  get_task_links,
145
171
  get_tasks_links,
146
- get_subset_links,
147
- get_subsets_links,
172
+ get_product_links,
173
+ get_products_links,
148
174
  get_version_links,
149
175
  get_versions_links,
150
176
  get_representations_links,
@@ -212,13 +238,31 @@ __all__ = (
212
238
  "get_addon_url",
213
239
  "download_addon_private_file",
214
240
 
241
+ "get_installers",
242
+ "create_installer",
243
+ "update_installer",
244
+ "delete_installer",
245
+ "download_installer",
246
+ "upload_installer",
247
+
215
248
  "get_dependencies_info",
216
249
  "update_dependency_info",
250
+ "get_dependency_packages",
251
+ "create_dependency_package",
252
+ "update_dependency_package",
253
+ "delete_dependency_package",
217
254
 
218
255
  "download_dependency_package",
219
256
  "upload_dependency_package",
220
- "delete_dependency_package",
221
257
 
258
+ "get_bundles",
259
+ "create_bundle",
260
+ "update_bundle",
261
+ "delete_bundle",
262
+
263
+ "get_info",
264
+ "get_server_version",
265
+ "get_server_version_tuple",
222
266
  "get_user",
223
267
  "get_users",
224
268
 
@@ -239,9 +283,11 @@ __all__ = (
239
283
  "get_addons_project_settings",
240
284
  "get_addons_settings",
241
285
 
286
+ "get_project_names",
242
287
  "get_projects",
243
288
  "get_project",
244
289
  "create_project",
290
+ "update_project",
245
291
  "delete_project",
246
292
 
247
293
  "get_folder_by_id",
@@ -251,22 +297,24 @@ __all__ = (
251
297
 
252
298
  "get_tasks",
253
299
 
254
- "get_folder_ids_with_subsets",
255
- "get_subset_by_id",
256
- "get_subset_by_name",
257
- "get_subsets",
258
- "get_subset_families",
300
+ "get_folder_ids_with_products",
301
+ "get_product_by_id",
302
+ "get_product_by_name",
303
+ "get_products",
304
+ "get_product_types",
305
+ "get_project_product_types",
306
+ "get_product_type_names",
259
307
 
260
308
  "get_version_by_id",
261
309
  "get_version_by_name",
262
310
  "version_is_latest",
263
311
  "get_versions",
264
- "get_hero_version_by_subset_id",
312
+ "get_hero_version_by_product_id",
265
313
  "get_hero_version_by_id",
266
314
  "get_hero_versions",
267
315
  "get_last_versions",
268
- "get_last_version_by_subset_id",
269
- "get_last_version_by_subset_name",
316
+ "get_last_version_by_product_id",
317
+ "get_last_version_by_product_name",
270
318
  "get_representation_by_id",
271
319
  "get_representation_by_name",
272
320
  "get_representations",
@@ -274,6 +322,10 @@ __all__ = (
274
322
  "get_representation_parents",
275
323
  "get_repre_ids_by_context_filters",
276
324
 
325
+ "get_workfiles_info",
326
+ "get_workfile_info",
327
+ "get_workfile_info_by_id",
328
+
277
329
  "get_thumbnail",
278
330
  "get_folder_thumbnail",
279
331
  "get_version_thumbnail",
@@ -295,8 +347,8 @@ __all__ = (
295
347
  "get_folders_links",
296
348
  "get_task_links",
297
349
  "get_tasks_links",
298
- "get_subset_links",
299
- "get_subsets_links",
350
+ "get_product_links",
351
+ "get_products_links",
300
352
  "get_version_links",
301
353
  "get_versions_links",
302
354
  "get_representations_links",
@@ -531,6 +531,53 @@ def download_addon_private_file(*args, **kwargs):
531
531
  return con.download_addon_private_file(*args, **kwargs)
532
532
 
533
533
 
534
+ def get_info(*args, **kwargs):
535
+ con = get_server_api_connection()
536
+ return con.get_info(*args, **kwargs)
537
+
538
+
539
+ def get_server_version(*args, **kwargs):
540
+ con = get_server_api_connection()
541
+ return con.get_server_version(*args, **kwargs)
542
+
543
+
544
+ def get_server_version_tuple(*args, **kwargs):
545
+ con = get_server_api_connection()
546
+ return con.get_server_version_tuple(*args, **kwargs)
547
+
548
+
549
+ # Installers
550
+ def get_installers(*args, **kwargs):
551
+ con = get_server_api_connection()
552
+ return con.get_installers(*args, **kwargs)
553
+
554
+
555
+ def create_installer(*args, **kwargs):
556
+ con = get_server_api_connection()
557
+ return con.create_installer(*args, **kwargs)
558
+
559
+
560
+ def update_installer(*args, **kwargs):
561
+ con = get_server_api_connection()
562
+ return con.update_installer(*args, **kwargs)
563
+
564
+
565
+ def delete_installer(*args, **kwargs):
566
+ con = get_server_api_connection()
567
+ return con.delete_installer(*args, **kwargs)
568
+
569
+
570
+ def download_installer(*args, **kwargs):
571
+ con = get_server_api_connection()
572
+ con.download_installer(*args, **kwargs)
573
+
574
+
575
+ def upload_installer(*args, **kwargs):
576
+ con = get_server_api_connection()
577
+ con.upload_installer(*args, **kwargs)
578
+
579
+
580
+ # Dependency packages
534
581
  def get_dependencies_info(*args, **kwargs):
535
582
  con = get_server_api_connection()
536
583
  return con.get_dependencies_info(*args, **kwargs)
@@ -551,6 +598,21 @@ def upload_dependency_package(*args, **kwargs):
551
598
  return con.upload_dependency_package(*args, **kwargs)
552
599
 
553
600
 
601
+ def get_dependency_packages(*args, **kwargs):
602
+ con = get_server_api_connection()
603
+ return con.get_dependency_packages(*args, **kwargs)
604
+
605
+
606
+ def create_dependency_package(*args, **kwargs):
607
+ con = get_server_api_connection()
608
+ return con.create_dependency_package(*args, **kwargs)
609
+
610
+
611
+ def update_dependency_package(*args, **kwargs):
612
+ con = get_server_api_connection()
613
+ return con.update_dependency_package(*args, **kwargs)
614
+
615
+
554
616
  def delete_dependency_package(*args, **kwargs):
555
617
  con = get_server_api_connection()
556
618
  return con.delete_dependency_package(*args, **kwargs)
@@ -561,6 +623,26 @@ def get_project_anatomy_presets(*args, **kwargs):
561
623
  return con.get_project_anatomy_presets(*args, **kwargs)
562
624
 
563
625
 
626
+ def get_bundles(*args, **kwargs):
627
+ con = get_server_api_connection()
628
+ return con.get_bundles(*args, **kwargs)
629
+
630
+
631
+ def create_bundle(*args, **kwargs):
632
+ con = get_server_api_connection()
633
+ return con.create_bundle(*args, **kwargs)
634
+
635
+
636
+ def update_bundle(*args, **kwargs):
637
+ con = get_server_api_connection()
638
+ return con.update_bundle(*args, **kwargs)
639
+
640
+
641
+ def delete_bundle(*args, **kwargs):
642
+ con = get_server_api_connection()
643
+ return con.delete_bundle(*args, **kwargs)
644
+
645
+
564
646
  def get_project_anatomy_preset(*args, **kwargs):
565
647
  con = get_server_api_connection()
566
648
  return con.get_project_anatomy_preset(*args, **kwargs)
@@ -621,6 +703,11 @@ def get_addons_settings(*args, **kwargs):
621
703
  return con.get_addons_settings(*args, **kwargs)
622
704
 
623
705
 
706
+ def get_project_names(*args, **kwargs):
707
+ con = get_server_api_connection()
708
+ return con.get_project_names(*args, **kwargs)
709
+
710
+
624
711
  def get_project(*args, **kwargs):
625
712
  con = get_server_api_connection()
626
713
  return con.get_project(*args, **kwargs)
@@ -656,29 +743,39 @@ def get_folder_by_name(*args, **kwargs):
656
743
  return con.get_folder_by_name(*args, **kwargs)
657
744
 
658
745
 
659
- def get_folder_ids_with_subsets(*args, **kwargs):
746
+ def get_folder_ids_with_products(*args, **kwargs):
747
+ con = get_server_api_connection()
748
+ return con.get_folder_ids_with_products(*args, **kwargs)
749
+
750
+
751
+ def get_product_types(*args, **kwargs):
752
+ con = get_server_api_connection()
753
+ return con.get_product_types(*args, **kwargs)
754
+
755
+
756
+ def get_project_product_types(*args, **kwargs):
660
757
  con = get_server_api_connection()
661
- return con.get_folder_ids_with_subsets(*args, **kwargs)
758
+ return con.get_project_product_types(*args, **kwargs)
662
759
 
663
760
 
664
- def get_subsets(*args, **kwargs):
761
+ def get_product_type_names(*args, **kwargs):
665
762
  con = get_server_api_connection()
666
- return con.get_subsets(*args, **kwargs)
763
+ return con.get_product_type_names(*args, **kwargs)
667
764
 
668
765
 
669
- def get_subset_by_id(*args, **kwargs):
766
+ def get_products(*args, **kwargs):
670
767
  con = get_server_api_connection()
671
- return con.get_subset_by_id(*args, **kwargs)
768
+ return con.get_products(*args, **kwargs)
672
769
 
673
770
 
674
- def get_subset_by_name(*args, **kwargs):
771
+ def get_product_by_id(*args, **kwargs):
675
772
  con = get_server_api_connection()
676
- return con.get_subset_by_name(*args, **kwargs)
773
+ return con.get_product_by_id(*args, **kwargs)
677
774
 
678
775
 
679
- def get_subset_families(*args, **kwargs):
776
+ def get_product_by_name(*args, **kwargs):
680
777
  con = get_server_api_connection()
681
- return con.get_subset_families(*args, **kwargs)
778
+ return con.get_product_by_name(*args, **kwargs)
682
779
 
683
780
 
684
781
  def get_versions(*args, **kwargs):
@@ -701,9 +798,9 @@ def get_hero_version_by_id(*args, **kwargs):
701
798
  return con.get_hero_version_by_id(*args, **kwargs)
702
799
 
703
800
 
704
- def get_hero_version_by_subset_id(*args, **kwargs):
801
+ def get_hero_version_by_product_id(*args, **kwargs):
705
802
  con = get_server_api_connection()
706
- return con.get_hero_version_by_subset_id(*args, **kwargs)
803
+ return con.get_hero_version_by_product_id(*args, **kwargs)
707
804
 
708
805
 
709
806
  def get_hero_versions(*args, **kwargs):
@@ -716,14 +813,14 @@ def get_last_versions(*args, **kwargs):
716
813
  return con.get_last_versions(*args, **kwargs)
717
814
 
718
815
 
719
- def get_last_version_by_subset_id(*args, **kwargs):
816
+ def get_last_version_by_product_id(*args, **kwargs):
720
817
  con = get_server_api_connection()
721
- return con.get_last_version_by_subset_id(*args, **kwargs)
818
+ return con.get_last_version_by_product_id(*args, **kwargs)
722
819
 
723
820
 
724
- def get_last_version_by_subset_name(*args, **kwargs):
821
+ def get_last_version_by_product_name(*args, **kwargs):
725
822
  con = get_server_api_connection()
726
- return con.get_last_version_by_subset_name(*args, **kwargs)
823
+ return con.get_last_version_by_product_name(*args, **kwargs)
727
824
 
728
825
 
729
826
  def version_is_latest(*args, **kwargs):
@@ -761,6 +858,21 @@ def get_repre_ids_by_context_filters(*args, **kwargs):
761
858
  return con.get_repre_ids_by_context_filters(*args, **kwargs)
762
859
 
763
860
 
861
+ def get_workfiles_info(*args, **kwargs):
862
+ con = get_server_api_connection()
863
+ return con.get_workfiles_info(*args, **kwargs)
864
+
865
+
866
+ def get_workfile_info(*args, **kwargs):
867
+ con = get_server_api_connection()
868
+ return con.get_workfile_info(*args, **kwargs)
869
+
870
+
871
+ def get_workfile_info_by_id(*args, **kwargs):
872
+ con = get_server_api_connection()
873
+ return con.get_workfile_info_by_id(*args, **kwargs)
874
+
875
+
764
876
  def create_project(
765
877
  project_name,
766
878
  project_code,
@@ -776,6 +888,11 @@ def create_project(
776
888
  )
777
889
 
778
890
 
891
+ def update_project(project_name, *args, **kwargs):
892
+ con = get_server_api_connection()
893
+ return con.update_project(project_name, *args, **kwargs)
894
+
895
+
779
896
  def delete_project(project_name):
780
897
  con = get_server_api_connection()
781
898
  return con.delete_project(project_name)
@@ -954,31 +1071,31 @@ def get_task_links(
954
1071
  )
955
1072
 
956
1073
 
957
- def get_subsets_links(
1074
+ def get_products_links(
958
1075
  project_name,
959
- subset_ids=None,
1076
+ product_ids=None,
960
1077
  link_types=None,
961
1078
  link_direction=None
962
1079
  ):
963
1080
  con = get_server_api_connection()
964
- return con.get_subsets_links(
1081
+ return con.get_products_links(
965
1082
  project_name,
966
- subset_ids,
1083
+ product_ids,
967
1084
  link_types,
968
1085
  link_direction
969
1086
  )
970
1087
 
971
1088
 
972
- def get_subset_links(
1089
+ def get_product_links(
973
1090
  project_name,
974
- subset_id,
1091
+ product_id,
975
1092
  link_types=None,
976
1093
  link_direction=None
977
1094
  ):
978
1095
  con = get_server_api_connection()
979
- return con.get_subset_links(
1096
+ return con.get_product_links(
980
1097
  project_name,
981
- subset_id,
1098
+ product_id,
982
1099
  link_types,
983
1100
  link_direction
984
1101
  )
@@ -4,6 +4,13 @@ SERVER_API_ENV_KEY = "AYON_API_KEY"
4
4
  # Backwards compatibility
5
5
  SERVER_TOKEN_ENV_KEY = SERVER_API_ENV_KEY
6
6
 
7
+ # --- Product types ---
8
+ DEFAULT_PRODUCT_TYPE_FIELDS = {
9
+ "name",
10
+ "icon",
11
+ "color",
12
+ }
13
+
7
14
  # --- Project ---
8
15
  DEFAULT_PROJECT_FIELDS = {
9
16
  "active",
@@ -36,13 +43,13 @@ DEFAULT_TASK_FIELDS = {
36
43
  "assignees",
37
44
  }
38
45
 
39
- # --- Subsets ---
40
- DEFAULT_SUBSET_FIELDS = {
46
+ # --- Products ---
47
+ DEFAULT_PRODUCT_FIELDS = {
41
48
  "id",
42
49
  "name",
43
50
  "folderId",
44
51
  "active",
45
- "family",
52
+ "productType",
46
53
  }
47
54
 
48
55
  # --- Versions ---
@@ -50,7 +57,7 @@ DEFAULT_VERSION_FIELDS = {
50
57
  "id",
51
58
  "name",
52
59
  "version",
53
- "subsetId",
60
+ "productId",
54
61
  "taskId",
55
62
  "active",
56
63
  "author",
@@ -558,7 +558,7 @@ class EntityHub(object):
558
558
  folder_fields = set(
559
559
  self._connection.get_default_fields_for_type("folder")
560
560
  )
561
- folder_fields.add("hasSubsets")
561
+ folder_fields.add("hasProducts")
562
562
  if self._allow_data_changes:
563
563
  folder_fields.add("data")
564
564
  return folder_fields
@@ -602,7 +602,7 @@ class EntityHub(object):
602
602
  for folder in folders_by_parent_id[parent_id]:
603
603
  folder_entity = self.add_folder(folder)
604
604
  children_ids.add(folder_entity.id)
605
- folder_entity.has_published_content = folder["hasSubsets"]
605
+ folder_entity.has_published_content = folder["hasProducts"]
606
606
  hierarchy_queue.append((folder_entity.id, folder_entity))
607
607
 
608
608
  for task in tasks_by_parent_id[parent_id]:
@@ -683,6 +683,82 @@ class EntityHub(object):
683
683
  "entityId": entity.id
684
684
  }
685
685
 
686
+ def _pre_commit_types_changes(
687
+ self, project_changes, orig_types, changes_key, post_changes
688
+ ):
689
+ """Compare changes of types on a project.
690
+
691
+ Compare old and new types. Change project changes content if some old
692
+ types were removed. In that case the final change of types will
693
+ happen when all other entities have changed.
694
+
695
+ Args:
696
+ project_changes (dict[str, Any]): Project changes.
697
+ orig_types (list[dict[str, Any]]): Original types.
698
+ changes_key (Literal[folderTypes, taskTypes]): Key of type changes
699
+ in project changes.
700
+ post_changes (dict[str, Any]): An object where post changes will
701
+ be stored.
702
+ """
703
+
704
+ if changes_key not in project_changes:
705
+ return
706
+
707
+ new_types = project_changes[changes_key]
708
+
709
+ orig_types_by_name = {
710
+ type_info["name"]: type_info
711
+ for type_info in orig_types
712
+ }
713
+ new_names = {
714
+ type_info["name"]
715
+ for type_info in new_types
716
+ }
717
+ diff_names = set(orig_types_by_name) - new_names
718
+ if not diff_names:
719
+ return
720
+
721
+ # Create copy of folder type changes to post changes
722
+ # - post changes will be commited at the end
723
+ post_changes[changes_key] = copy.deepcopy(new_types)
724
+
725
+ for type_name in diff_names:
726
+ new_types.append(orig_types_by_name[type_name])
727
+
728
+ def _pre_commit_project(self):
729
+ """Some project changes cannot be committed before hierarchy changes.
730
+
731
+ It is not possible to change folder types or task types if there are
732
+ existing hierarchy items using the removed types. For that purposes
733
+ is first committed union of all old and new types and post changes
734
+ are prepared when all existing entities are changed.
735
+
736
+ Returns:
737
+ dict[str, Any]: Changes that will be committed after hierarchy
738
+ changes.
739
+ """
740
+
741
+ project_changes = self.project_entity.changes
742
+
743
+ post_changes = {}
744
+ if not project_changes:
745
+ return post_changes
746
+
747
+ self._pre_commit_types_changes(
748
+ project_changes,
749
+ self.project_entity.get_orig_folder_types(),
750
+ "folderType",
751
+ post_changes
752
+ )
753
+ self._pre_commit_types_changes(
754
+ project_changes,
755
+ self.project_entity.get_orig_task_types(),
756
+ "taskType",
757
+ post_changes
758
+ )
759
+ self._connection.update_project(self.project_name, **project_changes)
760
+ return post_changes
761
+
686
762
  def commit_changes(self):
687
763
  """Commit any changes that happened on entities.
688
764
 
@@ -690,6 +766,9 @@ class EntityHub(object):
690
766
  Use Operations Session instead of known operations body.
691
767
  """
692
768
 
769
+ post_project_changes = self._pre_commit_project()
770
+ self.project_entity.lock()
771
+
693
772
  project_changes = self.project_entity.changes
694
773
  if project_changes:
695
774
  response = self._connection.patch(
@@ -760,6 +839,9 @@ class EntityHub(object):
760
839
  self._connection.send_batch_operations(
761
840
  self.project_name, operations_body
762
841
  )
842
+ if post_project_changes:
843
+ self._connection.update_project(
844
+ self.project_name, **post_project_changes)
763
845
 
764
846
  self.lock()
765
847
 
@@ -1463,6 +1545,9 @@ class ProjectEntity(BaseEntity):
1463
1545
 
1464
1546
  parent = property(get_parent, set_parent)
1465
1547
 
1548
+ def get_orig_folder_types(self):
1549
+ return copy.deepcopy(self._orig_folder_types)
1550
+
1466
1551
  def get_folder_types(self):
1467
1552
  return copy.deepcopy(self._folder_types)
1468
1553
 
@@ -1474,6 +1559,9 @@ class ProjectEntity(BaseEntity):
1474
1559
  new_folder_types.append(folder_type)
1475
1560
  self._folder_types = new_folder_types
1476
1561
 
1562
+ def get_orig_task_types(self):
1563
+ return copy.deepcopy(self._orig_task_types)
1564
+
1477
1565
  def get_task_types(self):
1478
1566
  return copy.deepcopy(self._task_types)
1479
1567
 
@@ -1564,7 +1652,7 @@ class FolderEntity(BaseEntity):
1564
1652
 
1565
1653
  self._orig_folder_type = folder_type
1566
1654
  self._orig_label = label
1567
- # Know if folder has any subsets
1655
+ # Know if folder has any products
1568
1656
  # - is used to know if folder allows hierarchy changes
1569
1657
  self._has_published_content = False
1570
1658
  self._path = path