Ayon-Python-Api 0.1.9__tar.gz → 0.1.10__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.9/ayon_python_api.egg-info → ayon-python-api-0.1.10}/PKG-INFO +6 -8
  2. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/README.md +6 -8
  3. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_api/__init__.py +2 -0
  4. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_api/constants.py +15 -0
  5. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_api/graphql_queries.py +33 -0
  6. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_api/server.py +85 -3
  7. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_api/server_api.py +5 -0
  8. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_api/version.py +1 -1
  9. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10/ayon_python_api.egg-info}/PKG-INFO +6 -8
  10. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_python_api.egg-info/requires.txt +1 -1
  11. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/pyproject.toml +2 -2
  12. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/setup.py +1 -1
  13. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/LICENSE +0 -0
  14. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_api/entity_hub.py +0 -0
  15. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_api/events.py +0 -0
  16. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_api/exceptions.py +0 -0
  17. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_api/graphql.py +0 -0
  18. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_api/operations.py +0 -0
  19. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_api/thumbnails.py +0 -0
  20. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_api/utils.py +0 -0
  21. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_python_api.egg-info/SOURCES.txt +0 -0
  22. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_python_api.egg-info/dependency_links.txt +0 -0
  23. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/ayon_python_api.egg-info/top_level.txt +0 -0
  24. {ayon-python-api-0.1.9 → ayon-python-api-0.1.10}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ayon-python-api
3
- Version: 0.1.9
3
+ Version: 0.1.10
4
4
  Summary: AYON Python API
5
5
  Home-page: https://github.com/ynput/ayon-python-api
6
6
  Author: ynput.io
@@ -9,20 +9,18 @@ License: Apache License (2.0)
9
9
  Description: # AYON server API
10
10
  Python client for connection server. Client must be (at least for some time) Python 2 compatible because will be used in DCC that are "older".
11
11
 
12
- Client should support connection to server with raw REST functions and prepared functionality for work with entities. Must not contain only functionality that can be used with core server functionality.
12
+ AYON Python api should support connection to server with raw REST functions and prepared functionality for work with entities. Must not contain only functionality that can be used with core server functionality.
13
13
 
14
+ Module support singleton connection which is using `AYON_SERVER_URL` and `AYON_TOKEN` environment variables as source for connection. The singleton connection is using `ServerAPI` object. There can be created multiple connection to different server at one time, for that purpose use `ServerAPIBase` object.
14
15
 
15
16
  ## TODOs
16
- - Current implementation contains prepared functions for entity queries which is not using full potential of OpenPype server but is MongoDB compatible.
17
- - only functions related to v4 should stay at that place and v3 compatible functions should be moved
18
- - Missing settings getter
19
- - Missing CRUD operations for entities (Only read is possible)
20
- - More clear what is difference in `ServerAPIBase` and `ServerAPI`
17
+ - More clear what is difference in `ServerAPIBase` and `ServerAPI` (`server.py` and `server_api.py`) and better names
21
18
  - `ServerAPI` was added primarily for desktop app which handle login and logout in a different way so the class should be maybe removed and `ServerAPIBase` should be renamed to `ServerAPI`
22
19
  - find more suitable names of classes
23
- - find more suitable name of objects (right now is used `connection` or `conn`)
20
+ - find more suitable name of objects (right now is used `connection` or `con`)
24
21
  - Add folder and task changes to operations
25
22
  - Entity hub should use operations to update folders and tasks
23
+
26
24
  Keywords: AYON,ynput,OpenPype,vfx
27
25
  Platform: UNKNOWN
28
26
  Classifier: Development Status :: 3 - Alpha
@@ -1,17 +1,15 @@
1
1
  # AYON server API
2
2
  Python client for connection server. Client must be (at least for some time) Python 2 compatible because will be used in DCC that are "older".
3
3
 
4
- Client should support connection to server with raw REST functions and prepared functionality for work with entities. Must not contain only functionality that can be used with core server functionality.
4
+ AYON Python api should support connection to server with raw REST functions and prepared functionality for work with entities. Must not contain only functionality that can be used with core server functionality.
5
5
 
6
+ Module support singleton connection which is using `AYON_SERVER_URL` and `AYON_TOKEN` environment variables as source for connection. The singleton connection is using `ServerAPI` object. There can be created multiple connection to different server at one time, for that purpose use `ServerAPIBase` object.
6
7
 
7
8
  ## TODOs
8
- - Current implementation contains prepared functions for entity queries which is not using full potential of OpenPype server but is MongoDB compatible.
9
- - only functions related to v4 should stay at that place and v3 compatible functions should be moved
10
- - Missing settings getter
11
- - Missing CRUD operations for entities (Only read is possible)
12
- - More clear what is difference in `ServerAPIBase` and `ServerAPI`
9
+ - More clear what is difference in `ServerAPIBase` and `ServerAPI` (`server.py` and `server_api.py`) and better names
13
10
  - `ServerAPI` was added primarily for desktop app which handle login and logout in a different way so the class should be maybe removed and `ServerAPIBase` should be renamed to `ServerAPI`
14
11
  - find more suitable names of classes
15
- - find more suitable name of objects (right now is used `connection` or `conn`)
12
+ - find more suitable name of objects (right now is used `connection` or `con`)
16
13
  - Add folder and task changes to operations
17
- - Entity hub should use operations to update folders and tasks
14
+ - Entity hub should use operations to update folders and tasks
15
+
@@ -34,6 +34,7 @@ from .server_api import (
34
34
  delete,
35
35
 
36
36
  get_event,
37
+ get_events,
37
38
  dispatch_event,
38
39
  update_event,
39
40
  enroll_event_job,
@@ -142,6 +143,7 @@ __all__ = (
142
143
  "delete",
143
144
 
144
145
  "get_event",
146
+ "get_events",
145
147
  "dispatch_event",
146
148
  "update_event",
147
149
  "enroll_event_job",
@@ -88,3 +88,18 @@ DEFAULT_WORKFILE_INFO_FIELDS = {
88
88
  "updatedAt",
89
89
  "updatedBy",
90
90
  }
91
+
92
+ DEFAULT_EVENT_FIELDS = {
93
+ "id",
94
+ "hash",
95
+ "createdAt",
96
+ "dependsOn",
97
+ "description",
98
+ "project",
99
+ "retries",
100
+ "sender",
101
+ "status",
102
+ "topic",
103
+ "updatedAt",
104
+ "user",
105
+ }
@@ -327,3 +327,36 @@ def workfiles_info_graphql_query(fields):
327
327
  for k, v in value.items():
328
328
  query_queue.append((k, v, field))
329
329
  return query
330
+
331
+
332
+ def events_graphql_query(fields):
333
+ query = GraphQlQuery("WorkfilesInfo")
334
+ topics_var = query.add_variable("eventTopics", "[String!]")
335
+ projects_var = query.add_variable("projectNames", "[String!]")
336
+ states_var = query.add_variable("eventStates", "[String!]")
337
+ users_var = query.add_variable("eventUsers", "[String!]")
338
+ include_logs_var = query.add_variable("includeLogsFilter", "Boolean!")
339
+
340
+ events_field = query.add_field("events", has_edges=True)
341
+ events_field.set_filter("topics", topics_var)
342
+ events_field.set_filter("projects", projects_var)
343
+ events_field.set_filter("states", states_var)
344
+ events_field.set_filter("users", users_var)
345
+ events_field.set_filter("includeLogs", include_logs_var)
346
+
347
+ nested_fields = fields_to_dict(set(fields))
348
+
349
+ query_queue = collections.deque()
350
+ for key, value in nested_fields.items():
351
+ query_queue.append((key, value, events_field))
352
+
353
+ while query_queue:
354
+ item = query_queue.popleft()
355
+ key, value, parent = item
356
+ field = parent.add_field(key)
357
+ if value is FIELD_VALUE:
358
+ continue
359
+
360
+ for k, v in value.items():
361
+ query_queue.append((k, v, field))
362
+ return query
@@ -6,7 +6,10 @@ import logging
6
6
  import collections
7
7
  import platform
8
8
  import copy
9
- from http import HTTPStatus
9
+ try:
10
+ from http import HTTPStatus
11
+ except ImportError:
12
+ HTTPStatus = None
10
13
 
11
14
  import requests
12
15
 
@@ -19,6 +22,7 @@ from .constants import (
19
22
  DEFAULT_REPRESENTATION_FIELDS,
20
23
  REPRESENTATION_FILES_FIELDS,
21
24
  DEFAULT_WORKFILE_INFO_FIELDS,
25
+ DEFAULT_EVENT_FIELDS,
22
26
  )
23
27
  from .thumbnails import ThumbnailCache
24
28
  from .graphql import GraphQlQuery, INTROSPECTION_QUERY
@@ -32,6 +36,7 @@ from .graphql_queries import (
32
36
  representations_graphql_query,
33
37
  representations_parents_qraphql_query,
34
38
  workfiles_info_graphql_query,
39
+ events_graphql_query,
35
40
  )
36
41
  from .exceptions import (
37
42
  FailedOperations,
@@ -56,6 +61,12 @@ PROJECT_NAME_REGEX = re.compile(
56
61
  )
57
62
 
58
63
 
64
+ def _get_description(response):
65
+ if HTTPStatus is None:
66
+ return str(response.orig_response)
67
+ return HTTPStatus(response.status).description
68
+
69
+
59
70
  class RequestType:
60
71
  def __init__(self, name):
61
72
  self.name = name
@@ -95,7 +106,10 @@ class RestApiResponse(object):
95
106
  @property
96
107
  def data(self):
97
108
  if self._data is None:
98
- self._data = self._response.json()
109
+ if self.status != 204:
110
+ self._data = self.orig_response.json()
111
+ else:
112
+ self._data = {}
99
113
  return self._data
100
114
 
101
115
  @property
@@ -108,7 +122,7 @@ class RestApiResponse(object):
108
122
 
109
123
  @property
110
124
  def detail(self):
111
- return self.get("detail", HTTPStatus(self.status).description)
125
+ return self.get("detail", _get_description(self))
112
126
 
113
127
  @property
114
128
  def status_code(self):
@@ -586,6 +600,74 @@ class ServerAPIBase(object):
586
600
  response.raise_for_status()
587
601
  return response.data
588
602
 
603
+ def get_events(
604
+ self,
605
+ topics=None,
606
+ project_names=None,
607
+ states=None,
608
+ users=None,
609
+ include_logs=None,
610
+ fields=None
611
+ ):
612
+ """Get events from server with filtering options.
613
+
614
+ Notes:
615
+ Not all event happen on a project.
616
+
617
+ Args:
618
+ topics (Iterable[str]): Name of topics.
619
+ project_names (Iterable[str]): Project on which event happened.
620
+ states (Iterable[str]): Filtering by states.
621
+ users (Iterable[str]): Filtering by users who created/triggered
622
+ an event.
623
+ include_logs (bool): Query also log events.
624
+ fields (Iterable[str]): Fields that should be received for each
625
+ event.
626
+
627
+ Returns:
628
+ Generator[Dict[str, Any]]: Available events matching filters.
629
+ """
630
+
631
+ filters = {}
632
+ if topics is not None:
633
+ topics = set(topics)
634
+ if not topics:
635
+ return
636
+ filters["eventTopics"] = list(topics)
637
+
638
+ if project_names is not None:
639
+ project_names = set(project_names)
640
+ if not project_names:
641
+ return
642
+ filters["projectName"] = list(project_names)
643
+
644
+ if states is not None:
645
+ states = set(states)
646
+ if not states:
647
+ return
648
+ filters["eventStates"] = list(states)
649
+
650
+ if users is not None:
651
+ users = set(users)
652
+ if not users:
653
+ return
654
+ filters["eventUsers"] = list(users)
655
+
656
+ if include_logs is None:
657
+ include_logs = False
658
+ filters["includeLogsFilter"] = include_logs
659
+
660
+ if not fields:
661
+ fields = DEFAULT_EVENT_FIELDS
662
+
663
+ query = events_graphql_query(set(fields))
664
+ for attr, filter_value in filters.items():
665
+ query.set_variable_value(attr, filter_value)
666
+
667
+ for parsed_data in query.continuous_query(self):
668
+ for event in parsed_data["events"]:
669
+ yield event
670
+
589
671
  def update_event(
590
672
  self,
591
673
  event_id,
@@ -302,6 +302,11 @@ def get_event(*args, **kwargs):
302
302
  return con.get_event(*args, **kwargs)
303
303
 
304
304
 
305
+ def get_events(*args, **kwargs):
306
+ con = get_server_api_connection()
307
+ return con.get_events(*args, **kwargs)
308
+
309
+
305
310
  def dispatch_event(*args, **kwargs):
306
311
  con = get_server_api_connection()
307
312
  return con.dispatch_event(*args, **kwargs)
@@ -1,2 +1,2 @@
1
1
  """Package declaring Python API for Ayon server."""
2
- __version__ = "0.1.9"
2
+ __version__ = "0.1.10"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ayon-python-api
3
- Version: 0.1.9
3
+ Version: 0.1.10
4
4
  Summary: AYON Python API
5
5
  Home-page: https://github.com/ynput/ayon-python-api
6
6
  Author: ynput.io
@@ -9,20 +9,18 @@ License: Apache License (2.0)
9
9
  Description: # AYON server API
10
10
  Python client for connection server. Client must be (at least for some time) Python 2 compatible because will be used in DCC that are "older".
11
11
 
12
- Client should support connection to server with raw REST functions and prepared functionality for work with entities. Must not contain only functionality that can be used with core server functionality.
12
+ AYON Python api should support connection to server with raw REST functions and prepared functionality for work with entities. Must not contain only functionality that can be used with core server functionality.
13
13
 
14
+ Module support singleton connection which is using `AYON_SERVER_URL` and `AYON_TOKEN` environment variables as source for connection. The singleton connection is using `ServerAPI` object. There can be created multiple connection to different server at one time, for that purpose use `ServerAPIBase` object.
14
15
 
15
16
  ## TODOs
16
- - Current implementation contains prepared functions for entity queries which is not using full potential of OpenPype server but is MongoDB compatible.
17
- - only functions related to v4 should stay at that place and v3 compatible functions should be moved
18
- - Missing settings getter
19
- - Missing CRUD operations for entities (Only read is possible)
20
- - More clear what is difference in `ServerAPIBase` and `ServerAPI`
17
+ - More clear what is difference in `ServerAPIBase` and `ServerAPI` (`server.py` and `server_api.py`) and better names
21
18
  - `ServerAPI` was added primarily for desktop app which handle login and logout in a different way so the class should be maybe removed and `ServerAPIBase` should be renamed to `ServerAPI`
22
19
  - find more suitable names of classes
23
- - find more suitable name of objects (right now is used `connection` or `conn`)
20
+ - find more suitable name of objects (right now is used `connection` or `con`)
24
21
  - Add folder and task changes to operations
25
22
  - Entity hub should use operations to update folders and tasks
23
+
26
24
  Keywords: AYON,ynput,OpenPype,vfx
27
25
  Platform: UNKNOWN
28
26
  Classifier: Development Status :: 3 - Alpha
@@ -1,4 +1,4 @@
1
1
  requests>=2.27.1
2
2
  six>=1.15
3
- Unidecode>=1.3.6
3
+ Unidecode>=1.2.0
4
4
  appdirs<2,>=1
@@ -1,13 +1,13 @@
1
1
  [tool.poetry]
2
2
  name = "ayon_api"
3
- version = "0.1.9"
3
+ version = "0.1.10"
4
4
  description = "Python api for AYON server"
5
5
  authors = ["ynput.io <info@ynput.io>"]
6
6
 
7
7
  [tool.poetry.dependencies]
8
8
  requests = "^2.28.1"
9
9
  six = "^1.15"
10
- Unidecode = "^1.3"
10
+ Unidecode = "^1.2"
11
11
  appdirs = "^1.4"
12
12
 
13
13
  [tool.poetry.dev-dependencies]
@@ -30,7 +30,7 @@ setup(
30
30
  install_requires=[
31
31
  "requests >= 2.27.1",
32
32
  "six >= 1.15",
33
- "Unidecode >= 1.3.6",
33
+ "Unidecode >= 1.2.0",
34
34
  "appdirs >=1, <2",
35
35
  ],
36
36
  keywords=["AYON", "ynput", "OpenPype", "vfx"],