Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions airbyte-integrations/connectors/source-monday/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ def extract_records(self, response: requests.Response) -> Iterable[Mapping[str,
@dataclass(kw_only=True)
class MondayGraphqlRequester(HttpRequester):
NEXT_PAGE_TOKEN_FIELD_NAME = "next_page_token"
# Fields that only exist on the TimelineValue implementation of the ColumnValue interface,
# and therefore must be requested through an inline fragment.
TIMELINE_VALUE_FIELDS = ("from", "to", "visualization_type", "updated_at")

schema_loader: InlineSchemaLoader
limit: Union[InterpolatedString, str, int] = None
Expand Down Expand Up @@ -193,20 +196,30 @@ def _build_query(self, object_name: str, field_schema: dict, **object_arguments)
if "ids" not in object_arguments:
object_arguments["ids"] = self.config.get("board_ids")

if object_name == "column_values":
# Columns with rollup capability on multi-level boards return an empty array unless
# calculated values are requested explicitly.
object_arguments["capabilities"] = "[CALCULATED]"

arguments = self._get_object_arguments(**object_arguments)
arguments = f"({arguments})" if arguments else ""

if object_name == "column_values":
fields.remove("display_value")
if "linked_item_ids" in fields:
fields.remove("linked_item_ids")
timeline_fields = [field for field in self.TIMELINE_VALUE_FIELDS if field in fields]
for field in timeline_fields:
fields.remove(field)
fields.extend(
[
"... on MirrorValue{display_value}",
"... on BoardRelationValue{display_value,linked_item_ids}",
"... on DependencyValue{display_value,linked_item_ids}",
]
)
if timeline_fields:
fields.append("... on TimelineValue{" + ",".join(timeline_fields) + "}")

fields = ",".join(fields)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{"stream": "items", "data": {"id": "4635211945", "name": "Item 1", "assets": [], "board": {"id": "4635211873"}, "column_values": [{"id": "person", "text": "", "type": "people", "value": null}, {"id": "status", "text": "Working on it", "type": "status", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2019-03-01T17:24:57.321Z\"}"}, {"id": "date4", "text": "2023-06-11", "type": "date", "value": "{\"date\":\"2023-06-11\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:25.871Z\"}"}, {"id": "tags", "text": "open", "type": "tags", "value": "{\"tag_ids\":[19038090]}"}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "topics"}, "parent_item": null, "state": "active", "subscribers": [{"id": "36694549"}], "updated_at": "2023-06-13T13:59:32Z", "updates": [{"id": "2223820299"}, {"id": "2223818363"}], "updated_at_int": 1686664772}, "emitted_at": 1708603933827}
{"stream": "items", "data": {"id": "4635211945", "name": "Item 1", "assets": [], "board": {"id": "4635211873"}, "column_values": [{"id": "person", "text": "", "type": "people", "value": null, "is_leaf": false}, {"id": "status", "text": "Working on it", "type": "status", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2019-03-01T17:24:57.321Z\"}", "is_leaf": false}, {"id": "date4", "text": "2023-06-11", "type": "date", "value": "{\"date\":\"2023-06-11\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:25.871Z\"}", "is_leaf": false}, {"id": "tags", "text": "open", "type": "tags", "value": "{\"tag_ids\":[19038090]}", "is_leaf": false}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "topics"}, "parent_item": null, "state": "active", "subscribers": [{"id": "36694549"}], "updated_at": "2023-06-13T13:59:32Z", "updates": [{"id": "2223820299"}, {"id": "2223818363"}], "updated_at_int": 1686664772}, "emitted_at": 1708603933827}
{"stream": "boards", "data": {"id": "3555407826", "name": "Procurement process", "board_kind": "public", "type": "board", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 380}, {"archived": false, "description": null, "id": "manager1", "settings_str": "{}", "title": "Owner", "type": "people", "width": 80}, {"archived": false, "description": null, "id": "date4", "settings_str": "{}", "title": "Request date", "type": "date", "width": null}, {"archived": false, "description": null, "id": "status1", "settings_str": "{\"done_colors\":[1],\"labels\":{\"0\":\"Evaluating\",\"1\":\"Done\",\"2\":\"Denied\",\"3\":\"Waiting for legal\",\"6\":\"Approved for POC\",\"11\":\"On hold\",\"14\":\"Waiting for vendor\",\"15\":\"Negotiation\",\"108\":\"Approved for use\"},\"labels_positions_v2\":{\"0\":0,\"1\":1,\"2\":7,\"3\":8,\"5\":9,\"6\":3,\"11\":6,\"14\":5,\"15\":4,\"108\":2},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"3\":{\"color\":\"#0086c0\",\"border\":\"#3DB0DF\",\"var_name\":\"blue-links\"},\"6\":{\"color\":\"#037f4c\",\"border\":\"#006B38\",\"var_name\":\"grass-green\"},\"11\":{\"color\":\"#BB3354\",\"border\":\"#A42D4A\",\"var_name\":\"dark-red\"},\"14\":{\"color\":\"#784BD1\",\"border\":\"#8F4DC4\",\"var_name\":\"dark-purple\"},\"15\":{\"color\":\"#9CD326\",\"border\":\"#89B921\",\"var_name\":\"lime-green\"},\"108\":{\"color\":\"#4eccc6\",\"border\":\"#4eccc6\",\"var_name\":\"australia\"}}}", "title": "Procurement status", "type": "status", "width": null}, {"archived": false, "description": null, "id": "person", "settings_str": "{}", "title": "Manager", "type": "people", "width": 80}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"done_colors\":[1],\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Manager approval", "type": "status", "width": null}, {"archived": false, "description": null, "id": "budget_owner", "settings_str": "{}", "title": "POC owner", "type": "people", "width": 80}, {"archived": false, "description": null, "id": "budget_owner_approval4", "settings_str": "{\"done_colors\":[1],\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "POC status", "type": "status", "width": null}, {"archived": false, "description": null, "id": "manager", "settings_str": "{}", "title": "Budget owner", "type": "people", "width": 80}, {"archived": false, "description": null, "id": "status4", "settings_str": "{\"done_colors\":[1],\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Budget owner approval", "type": "status", "width": 185}, {"archived": false, "description": null, "id": "people", "settings_str": "{}", "title": "Procurement team", "type": "people", "width": null}, {"archived": false, "description": null, "id": "budget_owner_approval", "settings_str": "{\"done_colors\":[1],\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Procurement approval", "type": "status", "width": null}, {"archived": false, "description": null, "id": "procurement_team", "settings_str": "{}", "title": "Finance", "type": "people", "width": null}, {"archived": false, "description": null, "id": "procurement_approval", "settings_str": "{\"done_colors\":[1],\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Finance approval", "type": "status", "width": null}, {"archived": false, "description": null, "id": "finance", "settings_str": "{}", "title": "Legal", "type": "people", "width": null}, {"archived": false, "description": null, "id": "finance_approval", "settings_str": "{\"done_colors\":[1],\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Redlines\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Legal approval", "type": "status", "width": null}, {"archived": false, "description": null, "id": "file", "settings_str": "{}", "title": "File", "type": "file", "width": null}, {"archived": false, "description": null, "id": "legal", "settings_str": "{}", "title": "Security", "type": "people", "width": null}, {"archived": false, "description": null, "id": "legal_approval", "settings_str": "{\"done_colors\":[1],\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Security approval", "type": "status", "width": null}, {"archived": false, "description": null, "id": "date", "settings_str": "{\"hide_footer\":false}", "title": "Renewal date", "type": "date", "width": null}, {"archived": false, "description": null, "id": "last_updated", "settings_str": "{}", "title": "Last updated", "type": "last_updated", "width": 129}], "communication": null, "description": "Many IT departments need to handle the procurement process for new services. The essence of this board is to streamline this process by providing an intuitive structure that supports collaboration and efficiency.", "groups": [{"archived": false, "color": "#579bfc", "deleted": false, "id": "topics", "position": "65536", "title": "Reviewing"}, {"archived": false, "color": "#FF642E", "deleted": false, "id": "new_group", "position": "98304.0", "title": "Corporate IT"}, {"archived": false, "color": "#037f4c", "deleted": false, "id": "new_group2816", "position": "114688.0", "title": "Finance"}], "owners": [{"id": "36694549"}], "creator": {"id": "36694549"}, "permissions": "everyone", "state": "active", "subscribers": [{"id": "36694549"}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2022-11-21T14:36:50Z", "updates": [], "views": [], "workspace": null, "updated_at_int": 1669041410}, "emitted_at": 1705073472066}
{"stream": "tags", "data": {"color": "#00c875", "id": "19038090", "name": "open"}, "emitted_at": 1690884065804}
{"stream": "tags", "data": {"color": "#fdab3d", "id": "19038091", "name": "closed"}, "emitted_at": 1690884065806}
Expand Down
23 changes: 23 additions & 0 deletions airbyte-integrations/connectors/source-monday/manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,29 @@ schemas:
type:
- "null"
- string
from:
type:
- "null"
- string
format: date-time
to:
type:
- "null"
- string
format: date-time
visualization_type:
type:
- "null"
- string
updated_at:
type:
- "null"
- string
format: date-time
is_leaf:
type:
- "null"
- boolean
display_value:
type:
- "null"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ data:
connectorSubtype: api
connectorType: source
definitionId: 80a54ea2-9959-4040-aac1-eee42423ec9b
dockerImageTag: 2.5.17
dockerImageTag: 2.6.0
releases:
rolloutConfiguration:
enableProgressiveRollout: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def request_body(self):
board_ids_str = ""

params["query"] = (
"{boards(limit:1%s){items_page(limit:20){cursor,items{id,name,assets{created_at,file_extension,file_size,id,name,original_geometry,public_url,uploaded_by{id},url,url_thumbnail},board{id,name},column_values{id,text,type,value,... on MirrorValue{display_value},... on BoardRelationValue{display_value,linked_item_ids},... on DependencyValue{display_value,linked_item_ids}},created_at,creator_id,group{id},parent_item{id},state,subscribers{id},updated_at,updates{id}}}}}"
"{boards(limit:1%s){items_page(limit:20){cursor,items{id,name,assets{created_at,file_extension,file_size,id,name,original_geometry,public_url,uploaded_by{id},url,url_thumbnail},board{id,name},column_values(capabilities:[CALCULATED]){id,text,type,value,is_leaf,... on MirrorValue{display_value},... on BoardRelationValue{display_value,linked_item_ids},... on DependencyValue{display_value,linked_item_ids},... on TimelineValue{from,to,visualization_type,updated_at}},created_at,creator_id,group{id},parent_item{id},state,subscribers{id},updated_at,updates{id}}}}}"
% board_ids_str
)
return params
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,43 @@ def test_build_items_incremental_query(monday_requester):
built_query = monday_requester._build_items_incremental_query(object_name, field_schema, stream_slice)

assert (
built_query == "items(limit:100,ids:[1, 2, 3]){id,name,column_values{id,text,type,value,... on MirrorValue{display_value},"
built_query
== "items(limit:100,ids:[1, 2, 3]){id,name,column_values(capabilities:[CALCULATED]){id,text,type,value,... on MirrorValue{display_value},"
"... on BoardRelationValue{display_value,linked_item_ids},... on DependencyValue{display_value,linked_item_ids}}}"
)


@pytest.mark.parametrize(
"column_value_properties, expected_query",
[
pytest.param(
["id", "text", "type", "value", "display_value"],
"column_values(capabilities:[CALCULATED]){id,text,type,value,... on MirrorValue{display_value},"
"... on BoardRelationValue{display_value,linked_item_ids},... on DependencyValue{display_value,linked_item_ids}}",
id="no_timeline_fields_requested",
),
pytest.param(
["id", "text", "type", "value", "from", "to", "visualization_type", "updated_at", "is_leaf", "display_value"],
"column_values(capabilities:[CALCULATED]){id,text,type,value,is_leaf,... on MirrorValue{display_value},"
"... on BoardRelationValue{display_value,linked_item_ids},... on DependencyValue{display_value,linked_item_ids},"
"... on TimelineValue{from,to,visualization_type,updated_at}}",
id="timeline_fields_moved_into_inline_fragment",
),
pytest.param(
["id", "text", "type", "value", "from", "to", "display_value"],
"column_values(capabilities:[CALCULATED]){id,text,type,value,... on MirrorValue{display_value},"
"... on BoardRelationValue{display_value,linked_item_ids},... on DependencyValue{display_value,linked_item_ids},"
"... on TimelineValue{from,to}}",
id="partial_timeline_fields",
),
],
)
def test_build_column_values_query(monday_requester, column_value_properties, expected_query):
field_schema = {field: {"type": ["null", "string"]} for field in column_value_properties}

assert monday_requester._build_query("column_values", field_schema) == expected_query


def test_get_request_headers(monday_requester):
headers = monday_requester.get_request_headers()

Expand Down
1 change: 1 addition & 0 deletions docs/integrations/sources/monday.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ If you use Airbyte Cloud and your organization restricts access to specific IPs,

| Version | Date | Pull Request | Subject |
|:-----------|:-----------|:----------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 2.6.0 | 2026-07-30 | [83271](https://github.com/airbytehq/airbyte/pull/83271) | Add timeline column fields (`from`, `to`, `visualization_type`, `updated_at`) and `is_leaf` to `items.column_values`, and request calculated column values |
| 2.5.17 | 2026-07-28 | [83194](https://github.com/airbytehq/airbyte/pull/83194) | Update to CDK 7.23.8 (fixes AirbyteCustomCodeNotPermittedError for bundled custom components) and remove the temporary Cloud version override |
| 2.5.16 | 2026-07-28 | [1082](https://github.com/airbytehq/airbyte-python-cdk/issues/1082) | Roll Cloud back to 2.5.14 — 2.5.15 is built on SDM 7.23.7, which breaks bundled custom components |
| 2.5.15 | 2026-07-28 | [83007](https://github.com/airbytehq/airbyte/pull/83007) | Update dependencies |
Expand Down
Loading