Ayon-Python-Api 0.3.2__tar.gz → 0.3.3__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.3.2 → ayon-python-api-0.3.3}/PKG-INFO +1 -1
  2. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_api/__init__.py +4 -0
  3. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_api/_api.py +30 -34
  4. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_api/server_api.py +154 -9
  5. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_api/utils.py +131 -8
  6. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_api/version.py +1 -1
  7. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_python_api.egg-info/PKG-INFO +1 -1
  8. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/pyproject.toml +1 -1
  9. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/LICENSE +0 -0
  10. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/README.md +0 -0
  11. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_api/constants.py +0 -0
  12. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_api/entity_hub.py +0 -0
  13. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_api/events.py +0 -0
  14. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_api/exceptions.py +0 -0
  15. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_api/graphql.py +0 -0
  16. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_api/graphql_queries.py +0 -0
  17. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_api/operations.py +0 -0
  18. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_api/thumbnails.py +0 -0
  19. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_python_api.egg-info/SOURCES.txt +0 -0
  20. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_python_api.egg-info/dependency_links.txt +0 -0
  21. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_python_api.egg-info/requires.txt +0 -0
  22. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/ayon_python_api.egg-info/top_level.txt +0 -0
  23. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/setup.cfg +0 -0
  24. {ayon-python-api-0.3.2 → ayon-python-api-0.3.3}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ayon-python-api
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: AYON Python API
5
5
  Home-page: https://github.com/ynput/ayon-python-api
6
6
  Author: ynput.io
@@ -78,6 +78,8 @@ from ._api import (
78
78
  download_dependency_package,
79
79
  upload_dependency_package,
80
80
 
81
+ upload_addon_zip,
82
+
81
83
  get_bundles,
82
84
  create_bundle,
83
85
  update_bundle,
@@ -262,6 +264,8 @@ __all__ = (
262
264
  "download_dependency_package",
263
265
  "upload_dependency_package",
264
266
 
267
+ "upload_addon_zip",
268
+
265
269
  "get_bundles",
266
270
  "create_bundle",
267
271
  "update_bundle",
@@ -25,12 +25,29 @@ class GlobalServerAPI(ServerAPI):
25
25
  but that can be filled afterwards with calling 'login' method.
26
26
  """
27
27
 
28
- def __init__(self, site_id=None, client_version=None):
28
+ def __init__(
29
+ self,
30
+ site_id=None,
31
+ client_version=None,
32
+ default_settings_variant=None,
33
+ ssl_verify=None,
34
+ cert=None,
35
+ ):
29
36
  url = self.get_url()
30
37
  token = self.get_token()
31
38
 
32
- super(GlobalServerAPI, self).__init__(url, token, site_id, client_version)
33
-
39
+ super(GlobalServerAPI, self).__init__(
40
+ url,
41
+ token,
42
+ site_id,
43
+ client_version,
44
+ default_settings_variant,
45
+ ssl_verify,
46
+ cert,
47
+ # We want to make sure that server and api key validation
48
+ # happens all the time in 'GlobalServerAPI'.
49
+ create_session=False,
50
+ )
34
51
  self.validate_server_availability()
35
52
  self.create_session()
36
53
 
@@ -129,17 +146,6 @@ class ServiceContext:
129
146
  addon_version = None
130
147
  service_name = None
131
148
 
132
- @staticmethod
133
- def get_value_from_envs(env_keys, value=None):
134
- if value:
135
- return value
136
-
137
- for env_key in env_keys:
138
- value = os.environ.get(env_key)
139
- if value:
140
- break
141
- return value
142
-
143
149
  @classmethod
144
150
  def init_service(
145
151
  cls,
@@ -150,14 +156,8 @@ class ServiceContext:
150
156
  service_name=None,
151
157
  connect=True
152
158
  ):
153
- token = cls.get_value_from_envs(
154
- ("AY_API_KEY", "AYON_API_KEY"),
155
- token
156
- )
157
- server_url = cls.get_value_from_envs(
158
- ("AY_SERVER_URL", "AYON_SERVER_URL"),
159
- server_url
160
- )
159
+ token = token or os.environ.get("AYON_API_KEY")
160
+ server_url = server_url or os.environ.get("AYON_SERVER_URL")
161
161
  if not server_url:
162
162
  raise FailedServiceInit("URL to server is not set")
163
163
 
@@ -166,18 +166,9 @@ class ServiceContext:
166
166
  "Token to server {} is not set".format(server_url)
167
167
  )
168
168
 
169
- addon_name = cls.get_value_from_envs(
170
- ("AY_ADDON_NAME", "AYON_ADDON_NAME"),
171
- addon_name
172
- )
173
- addon_version = cls.get_value_from_envs(
174
- ("AY_ADDON_VERSION", "AYON_ADDON_VERSION"),
175
- addon_version
176
- )
177
- service_name = cls.get_value_from_envs(
178
- ("AY_SERVICE_NAME", "AYON_SERVICE_NAME"),
179
- service_name
180
- )
169
+ addon_name = addon_name or os.environ.get("AYON_ADDON_NAME")
170
+ addon_version = addon_version or os.environ.get("AYON_ADDON_VERSION")
171
+ service_name = service_name or os.environ.get("AYON_SERVICE_NAME")
181
172
 
182
173
  cls.token = token
183
174
  cls.server_url = server_url
@@ -618,6 +609,11 @@ def delete_dependency_package(*args, **kwargs):
618
609
  return con.delete_dependency_package(*args, **kwargs)
619
610
 
620
611
 
612
+ def upload_addon_zip(*args, **kwargs):
613
+ con = get_server_api_connection()
614
+ return con.upload_addon_zip(*args, **kwargs)
615
+
616
+
621
617
  def get_project_anatomy_presets(*args, **kwargs):
622
618
  con = get_server_api_connection()
623
619
  return con.get_project_anatomy_presets(*args, **kwargs)
@@ -4,7 +4,6 @@ import io
4
4
  import json
5
5
  import logging
6
6
  import collections
7
- import datetime
8
7
  import platform
9
8
  import copy
10
9
  import uuid
@@ -325,6 +324,8 @@ class ServerAPI(object):
325
324
  available then 'True' is used.
326
325
  cert (Optional[str]): Path to certificate file. Looks for env
327
326
  variable value 'AYON_CERT_FILE' by default.
327
+ create_session (Optional[bool]): Create session for connection if
328
+ token is available. Default is True.
328
329
  """
329
330
 
330
331
  def __init__(
@@ -336,6 +337,7 @@ class ServerAPI(object):
336
337
  default_settings_variant=None,
337
338
  ssl_verify=None,
338
339
  cert=None,
340
+ create_session=True,
339
341
  ):
340
342
  if not base_url:
341
343
  raise ValueError("Invalid server URL {}".format(str(base_url)))
@@ -367,6 +369,7 @@ class ServerAPI(object):
367
369
 
368
370
  self._access_token_is_service = None
369
371
  self._token_is_valid = None
372
+ self._token_validation_started = False
370
373
  self._server_available = None
371
374
  self._server_version = None
372
375
  self._server_version_tuple = None
@@ -389,6 +392,11 @@ class ServerAPI(object):
389
392
  self._as_user_stack = _AsUserStack()
390
393
  self._thumbnail_cache = ThumbnailCache(True)
391
394
 
395
+ # Create session
396
+ if self._access_token and create_session:
397
+ self.validate_server_availability()
398
+ self.create_session()
399
+
392
400
  @property
393
401
  def log(self):
394
402
  if self._log is None:
@@ -652,6 +660,7 @@ class ServerAPI(object):
652
660
 
653
661
  def validate_token(self):
654
662
  try:
663
+ self._token_validation_started = True
655
664
  # TODO add other possible validations
656
665
  # - existence of 'user' key in info
657
666
  # - validate that 'site_id' is in 'sites' in info
@@ -661,6 +670,9 @@ class ServerAPI(object):
661
670
 
662
671
  except UnauthorizedError:
663
672
  self._token_is_valid = False
673
+
674
+ finally:
675
+ self._token_validation_started = False
664
676
  return self._token_is_valid
665
677
 
666
678
  def set_token(self, token):
@@ -673,8 +685,25 @@ class ServerAPI(object):
673
685
  self._token_is_valid = None
674
686
  self.close_session()
675
687
 
676
- def create_session(self):
688
+ def create_session(self, ignore_existing=True, force=False):
689
+ """Create a connection session.
690
+
691
+ Session helps to keep connection with server without
692
+ need to reconnect on each call.
693
+
694
+ Args:
695
+ ignore_existing (bool): If session already exists,
696
+ ignore creation.
697
+ force (bool): If session already exists, close it and
698
+ create new.
699
+ """
700
+
701
+ if force and self._session is not None:
702
+ self.close_session()
703
+
677
704
  if self._session is not None:
705
+ if ignore_existing:
706
+ return
678
707
  raise ValueError("Session is already created.")
679
708
 
680
709
  self._as_user_stack.clear()
@@ -841,7 +870,19 @@ class ServerAPI(object):
841
870
  self._access_token)
842
871
  return headers
843
872
 
844
- def login(self, username, password):
873
+ def login(self, username, password, create_session=True):
874
+ """Login to server.
875
+
876
+ Args:
877
+ username (str): Username.
878
+ password (str): Password.
879
+ create_session (Optional[bool]): Create session after login.
880
+ Default: True.
881
+
882
+ Raises:
883
+ AuthenticationError: Login failed.
884
+ """
885
+
845
886
  if self.has_valid_token:
846
887
  try:
847
888
  user_info = self.get_user()
@@ -851,7 +892,8 @@ class ServerAPI(object):
851
892
  current_username = user_info.get("name")
852
893
  if current_username == username:
853
894
  self.close_session()
854
- self.create_session()
895
+ if create_session:
896
+ self.create_session()
855
897
  return
856
898
 
857
899
  self.reset_token()
@@ -875,7 +917,9 @@ class ServerAPI(object):
875
917
 
876
918
  if not self.has_valid_token:
877
919
  raise AuthenticationError("Invalid credentials")
878
- self.create_session()
920
+
921
+ if create_session:
922
+ self.create_session()
879
923
 
880
924
  def logout(self, soft=False):
881
925
  if self._access_token:
@@ -888,6 +932,15 @@ class ServerAPI(object):
888
932
 
889
933
  def _do_rest_request(self, function, url, **kwargs):
890
934
  if self._session is None:
935
+ # Validate token if was not yet validated
936
+ # - ignore validation if we're in middle of
937
+ # validation
938
+ if (
939
+ self._token_is_valid is None
940
+ and not self._token_validation_started
941
+ ):
942
+ self.validate_token()
943
+
891
944
  if "headers" not in kwargs:
892
945
  kwargs["headers"] = self.get_headers()
893
946
 
@@ -1328,6 +1381,7 @@ class ServerAPI(object):
1328
1381
  response = post_func(url, data=stream, **kwargs)
1329
1382
  response.raise_for_status()
1330
1383
  progress.set_transferred_size(size)
1384
+ return response
1331
1385
 
1332
1386
  def upload_file(
1333
1387
  self, endpoint, filepath, progress=None, request_type=None
@@ -1344,6 +1398,9 @@ class ServerAPI(object):
1344
1398
  to track upload progress.
1345
1399
  request_type (Optional[RequestType]): Type of request that will
1346
1400
  be used to upload file.
1401
+
1402
+ Returns:
1403
+ requests.Response: Response object.
1347
1404
  """
1348
1405
 
1349
1406
  if endpoint.startswith(self._base_url):
@@ -1362,7 +1419,7 @@ class ServerAPI(object):
1362
1419
  progress.set_started()
1363
1420
 
1364
1421
  try:
1365
- self._upload_file(url, filepath, progress, request_type)
1422
+ return self._upload_file(url, filepath, progress, request_type)
1366
1423
 
1367
1424
  except Exception as exc:
1368
1425
  progress.set_failed(str(exc))
@@ -1640,7 +1697,7 @@ class ServerAPI(object):
1640
1697
  Args:
1641
1698
  addon_name (str): Name of addon.
1642
1699
  addon_version (str): Version of addon.
1643
- subpaths (tuple[str]): Any amount of subpaths that are added to
1700
+ *subpaths (str): Any amount of subpaths that are added to
1644
1701
  addon url.
1645
1702
 
1646
1703
  Returns:
@@ -1848,9 +1905,12 @@ class ServerAPI(object):
1848
1905
  dst_filename (str): Destination filename.
1849
1906
  progress (Optional[TransferProgress]): Object that gives ability
1850
1907
  to track download progress.
1908
+
1909
+ Returns:
1910
+ requests.Response: Response object.
1851
1911
  """
1852
1912
 
1853
- self.upload_file(
1913
+ return self.upload_file(
1854
1914
  "desktop/installers/{}".format(dst_filename),
1855
1915
  src_filepath,
1856
1916
  progress=progress
@@ -2162,6 +2222,33 @@ class ServerAPI(object):
2162
2222
 
2163
2223
  return create_dependency_package_basename(platform_name)
2164
2224
 
2225
+ def upload_addon_zip(self, src_filepath, progress=None):
2226
+ """Upload addon zip file to server.
2227
+
2228
+ File is validated on server. If it is valid, it is installed. It will
2229
+ create an event job which can be tracked (tracking part is not
2230
+ implemented yet).
2231
+
2232
+ Example output:
2233
+ {'eventId': 'a1bfbdee27c611eea7580242ac120003'}
2234
+
2235
+ Args:
2236
+ src_filepath (str): Path to a zip file.
2237
+ progress (Optional[TransferProgress]): Object to keep track about
2238
+ upload state.
2239
+
2240
+ Returns:
2241
+ dict[str, Any]: Response data from server.
2242
+ """
2243
+
2244
+ response = self.upload_file(
2245
+ "addons/install",
2246
+ src_filepath,
2247
+ progress=progress,
2248
+ request_type=RequestTypes.post,
2249
+ )
2250
+ return response.json()
2251
+
2165
2252
  def _get_bundles_route(self):
2166
2253
  major, minor, patch, _, _ = self.server_version_tuple
2167
2254
  # Backwards compatibility for AYON server 0.3.0
@@ -3051,6 +3138,65 @@ class ServerAPI(object):
3051
3138
  fill_own_attribs(project)
3052
3139
  return project
3053
3140
 
3141
+ def get_folders_hierarchy(
3142
+ self,
3143
+ project_name,
3144
+ search_string=None,
3145
+ folder_types=None
3146
+ ):
3147
+ """Get project hierarchy.
3148
+
3149
+ All folders in project in hierarchy data structure.
3150
+
3151
+ Example output:
3152
+ {
3153
+ "hierarchy": [
3154
+ {
3155
+ "id": "...",
3156
+ "name": "...",
3157
+ "label": "...",
3158
+ "status": "...",
3159
+ "folderType": "...",
3160
+ "hasTasks": False,
3161
+ "taskNames": [],
3162
+ "parents": [],
3163
+ "parentId": None,
3164
+ "children": [...children folders...]
3165
+ },
3166
+ ...
3167
+ ]
3168
+ }
3169
+
3170
+ Args:
3171
+ project_name (str): Project where to look for folders.
3172
+ search_string (Optional[str]): Search string to filter folders.
3173
+ folder_types (Optional[Iterable[str]]): Folder types to filter.
3174
+
3175
+ Returns:
3176
+ dict[str, Any]: Response data from server.
3177
+ """
3178
+
3179
+ if folder_types:
3180
+ folder_types = ",".join(folder_types)
3181
+
3182
+ query_fields = [
3183
+ "{}={}".format(key, value)
3184
+ for key, value in (
3185
+ ("search", search_string),
3186
+ ("types", folder_types),
3187
+ )
3188
+ if value
3189
+ ]
3190
+ query = ""
3191
+ if query_fields:
3192
+ query = "?{}".format(",".join(query_fields))
3193
+
3194
+ response = self.get(
3195
+ "projects/{}/hierarchy{}".format(project_name, query)
3196
+ )
3197
+ response.raise_for_status()
3198
+ return response.data
3199
+
3054
3200
  def get_folders(
3055
3201
  self,
3056
3202
  project_name,
@@ -3622,7 +3768,6 @@ class ServerAPI(object):
3622
3768
  if filtered_product is not None:
3623
3769
  yield filtered_product
3624
3770
 
3625
-
3626
3771
  def get_product_by_id(
3627
3772
  self,
3628
3773
  project_name,
@@ -359,7 +359,7 @@ class TransferProgress:
359
359
  def __init__(self):
360
360
  self._started = False
361
361
  self._transfer_done = False
362
- self._transfered = 0
362
+ self._transferred = 0
363
363
  self._content_size = None
364
364
 
365
365
  self._failed = False
@@ -369,25 +369,66 @@ class TransferProgress:
369
369
  self._destination_url = "N/A"
370
370
 
371
371
  def get_content_size(self):
372
+ """Content size in bytes.
373
+
374
+ Returns:
375
+ Union[int, None]: Content size in bytes or None
376
+ if is unknown.
377
+ """
378
+
372
379
  return self._content_size
373
380
 
374
381
  def set_content_size(self, content_size):
382
+ """Set content size in bytes.
383
+
384
+ Args:
385
+ content_size (int): Content size in bytes.
386
+
387
+ Raises:
388
+ ValueError: If content size was already set.
389
+ """
390
+
375
391
  if self._content_size is not None:
376
392
  raise ValueError("Content size was set more then once")
377
393
  self._content_size = content_size
378
394
 
379
395
  def get_started(self):
396
+ """Transfer was started.
397
+
398
+ Returns:
399
+ bool: True if transfer started.
400
+ """
401
+
380
402
  return self._started
381
403
 
382
404
  def set_started(self):
405
+ """Mark that transfer started.
406
+
407
+ Raises:
408
+ ValueError: If transfer was already started.
409
+ """
410
+
383
411
  if self._started:
384
412
  raise ValueError("Progress already started")
385
413
  self._started = True
386
414
 
387
415
  def get_transfer_done(self):
416
+ """Transfer finished.
417
+
418
+ Returns:
419
+ bool: Transfer finished.
420
+ """
421
+
388
422
  return self._transfer_done
389
423
 
390
424
  def set_transfer_done(self):
425
+ """Mark progress as transfer finished.
426
+
427
+ Raises:
428
+ ValueError: If progress was already marked as done
429
+ or wasn't started yet.
430
+ """
431
+
391
432
  if self._transfer_done:
392
433
  raise ValueError("Progress was already marked as done")
393
434
  if not self._started:
@@ -395,41 +436,117 @@ class TransferProgress:
395
436
  self._transfer_done = True
396
437
 
397
438
  def get_failed(self):
439
+ """Transfer failed.
440
+
441
+ Returns:
442
+ bool: True if transfer failed.
443
+ """
444
+
398
445
  return self._failed
399
446
 
400
447
  def get_fail_reason(self):
448
+ """Get reason why transfer failed.
449
+
450
+ Returns:
451
+ Union[str, None]: Reason why transfer
452
+ failed or None.
453
+ """
454
+
401
455
  return self._fail_reason
402
456
 
403
457
  def set_failed(self, reason):
458
+ """Mark progress as failed.
459
+
460
+ Args:
461
+ reason (str): Reason why transfer failed.
462
+ """
463
+
404
464
  self._fail_reason = reason
405
465
  self._failed = True
406
466
 
407
467
  def get_transferred_size(self):
408
- return self._transfered
468
+ """Already transferred size in bytes.
469
+
470
+ Returns:
471
+ int: Already transferred size in bytes.
472
+ """
409
473
 
410
- def set_transferred_size(self, transfered):
411
- self._transfered = transfered
474
+ return self._transferred
475
+
476
+ def set_transferred_size(self, transferred):
477
+ """Set already transferred size in bytes.
478
+
479
+ Args:
480
+ transferred (int): Already transferred size in bytes.
481
+ """
482
+
483
+ self._transferred = transferred
412
484
 
413
485
  def add_transferred_chunk(self, chunk_size):
414
- self._transfered += chunk_size
486
+ """Add transferred chunk size in bytes.
487
+
488
+ Args:
489
+ chunk_size (int): Add transferred chunk size
490
+ in bytes.
491
+ """
492
+
493
+ self._transferred += chunk_size
415
494
 
416
495
  def get_source_url(self):
496
+ """Source url from where transfer happens.
497
+
498
+ Note:
499
+ Consider this as title. Must be set using
500
+ 'set_source_url' or 'N/A' will be returned.
501
+
502
+ Returns:
503
+ str: Source url from where transfer happens.
504
+ """
505
+
417
506
  return self._source_url
418
507
 
419
508
  def set_source_url(self, url):
509
+ """Set source url from where transfer happens.
510
+
511
+ Args:
512
+ url (str): Source url from where transfer happens.
513
+ """
514
+
420
515
  self._source_url = url
421
516
 
422
517
  def get_destination_url(self):
518
+ """Destination url where transfer happens.
519
+
520
+ Note:
521
+ Consider this as title. Must be set using
522
+ 'set_source_url' or 'N/A' will be returned.
523
+
524
+ Returns:
525
+ str: Destination url where transfer happens.
526
+ """
527
+
423
528
  return self._destination_url
424
529
 
425
530
  def set_destination_url(self, url):
531
+ """Set destination url where transfer happens.
532
+
533
+ Args:
534
+ url (str): Destination url where transfer happens.
535
+ """
536
+
426
537
  self._destination_url = url
427
538
 
428
539
  @property
429
540
  def is_running(self):
541
+ """Check if transfer is running.
542
+
543
+ Returns:
544
+ bool: True if transfer is running.
545
+ """
546
+
430
547
  if (
431
548
  not self.started
432
- or self.done
549
+ or self.transfer_done
433
550
  or self.failed
434
551
  ):
435
552
  return False
@@ -437,9 +554,16 @@ class TransferProgress:
437
554
 
438
555
  @property
439
556
  def transfer_progress(self):
557
+ """Get transfer progress in percents.
558
+
559
+ Returns:
560
+ Union[float, None]: Transfer progress in percents or 'None'
561
+ if content size is unknown.
562
+ """
563
+
440
564
  if self._content_size is None:
441
565
  return None
442
- return (self._transfered * 100.0) / float(self._content_size)
566
+ return (self._transferred * 100.0) / float(self._content_size)
443
567
 
444
568
  content_size = property(get_content_size, set_content_size)
445
569
  started = property(get_started)
@@ -448,7 +572,6 @@ class TransferProgress:
448
572
  fail_reason = property(get_fail_reason)
449
573
  source_url = property(get_source_url, set_source_url)
450
574
  destination_url = property(get_destination_url, set_destination_url)
451
- content_size = property(get_content_size, set_content_size)
452
575
  transferred_size = property(get_transferred_size, set_transferred_size)
453
576
 
454
577
 
@@ -1,2 +1,2 @@
1
1
  """Package declaring Python API for Ayon server."""
2
- __version__ = "0.3.2"
2
+ __version__ = "0.3.3"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ayon-python-api
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: AYON Python API
5
5
  Home-page: https://github.com/ynput/ayon-python-api
6
6
  Author: ynput.io
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ayon-python-api"
3
- version = "0.3.2"
3
+ version = "0.3.3"
4
4
  description = "AYON Python API"
5
5
  license = {file = "LICENSE"}
6
6
  readme = {file = "README.md", content-type = "text/markdown"}
File without changes