contextbase-plugin-slack 0.0.0a1__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.
- contextbase_plugin_slack-0.0.0a1.dist-info/METADATA +9 -0
- contextbase_plugin_slack-0.0.0a1.dist-info/RECORD +8 -0
- contextbase_plugin_slack-0.0.0a1.dist-info/WHEEL +4 -0
- contextbase_plugin_slack-0.0.0a1.dist-info/entry_points.txt +3 -0
- plugin_slack/__init__.py +1 -0
- plugin_slack/binding_config.py +12 -0
- plugin_slack/component.py +130 -0
- plugin_slack/plugin.json +17 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: contextbase-plugin-slack
|
|
3
|
+
Version: 0.0.0a1
|
|
4
|
+
Summary: Slack plugin for ContextBase (PyAirbyte-backed)
|
|
5
|
+
Author: Alizain Feerasta
|
|
6
|
+
Author-email: Alizain Feerasta <alizain.feerasta@gmail.com>
|
|
7
|
+
Requires-Dist: contextbase-shared-plugins==0.0.0a1
|
|
8
|
+
Requires-Dist: dagster==1.12.14
|
|
9
|
+
Requires-Python: >=3.12, <3.13
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
plugin_slack/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
2
|
+
plugin_slack/binding_config.py,sha256=SYJdiBLEyEOBtYbrJV7XlCxpR1GUx4lkvGgVHqEHBew,308
|
|
3
|
+
plugin_slack/component.py,sha256=Hhanay7krd7_SBrfIKFCAhBavKEJcGdEBLgDQzu7EcY,4779
|
|
4
|
+
plugin_slack/plugin.json,sha256=-qW1x85pTSto4fXzEr_MNUjFthedx77gfSLWPqO13Ds,278
|
|
5
|
+
contextbase_plugin_slack-0.0.0a1.dist-info/WHEEL,sha256=i9aSRDivn5iP9LaR1BLQX2GNAuriQWPsFwbbWygTX2k,81
|
|
6
|
+
contextbase_plugin_slack-0.0.0a1.dist-info/entry_points.txt,sha256=4Lzuq39WTOtbTYt79i_w3pcyFJjYd7yWEzFc8RwxmEQ,74
|
|
7
|
+
contextbase_plugin_slack-0.0.0a1.dist-info/METADATA,sha256=GrWNkCCchcnPfpuFwneZzTSWAdgj865G0xJF-Gz6pZw,326
|
|
8
|
+
contextbase_plugin_slack-0.0.0a1.dist-info/RECORD,,
|
plugin_slack/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from shared_plugins.bindings import (
|
|
4
|
+
BaseBindingConfigModel,
|
|
5
|
+
StrictNonNegativeInt,
|
|
6
|
+
UtcTimestampText,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SlackBindingConfig(BaseBindingConfigModel):
|
|
11
|
+
start_date: UtcTimestampText = "2020-01-01T00:00:00Z"
|
|
12
|
+
lookback_window: StrictNonNegativeInt = 7
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import dagster as dg
|
|
2
|
+
from dagster import AssetExecutionContext
|
|
3
|
+
from shared_plugins.automation import non_overlapping_automation_condition
|
|
4
|
+
from shared_plugins.bindings import (
|
|
5
|
+
parse_binding_config,
|
|
6
|
+
require_authenticated_account,
|
|
7
|
+
)
|
|
8
|
+
from shared_plugins.base_platform import BasePlatformClient
|
|
9
|
+
from shared_plugins.dlt import resolve_partition_binding
|
|
10
|
+
from shared_plugins.naming import (
|
|
11
|
+
dagster_airbyte_sync_asset_key,
|
|
12
|
+
dagster_asset_group_name,
|
|
13
|
+
dagster_asset_tags,
|
|
14
|
+
dagster_partition_def_name,
|
|
15
|
+
dagster_pool_name,
|
|
16
|
+
plugin_id_from_module,
|
|
17
|
+
)
|
|
18
|
+
from shared_plugins.provider_token import ProviderTokenClient, ProviderTokenLease
|
|
19
|
+
from shared_plugins.pyairbyte import (
|
|
20
|
+
build_pyairbyte_source,
|
|
21
|
+
require_pyairbyte_selected_stream_names,
|
|
22
|
+
run_pyairbyte_sync,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
from .binding_config import SlackBindingConfig
|
|
26
|
+
|
|
27
|
+
PLUGIN_ID = plugin_id_from_module(__file__)
|
|
28
|
+
DOCKER_IMAGE = "airbyte/source-slack:3.1.16"
|
|
29
|
+
|
|
30
|
+
# Every stream source-slack 3.1.16 exposes (exact discovered-catalog names).
|
|
31
|
+
# A binding with no models.active syncs all of them; models.active narrows.
|
|
32
|
+
ALL_STREAM_NAMES = (
|
|
33
|
+
"users",
|
|
34
|
+
"channels",
|
|
35
|
+
"channel_members",
|
|
36
|
+
"channel_messages",
|
|
37
|
+
"threads",
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# users.updated is epoch-seconds; channels.updated is epoch-MILLISECONDS
|
|
41
|
+
# (Slack-documented), so its unit is declared explicitly.
|
|
42
|
+
SOURCE_UPDATED_AT_FIELDS = {
|
|
43
|
+
"users": "updated",
|
|
44
|
+
"channels": ("updated", "epoch_ms"),
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _build_connector_config(
|
|
49
|
+
cfg: SlackBindingConfig,
|
|
50
|
+
lease: ProviderTokenLease,
|
|
51
|
+
) -> dict[str, object]:
|
|
52
|
+
return {
|
|
53
|
+
**cfg.model_dump(mode="json", exclude_none=True),
|
|
54
|
+
"credentials": {
|
|
55
|
+
"option_title": "API Token Credentials",
|
|
56
|
+
"api_token": lease.access_token,
|
|
57
|
+
},
|
|
58
|
+
# BYO Slack OAuth always yields a user token (xoxp-); user tokens cannot invite
|
|
59
|
+
# themselves into channels, so join_channels is never applicable.
|
|
60
|
+
"join_channels": False,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class SlackSyncComponent(dg.Component):
|
|
65
|
+
def build_defs(self, context: dg.ComponentLoadContext) -> dg.Definitions:
|
|
66
|
+
partitions_def = dg.DynamicPartitionsDefinition(
|
|
67
|
+
name=dagster_partition_def_name(PLUGIN_ID)
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
@dg.asset(
|
|
71
|
+
key=dagster_airbyte_sync_asset_key(PLUGIN_ID),
|
|
72
|
+
group_name=dagster_asset_group_name(PLUGIN_ID),
|
|
73
|
+
tags=dagster_asset_tags(PLUGIN_ID, extra_tags={"ctx_primary": "true"}),
|
|
74
|
+
automation_condition=non_overlapping_automation_condition(
|
|
75
|
+
dg.AutomationCondition.on_missing()
|
|
76
|
+
| dg.AutomationCondition.on_cron("*/15 * * * *")
|
|
77
|
+
),
|
|
78
|
+
partitions_def=partitions_def,
|
|
79
|
+
pool=dagster_pool_name(PLUGIN_ID),
|
|
80
|
+
)
|
|
81
|
+
def slack_sync_asset(
|
|
82
|
+
context: AssetExecutionContext,
|
|
83
|
+
base_platform: dg.ResourceParam[BasePlatformClient],
|
|
84
|
+
provider_token: dg.ResourceParam[ProviderTokenClient],
|
|
85
|
+
):
|
|
86
|
+
binding = resolve_partition_binding(
|
|
87
|
+
context=context,
|
|
88
|
+
base_platform=base_platform,
|
|
89
|
+
plugin_id=PLUGIN_ID,
|
|
90
|
+
)
|
|
91
|
+
binding_id = binding.binding_id
|
|
92
|
+
cfg = parse_binding_config(binding, SlackBindingConfig)
|
|
93
|
+
auth = require_authenticated_account(binding)
|
|
94
|
+
# PyAirbyte consumes the token synchronously within one sync (minutes, well
|
|
95
|
+
# under the user-token TTL), so redeem once with no refresh handler — unlike
|
|
96
|
+
# the long-lived google Credentials wrapped in build_google_service.
|
|
97
|
+
lease = provider_token.redeem(
|
|
98
|
+
provider_id=auth.provider_id,
|
|
99
|
+
account_id=auth.account_id,
|
|
100
|
+
)
|
|
101
|
+
selected_stream_names = require_pyairbyte_selected_stream_names(
|
|
102
|
+
binding, default_active=ALL_STREAM_NAMES
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
connector_config = _build_connector_config(cfg, lease)
|
|
106
|
+
source = build_pyairbyte_source(
|
|
107
|
+
docker_image=DOCKER_IMAGE,
|
|
108
|
+
connector_config=connector_config,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
return run_pyairbyte_sync(
|
|
112
|
+
context=context,
|
|
113
|
+
plugin_id=PLUGIN_ID,
|
|
114
|
+
binding_id=binding_id,
|
|
115
|
+
selected_stream_names=selected_stream_names,
|
|
116
|
+
source_updated_at_fields=SOURCE_UPDATED_AT_FIELDS,
|
|
117
|
+
source=source,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
automation_sensor = dg.AutomationConditionSensorDefinition(
|
|
121
|
+
name="slack_automation_sensor",
|
|
122
|
+
target=dg.AssetSelection.assets(slack_sync_asset),
|
|
123
|
+
default_status=dg.DefaultSensorStatus.RUNNING,
|
|
124
|
+
minimum_interval_seconds=30,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
return dg.Definitions(
|
|
128
|
+
assets=[slack_sync_asset],
|
|
129
|
+
sensors=[automation_sensor],
|
|
130
|
+
)
|
plugin_slack/plugin.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"auth": {
|
|
3
|
+
"provider_id": "slack",
|
|
4
|
+
"requires_oauth_app_id": true,
|
|
5
|
+
"scopes": [
|
|
6
|
+
"channels:read",
|
|
7
|
+
"channels:history",
|
|
8
|
+
"groups:read",
|
|
9
|
+
"groups:history",
|
|
10
|
+
"users:read",
|
|
11
|
+
"users:read.email"
|
|
12
|
+
],
|
|
13
|
+
"type": "oauth"
|
|
14
|
+
},
|
|
15
|
+
"mode": "dagster",
|
|
16
|
+
"plugin_id": "slack"
|
|
17
|
+
}
|