contextbase-plugin-microsoft-planner-premium 0.2.3__py3-none-any.whl

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.
@@ -0,0 +1,12 @@
1
+ Metadata-Version: 2.3
2
+ Name: contextbase-plugin-microsoft-planner-premium
3
+ Version: 0.2.3
4
+ Summary: Microsoft Planner Premium / Project for the Web plugin for ContextBase
5
+ Author: Alizain Feerasta
6
+ Author-email: Alizain Feerasta <alizain.feerasta@gmail.com>
7
+ Requires-Dist: contextbase-shared-plugins==0.2.3
8
+ Requires-Dist: dagster==1.12.14
9
+ Requires-Dist: dagster-dlt==0.28.14
10
+ Requires-Dist: dlt[duckdb]>=1.26.0
11
+ Requires-Dist: pydantic>=2.12.0
12
+ Requires-Python: >=3.10, <3.15
@@ -0,0 +1,10 @@
1
+ plugin_microsoft_planner_premium/__init__.py,sha256=IKZK1qTZr1ZFeRpERM1QyrdaimrSr79pJbrD-prTihk,78
2
+ plugin_microsoft_planner_premium/binding_config.py,sha256=ZRWmqzotiil91S5x-1JKgJNcWTSMS4pbRALasYrFlmQ,193
3
+ plugin_microsoft_planner_premium/component.py,sha256=viFb_wwZrCS-glO4P01oGF0yie6-LNL3ewBDkxotUdQ,4889
4
+ plugin_microsoft_planner_premium/defs/__init__.py,sha256=aiymnDSQw4Nf9aphyppXgmszpYkDeixyaM2vlyAIJEg,78
5
+ plugin_microsoft_planner_premium/defs/defs.yaml,sha256=gqTJq_QRtYyQ_3AfcI15ezxzCnciJF-M_rKYDdo70tU,86
6
+ plugin_microsoft_planner_premium/plugin.json,sha256=QpxIW6RG1AYlILZXJ8k2rwL_B7nQy4ZIdZssKwU3uwI,112
7
+ plugin_microsoft_planner_premium/tables.py,sha256=Cjn8tZ8ZuWmS099B-BJgKtOYLyu7jhGzghcI7na2GiE,6042
8
+ contextbase_plugin_microsoft_planner_premium-0.2.3.dist-info/WHEEL,sha256=i9aSRDivn5iP9LaR1BLQX2GNAuriQWPsFwbbWygTX2k,81
9
+ contextbase_plugin_microsoft_planner_premium-0.2.3.dist-info/METADATA,sha256=jFD5-ARRzKzujfpNzSv1sbQ_VNuGfVhbNWfQBQgSQnA,468
10
+ contextbase_plugin_microsoft_planner_premium-0.2.3.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.11.15
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1 @@
1
+ """Microsoft Planner Premium / Project for the Web plugin for ContextBase."""
@@ -0,0 +1,7 @@
1
+ from __future__ import annotations
2
+
3
+ from shared_plugins.microsoft_dataverse import DataverseBindingConfigBase
4
+
5
+
6
+ class MicrosoftPlannerPremiumBindingConfig(DataverseBindingConfigBase):
7
+ pass
@@ -0,0 +1,148 @@
1
+ import dagster as dg
2
+ from dagster import AssetExecutionContext
3
+ from dagster_dlt import DagsterDltResource
4
+ from shared_plugins.automation import non_overlapping_automation_condition
5
+ from shared_plugins.bindings import (
6
+ parse_binding_config,
7
+ require_client_credentials,
8
+ resolve_binding_models,
9
+ )
10
+ from shared_plugins.control_plane import ControlPlaneClient
11
+ from shared_plugins.dlt import resolve_partition_binding, run_dlt_pipeline
12
+ from shared_plugins.microsoft_dataverse import (
13
+ DataverseClient,
14
+ build_dataverse_dlt_source,
15
+ )
16
+ from shared_plugins.naming import (
17
+ dagster_asset_group_name,
18
+ dagster_asset_tags,
19
+ dagster_dlt_asset_key,
20
+ dagster_partition_def_name,
21
+ dagster_pool_name,
22
+ dlt_source_name,
23
+ plugin_id_from_module,
24
+ )
25
+ from shared_plugins.resources import DLT_RESOURCE
26
+ from shared_types.client_credentials_auth import ClientCredentialsAuth
27
+
28
+ from .binding_config import MicrosoftPlannerPremiumBindingConfig
29
+ from .tables import (
30
+ DEFAULT_ACTIVE_MODEL_NAMES,
31
+ SUPPORTED_MODEL_NAMES,
32
+ TABLE_SPECS,
33
+ )
34
+
35
+ PLUGIN_ID = plugin_id_from_module(__file__)
36
+ SYNC_JOB = "sync"
37
+ SYNC_SOURCE_NAME = dlt_source_name(PLUGIN_ID, SYNC_JOB)
38
+
39
+
40
+ def _build_dataverse_client(
41
+ cfg: MicrosoftPlannerPremiumBindingConfig,
42
+ auth: ClientCredentialsAuth,
43
+ ) -> DataverseClient:
44
+ return DataverseClient(
45
+ org_url=cfg.org_url,
46
+ tenant_id=cfg.tenant_id,
47
+ client_id=auth.client_id,
48
+ client_secret=auth.client_secret,
49
+ )
50
+
51
+
52
+ def _build_sync_specs(
53
+ partitions_def: dg.PartitionsDefinition,
54
+ automation_condition: dg.AutomationCondition,
55
+ ) -> list[dg.AssetSpec]:
56
+ shared = dict(
57
+ group_name=dagster_asset_group_name(PLUGIN_ID),
58
+ tags=dagster_asset_tags(PLUGIN_ID),
59
+ automation_condition=automation_condition,
60
+ partitions_def=partitions_def,
61
+ )
62
+
63
+ return [
64
+ dg.AssetSpec(
65
+ key=dagster_dlt_asset_key(SYNC_SOURCE_NAME, spec.resource_name),
66
+ **shared,
67
+ )
68
+ for spec in TABLE_SPECS
69
+ ]
70
+
71
+
72
+ class MicrosoftPlannerPremiumSyncComponent(dg.Component):
73
+ def build_defs(self, context: dg.ComponentLoadContext) -> dg.Definitions:
74
+ partitions_def = dg.DynamicPartitionsDefinition(
75
+ name=dagster_partition_def_name(PLUGIN_ID)
76
+ )
77
+
78
+ sync_specs = _build_sync_specs(
79
+ partitions_def,
80
+ non_overlapping_automation_condition(
81
+ dg.AutomationCondition.on_missing()
82
+ | dg.AutomationCondition.on_cron("*/15 * * * *")
83
+ ),
84
+ )
85
+
86
+ @dg.multi_asset(
87
+ specs=sync_specs,
88
+ can_subset=True,
89
+ name="microsoft_planner_premium_sync",
90
+ pool=dagster_pool_name(PLUGIN_ID),
91
+ )
92
+ def microsoft_planner_premium_sync_assets(
93
+ context: AssetExecutionContext,
94
+ dlt_resource: DagsterDltResource,
95
+ control_plane: dg.ResourceParam[ControlPlaneClient],
96
+ ):
97
+ binding = resolve_partition_binding(
98
+ context=context,
99
+ control_plane=control_plane,
100
+ plugin_id=PLUGIN_ID,
101
+ )
102
+ binding_id = str(binding.binding_id)
103
+ cfg = parse_binding_config(binding, MicrosoftPlannerPremiumBindingConfig)
104
+ auth = require_client_credentials(binding)
105
+ binding_models = resolve_binding_models(
106
+ binding,
107
+ supported_models=SUPPORTED_MODEL_NAMES,
108
+ default_active=DEFAULT_ACTIVE_MODEL_NAMES,
109
+ )
110
+ client = _build_dataverse_client(cfg, auth)
111
+ try:
112
+ source = build_dataverse_dlt_source(
113
+ plugin_id=PLUGIN_ID,
114
+ job=SYNC_JOB,
115
+ binding_id=binding_id,
116
+ client=client,
117
+ binding_models=binding_models,
118
+ specs=TABLE_SPECS,
119
+ )
120
+ yield from run_dlt_pipeline(
121
+ context=context,
122
+ dlt_resource=dlt_resource,
123
+ source=source,
124
+ plugin_id=PLUGIN_ID,
125
+ binding_id=binding_id,
126
+ job_name=SYNC_JOB,
127
+ )
128
+ finally:
129
+ client.close()
130
+
131
+ automation_sensor = dg.AutomationConditionSensorDefinition(
132
+ name="microsoft_planner_premium_automation_sensor",
133
+ target=dg.AssetSelection.assets(
134
+ microsoft_planner_premium_sync_assets,
135
+ ),
136
+ default_status=dg.DefaultSensorStatus.RUNNING,
137
+ minimum_interval_seconds=30,
138
+ )
139
+
140
+ return dg.Definitions(
141
+ assets=[
142
+ microsoft_planner_premium_sync_assets,
143
+ ],
144
+ sensors=[automation_sensor],
145
+ resources={
146
+ "dlt_resource": DLT_RESOURCE,
147
+ },
148
+ )
@@ -0,0 +1 @@
1
+ """Dagster component definitions for the Microsoft Planner Premium plugin."""
@@ -0,0 +1 @@
1
+ type: plugin_microsoft_planner_premium.component.MicrosoftPlannerPremiumSyncComponent
@@ -0,0 +1,7 @@
1
+ {
2
+ "auth": {
3
+ "type": "client_credentials"
4
+ },
5
+ "mode": "dagster",
6
+ "plugin_id": "microsoft_planner_premium"
7
+ }
@@ -0,0 +1,171 @@
1
+ """Inventory of Dataverse entity sets this plugin syncs.
2
+
3
+ Each `DataverseTableSpec` names one OData entity set, its primary-key
4
+ attribute, and the sync mode (delta-tracked vs. full snapshot). Selected
5
+ columns are NOT carried on the spec — they are computed at warmup from
6
+ per-tenant `EntityDefinitions` metadata via
7
+ `shared_plugins.microsoft_dataverse.runtime_schema.build_runtime_table_schemas`,
8
+ which lets the typed-column rewrite pick up new attributes without
9
+ requiring code changes per tenant.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from shared_plugins.microsoft_dataverse import (
15
+ DataverseSyncMode,
16
+ DataverseTableSpec,
17
+ )
18
+
19
+ DELTA_TABLE_SPECS: tuple[DataverseTableSpec, ...] = (
20
+ DataverseTableSpec(
21
+ entity_set="msdyn_projects",
22
+ primary_key="msdyn_projectid",
23
+ sync_mode=DataverseSyncMode.DELTA,
24
+ resource_name="msdyn_projects",
25
+ ),
26
+ DataverseTableSpec(
27
+ entity_set="msdyn_projecttasks",
28
+ primary_key="msdyn_projecttaskid",
29
+ sync_mode=DataverseSyncMode.DELTA,
30
+ resource_name="msdyn_projecttasks",
31
+ ),
32
+ DataverseTableSpec(
33
+ entity_set="msdyn_projectteams",
34
+ primary_key="msdyn_projectteamid",
35
+ sync_mode=DataverseSyncMode.DELTA,
36
+ resource_name="msdyn_projectteams",
37
+ ),
38
+ DataverseTableSpec(
39
+ entity_set="msdyn_projectbuckets",
40
+ primary_key="msdyn_projectbucketid",
41
+ sync_mode=DataverseSyncMode.DELTA,
42
+ resource_name="msdyn_projectbuckets",
43
+ ),
44
+ DataverseTableSpec(
45
+ entity_set="msdyn_projecttaskdependencies",
46
+ primary_key="msdyn_projecttaskdependencyid",
47
+ sync_mode=DataverseSyncMode.DELTA,
48
+ resource_name="msdyn_projecttaskdependencies",
49
+ ),
50
+ DataverseTableSpec(
51
+ entity_set="msdyn_resourceassignments",
52
+ primary_key="msdyn_resourceassignmentid",
53
+ sync_mode=DataverseSyncMode.DELTA,
54
+ resource_name="msdyn_resourceassignments",
55
+ ),
56
+ DataverseTableSpec(
57
+ entity_set="msdyn_projectlabels",
58
+ primary_key="msdyn_projectlabelid",
59
+ sync_mode=DataverseSyncMode.DELTA,
60
+ resource_name="msdyn_projectlabels",
61
+ ),
62
+ DataverseTableSpec(
63
+ entity_set="msdyn_projecttasktolabels",
64
+ primary_key="msdyn_projecttasktolabelid",
65
+ sync_mode=DataverseSyncMode.DELTA,
66
+ resource_name="msdyn_projecttasktolabels",
67
+ ),
68
+ DataverseTableSpec(
69
+ entity_set="msdyn_projectstatusreports",
70
+ primary_key="msdyn_projectstatusreportid",
71
+ sync_mode=DataverseSyncMode.DELTA,
72
+ resource_name="msdyn_projectstatusreports",
73
+ ),
74
+ DataverseTableSpec(
75
+ entity_set="msdyn_projectissues",
76
+ primary_key="msdyn_projectissueid",
77
+ sync_mode=DataverseSyncMode.DELTA,
78
+ resource_name="msdyn_projectissues",
79
+ ),
80
+ DataverseTableSpec(
81
+ entity_set="msdyn_projectrisks",
82
+ primary_key="msdyn_projectriskid",
83
+ sync_mode=DataverseSyncMode.DELTA,
84
+ resource_name="msdyn_projectrisks",
85
+ ),
86
+ DataverseTableSpec(
87
+ entity_set="msdyn_projectchanges",
88
+ primary_key="msdyn_projectchangeid",
89
+ sync_mode=DataverseSyncMode.DELTA,
90
+ resource_name="msdyn_projectchanges",
91
+ ),
92
+ DataverseTableSpec(
93
+ entity_set="msdyn_projectparameters",
94
+ primary_key="msdyn_projectparameterid",
95
+ sync_mode=DataverseSyncMode.DELTA,
96
+ resource_name="msdyn_projectparameters",
97
+ ),
98
+ DataverseTableSpec(
99
+ entity_set="msdyn_workhourtemplates",
100
+ primary_key="msdyn_workhourtemplateid",
101
+ sync_mode=DataverseSyncMode.DELTA,
102
+ resource_name="msdyn_workhourtemplates",
103
+ ),
104
+ )
105
+
106
+ SNAPSHOT_TABLE_SPECS: tuple[DataverseTableSpec, ...] = (
107
+ DataverseTableSpec(
108
+ entity_set="msdyn_projectchecklists",
109
+ primary_key="msdyn_projectchecklistid",
110
+ sync_mode=DataverseSyncMode.SNAPSHOT,
111
+ resource_name="msdyn_projectchecklists",
112
+ ),
113
+ DataverseTableSpec(
114
+ entity_set="msdyn_projectsprints",
115
+ primary_key="msdyn_projectsprintid",
116
+ sync_mode=DataverseSyncMode.SNAPSHOT,
117
+ resource_name="msdyn_projectsprints",
118
+ ),
119
+ DataverseTableSpec(
120
+ entity_set="msdyn_projecttaskattachments",
121
+ primary_key="msdyn_projecttaskattachmentid",
122
+ sync_mode=DataverseSyncMode.SNAPSHOT,
123
+ resource_name="msdyn_projecttaskattachments",
124
+ ),
125
+ DataverseTableSpec(
126
+ entity_set="msdyn_projecttaskconversations",
127
+ primary_key="msdyn_projecttaskconversationid",
128
+ sync_mode=DataverseSyncMode.SNAPSHOT,
129
+ resource_name="msdyn_projecttaskconversations",
130
+ ),
131
+ DataverseTableSpec(
132
+ entity_set="msdyn_projecttasktogoals",
133
+ primary_key="msdyn_projecttasktogoalid",
134
+ sync_mode=DataverseSyncMode.SNAPSHOT,
135
+ resource_name="msdyn_projecttasktogoals",
136
+ ),
137
+ DataverseTableSpec(
138
+ entity_set="msdyn_projectgoals",
139
+ primary_key="msdyn_projectgoalid",
140
+ sync_mode=DataverseSyncMode.SNAPSHOT,
141
+ resource_name="msdyn_projectgoals",
142
+ ),
143
+ DataverseTableSpec(
144
+ entity_set="msdyn_projectbaselinedatas",
145
+ primary_key="msdyn_projectbaselinedataid",
146
+ sync_mode=DataverseSyncMode.SNAPSHOT,
147
+ resource_name="msdyn_projectbaselinedatas",
148
+ ),
149
+ DataverseTableSpec(
150
+ entity_set="msdyn_projectbaselinetaskdatas",
151
+ primary_key="msdyn_projectbaselinetaskdataid",
152
+ sync_mode=DataverseSyncMode.SNAPSHOT,
153
+ resource_name="msdyn_projectbaselinetaskdatas",
154
+ ),
155
+ DataverseTableSpec(
156
+ entity_set="msdyn_projectteamschannelmappings",
157
+ primary_key="msdyn_projectteamschannelmappingid",
158
+ sync_mode=DataverseSyncMode.SNAPSHOT,
159
+ resource_name="msdyn_projectteamschannelmappings",
160
+ ),
161
+ )
162
+
163
+ TABLE_SPECS: tuple[DataverseTableSpec, ...] = (
164
+ *DELTA_TABLE_SPECS,
165
+ *SNAPSHOT_TABLE_SPECS,
166
+ )
167
+
168
+ SUPPORTED_MODEL_NAMES: tuple[str, ...] = tuple(
169
+ spec.resource_name for spec in TABLE_SPECS
170
+ )
171
+ DEFAULT_ACTIVE_MODEL_NAMES: tuple[str, ...] = SUPPORTED_MODEL_NAMES