Skip to content

Commit

Permalink
Merge pull request #123 from ProdPerfect/items-page-update
Browse files Browse the repository at this point in the history
Items Page Update
  • Loading branch information
pevner-p2 authored Dec 16, 2023
2 parents 898e3c1 + 0855688 commit 540b059
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 45 deletions.
2 changes: 1 addition & 1 deletion monday/__version__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__version__ = '2.0.0rc2'
__version__ = '2.0.0rc3'
__author__ = 'Christina D\'Astolfo'
__email__ = 'chdastolfo@gmail.com, lemi@prodperfect.com, pevner@prodperfect.com'
48 changes: 29 additions & 19 deletions monday/query_joins.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json
from enum import Enum
from typing import List, Union, Optional, Mapping
from typing import List, Union, Optional, Mapping, Any

from monday.resources.types import BoardKind, BoardState, BoardsOrderBy, DuplicateType, ColumnType
from monday.utils import monday_json_stringify, gather_params
Expand Down Expand Up @@ -58,13 +58,15 @@ def mutate_subitem_query(parent_item_id, subitem_name, column_values,
str(create_labels_if_missing).lower())


def get_item_query(board_id, column_id, value):
def get_item_query(board_id, column_id, value, limit=None, cursor=None):
columns = [{"column_id": str(column_id), "column_values": [str(value)]}] if not cursor else None

raw_params = locals().items()
items_page_params = gather_params(raw_params, excluded_params=["column_id", "value"])

query = '''query
{
items_page_by_column_values(
board_id: %s,
columns: [{column_id: "%s", column_values: ["%s"]}]
) {
items_page_by_column_values (%s) {
cursor
items {
id
Expand All @@ -84,7 +86,7 @@ def get_item_query(board_id, column_id, value):
}
}
}
}''' % (board_id, column_id, value)
}''' % items_page_params

return query

Expand Down Expand Up @@ -116,7 +118,7 @@ def update_item_query(board_id, item_id, column_id, value):
change_column_value(
board_id: %s,
item_id: %s,
column_id: %s,
column_id: "%s",
value: %s
) {
id
Expand All @@ -136,7 +138,7 @@ def move_item_to_group_query(item_id, group_id):
query = '''
mutation
{
move_item_to_group (item_id: %s, group_id: %s)
move_item_to_group (item_id: %s, group_id: "%s")
{
id
}
Expand Down Expand Up @@ -250,7 +252,7 @@ def add_file_to_column_query(item_id, column_id):
add_file_to_column (
file: $file,
item_id: %s,
column_id: %s
column_id: "%s"
) {
id
}
Expand Down Expand Up @@ -354,16 +356,18 @@ def get_tags_query(tags):


# BOARD RESOURCE QUERIES
def get_board_items_query(board_id: Union[str, int], limit: Optional[int] = None, page: Optional[int] = None) -> str:
def get_board_items_query(board_id: Union[str, int], query_params: Optional[Mapping[str, Any]] = None,
limit: Optional[int] = None, cursor: Optional[str] = None) -> str:
raw_params = locals().items()
item_params = gather_params(raw_params, exclusion_list=["board_id", "item_ids"])
joined_params = f"({', '.join(item_params)})" if item_params else ""
items_page_params = gather_params(raw_params, excluded_params=["board_id"])
wrapped_params = f"({items_page_params})" if items_page_params else ""

query = '''query{
boards(ids: %s){
name
items_page {
items %s {
items_page %s {
cursor
items {
group {
id
title
Expand All @@ -379,7 +383,7 @@ def get_board_items_query(board_id: Union[str, int], limit: Optional[int] = None
}
}
}
}''' % (board_id, joined_params)
}''' % (board_id, wrapped_params)

return query

Expand Down Expand Up @@ -520,22 +524,28 @@ def get_groups_by_board_query(board_ids):
return query


def get_items_by_group_query(board_id, group_id):
def get_items_by_group_query(board_id: Union[int, str], group_id: str,
limit: Optional[int] = None, cursor: Optional[str] = None):
raw_params = locals().items()
items_page_params = gather_params(raw_params, excluded_params=["board_id", "group_id"])
wrapped_params = f"({items_page_params})" if items_page_params else ""

query = '''query
{
boards(ids: %s) {
groups(ids: "%s") {
id
title
items_page {
items_page %s {
cursor
items {
id
name
}
}
}
}
}''' % (board_id, group_id)
}''' % (board_id, group_id, wrapped_params)
return query


Expand Down
11 changes: 6 additions & 5 deletions monday/resources/boards.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, Optional
from typing import List, Optional, Union, Any, Mapping

from monday.query_joins import get_boards_query, get_boards_by_id_query, get_board_items_query, \
get_columns_by_board_query, create_board_by_workspace_query, duplicate_board_query
Expand All @@ -13,15 +13,16 @@ def fetch_boards(self, limit: Optional[int] = None, page: Optional[int] = None,
query = get_boards_query(limit, page, ids, board_kind, state, order_by)
return self.client.execute(query)

def fetch_boards_by_id(self, board_ids):
def fetch_boards_by_id(self, board_ids: Union[int, str]):
query = get_boards_by_id_query(board_ids)
return self.client.execute(query)

def fetch_items_by_board_id(self, board_ids, limit: Optional[int] = None, page: Optional[int] = None):
query = get_board_items_query(board_ids, limit=limit, page=page)
def fetch_items_by_board_id(self, board_ids: Union[int, str], query_params: Optional[Mapping[str, Any]] = None,
limit: Optional[int] = None, cursor: Optional[str] = None):
query = get_board_items_query(board_ids, query_params=query_params, limit=limit, cursor=cursor)
return self.client.execute(query)

def fetch_columns_by_board_id(self, board_ids):
def fetch_columns_by_board_id(self, board_ids: Union[int, str]):
query = get_columns_by_board_query(board_ids)
return self.client.execute(query)

Expand Down
4 changes: 2 additions & 2 deletions monday/resources/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ def get_groups_by_board(self, board_ids):
query = get_groups_by_board_query(board_ids=board_ids)
return self.client.execute(query)

def get_items_by_group(self, board_id, group_id):
query = get_items_by_group_query(board_id=board_id, group_id=group_id)
def get_items_by_group(self, board_id, group_id, limit=None, cursor=None):
query = get_items_by_group_query(board_id=board_id, group_id=group_id, limit=limit, cursor=cursor)
return self.client.execute(query)

def create_group(self, board_id, group_name):
Expand Down
4 changes: 2 additions & 2 deletions monday/resources/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def create_subitem(self, parent_item_id, subitem_name, column_values=None,
create_labels_if_missing)
return self.client.execute(query)

def fetch_items_by_column_value(self, board_id, column_id, value):
query = get_item_query(board_id, column_id, value)
def fetch_items_by_column_value(self, board_id, column_id, value, limit=None, cursor=None):
query = get_item_query(board_id, column_id, value, limit, cursor)
return self.client.execute(query)

def fetch_items_by_id(self, ids):
Expand Down
35 changes: 35 additions & 0 deletions monday/resources/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,38 @@ class BoardsOrderBy(Enum):

CREATED_AT = "created_at"
USED_AT = "used_at"


class ItemsQueryOperator(Enum):
"""Conditions between query rules"""

AND = "and"
OR = "or"


class ItemsOrderByDirection(Enum):
"""Direction to sort items in"""

ASC = "asc"
DESC = "desc"


class ItemsQueryRuleOperator(Enum):
"""Condition for value comparison"""

ANY_OF = "any_of"
NOT_ANY_OF = "not_any_of"
IS_EMPTY = "is_empty"
IS_NOT_EMPTY = "is_not_empty"
GREATER_THAN = "greater_than"
GREATER_THAN_OR_EQUALS = "greater_than_or_equals"
LOWER_THAN = "lower_than"
LOWER_THAN_OR_EQUAL = "lower_than_or_equal"
BETWEEN = "between"
NOT_CONTAINS_TEXT = "not_contains_text"
CONTAINS_TEXT = "contains_text"
CONTAINS_TERMS = "contains_terms"
STARTS_WITH = "starts_with"
ENDS_WITH = "ends_with"
WITHIN_THE_NEXT = "within_the_next"
WITHIN_THE_LAST = "within_the_last"
27 changes: 22 additions & 5 deletions monday/tests/test_board_resource.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from monday.query_joins import duplicate_board_query, create_board_by_workspace_query, get_boards_query, \
get_boards_by_id_query, get_board_items_query, get_columns_by_board_query
from monday.resources.types import ItemsQueryRuleOperator
from monday.tests.test_case_resource import BaseTestCase


Expand Down Expand Up @@ -41,12 +42,28 @@ def test_get_board_items_query(self):
items_line = 'items'
self.assertIn(items_line, query)

def test_get_board_items_query_with_limit_and_pages(self):
def test_get_board_items_query_with_limit_and_cursor(self):
limit = 100
page = 1
query = get_board_items_query(board_id=self.board_id, limit=limit, page=page)
items_line = f'items (limit: {limit}, page: {page})'
self.assertIn(items_line, query)
cursor = 'MSw0NTc5ODYzMTkyLFRWX2ljOWt2MVpnT...'
query = get_board_items_query(board_id=self.board_id, limit=limit, cursor=cursor)
items_page_line = f'items_page (limit: {limit}, cursor: "{cursor}")'
self.assertIn(items_page_line, query)

def test_get_board_items_query_with_query_params(self):
query_params = {
'rules': {
'column_id': 'timeline',
'compare_value': ['2023-06-30', '2023-07-01'],
'compare_attribute': 'START_DATE',
'operator': ItemsQueryRuleOperator.BETWEEN
}}
query = get_board_items_query(board_id=self.board_id, query_params=query_params)
items_page_line = ('items_page (query_params: {rules: {'
'column_id: "timeline", '
'compare_value: ["2023-06-30", "2023-07-01"], '
'compare_attribute: "START_DATE", '
'operator: between}')
self.assertIn(items_page_line, query)

def test_get_columns_by_board_query(self):
query = get_columns_by_board_query(board_ids=self.board_id)
Expand Down
7 changes: 7 additions & 0 deletions monday/tests/test_group_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ def test_get_items_by_group_query(self):
self.assertIn(str(self.board_id), query)
self.assertIn(str(self.group_id), query)

def test_get_items_by_group_query_with_limit_and_cursor(self):
limit = 25
cursor = 'MSw5NzI4MDA5MDAsaV9YcmxJb0p1VEdY...'
query = get_items_by_group_query(board_id=self.board_id, group_id=self.group_id, limit=limit, cursor=cursor)
items_page_line = f'items_page (limit: {limit}, cursor: "{cursor}")'
self.assertIn(items_page_line, query)

def test_duplicate_group_query(self):
query = duplicate_group_query(board_id=self.board_id, group_id=self.group_id)
self.assertIn(str(self.board_id), query)
Expand Down
9 changes: 9 additions & 0 deletions monday/tests/test_item_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ def test_get_item_query(self):
self.assertIn(self.column_id, query)
self.assertIn("foo", query)

def test_get_item_query_with_limit_and_cursor(self):
limit = 10
cursor = "MSw0NTc5ODYzMTkyLFRWX2ljOW..."
query = get_item_query(board_id=self.board_id, column_id=None, value="foo", limit=limit, cursor=cursor)
items_page_line = f'items_page_by_column_values (board_id: {self.board_id}, limit: {limit}, cursor: "{cursor}")'
self.assertIn(items_page_line, query)
self.assertNotIn(self.column_id, query)
self.assertNotIn("foo", query)

def test_update_item_query(self):
query = update_item_query(
board_id=self.board_id, item_id=self.item_id, column_id=self.column_id, value="foo")
Expand Down
31 changes: 20 additions & 11 deletions monday/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json
from enum import Enum
from typing import List
from typing import List, Iterable, Tuple, Any, Optional


def monday_json_stringify(value):
Expand All @@ -13,13 +13,22 @@ def monday_json_stringify(value):
return json.dumps(json.dumps(value))


def gather_params(params, exclusion_list: List[str]) -> List[str]:
valid_params: List[str] = []
for param, value in params:
if value is None or param in exclusion_list:
continue
if isinstance(value, Enum):
valid_params.append(f"{param}: {value.value}")
continue
valid_params.append(f"{param}: {value}")
return valid_params
def gather_params(params: Iterable[Tuple[str, Any]], excluded_params: Optional[List[str]] = None,
exclude_none: bool = True) -> str:
valid_params = [f"{param}: {format_param_value(value)}" for param, value in params
if not ((excluded_params and param in excluded_params) or (value is None and exclude_none))]
return ', '.join(valid_params)


def format_param_value(value: Any) -> str:
if value is None:
return 'null'
if isinstance(value, str):
return f'"{value}"'
if isinstance(value, Enum):
return str(value.value)
if isinstance(value, dict):
return f"{{{gather_params(value.items(), exclude_none=False)}}}"
if isinstance(value, list):
return f"[{', '.join(format_param_value(val) for val in value)}]"
return str(value)

0 comments on commit 540b059

Please sign in to comment.