contextbase-plugin-salesforce 0.2.8__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_salesforce-0.2.8.dist-info/METADATA +9 -0
- contextbase_plugin_salesforce-0.2.8.dist-info/RECORD +9 -0
- contextbase_plugin_salesforce-0.2.8.dist-info/WHEEL +4 -0
- plugin_salesforce/__init__.py +0 -0
- plugin_salesforce/binding_config.py +36 -0
- plugin_salesforce/component.py +102 -0
- plugin_salesforce/defs/__init__.py +1 -0
- plugin_salesforce/defs/defs.yaml +1 -0
- plugin_salesforce/plugin.json +7 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: contextbase-plugin-salesforce
|
|
3
|
+
Version: 0.2.8
|
|
4
|
+
Summary: Salesforce 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.2.8
|
|
8
|
+
Requires-Dist: dagster==1.12.14
|
|
9
|
+
Requires-Python: >=3.14, <3.15
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
plugin_salesforce/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
plugin_salesforce/binding_config.py,sha256=eO1G7ITf4BkCikM9KEHHlSmc9_1Y3jKWnACSovy0tr0,910
|
|
3
|
+
plugin_salesforce/component.py,sha256=hY4GmdJGHgMj3HqIZNmV60JO-b7FemsHhplbLSQ00wg,3627
|
|
4
|
+
plugin_salesforce/defs/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
5
|
+
plugin_salesforce/defs/defs.yaml,sha256=DuagQvPwOWC_blt37MHH1GLUwhQOqOAdwL4f6EcyBpo,58
|
|
6
|
+
plugin_salesforce/plugin.json,sha256=M0moV5I4MF7MI93a1ZKnh3umLKbd5MJdfDJoX1tuhKc,83
|
|
7
|
+
contextbase_plugin_salesforce-0.2.8.dist-info/WHEEL,sha256=i9aSRDivn5iP9LaR1BLQX2GNAuriQWPsFwbbWygTX2k,81
|
|
8
|
+
contextbase_plugin_salesforce-0.2.8.dist-info/METADATA,sha256=vS-_4-lj223_Gr96CvU8ik44uQsGpvRbAT2xDNlZR8c,332
|
|
9
|
+
contextbase_plugin_salesforce-0.2.8.dist-info/RECORD,,
|
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import Field, StrictBool
|
|
6
|
+
|
|
7
|
+
from shared_plugins.bindings import (
|
|
8
|
+
BaseBindingConfigModel,
|
|
9
|
+
NonEmptyText,
|
|
10
|
+
UtcTimestampText,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SalesforceStreamCriterion(BaseBindingConfigModel):
|
|
15
|
+
criteria: Literal[
|
|
16
|
+
"starts with",
|
|
17
|
+
"ends with",
|
|
18
|
+
"contains",
|
|
19
|
+
"exacts",
|
|
20
|
+
"starts not with",
|
|
21
|
+
"ends not with",
|
|
22
|
+
"not contains",
|
|
23
|
+
"not exacts",
|
|
24
|
+
]
|
|
25
|
+
value: NonEmptyText
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class SalesforceBindingConfig(BaseBindingConfigModel):
|
|
29
|
+
client_id: NonEmptyText
|
|
30
|
+
client_secret: NonEmptyText
|
|
31
|
+
refresh_token: NonEmptyText
|
|
32
|
+
is_sandbox: StrictBool = False
|
|
33
|
+
start_date: UtcTimestampText | None = None
|
|
34
|
+
force_use_bulk_api: StrictBool = False
|
|
35
|
+
lookback_window: NonEmptyText | None = None
|
|
36
|
+
streams_criteria: list[SalesforceStreamCriterion] = Field(default_factory=list)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from collections.abc import Sequence
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import dagster as dg
|
|
5
|
+
from dagster import AssetExecutionContext
|
|
6
|
+
from shared_plugins.automation import non_overlapping_automation_condition
|
|
7
|
+
from shared_plugins.bindings import (
|
|
8
|
+
parse_binding_config,
|
|
9
|
+
require_binding_auth_none,
|
|
10
|
+
)
|
|
11
|
+
from shared_plugins.control_plane import ControlPlaneClient
|
|
12
|
+
from shared_plugins.dlt import resolve_partition_binding
|
|
13
|
+
from shared_plugins.naming import (
|
|
14
|
+
dagster_airbyte_sync_asset_key,
|
|
15
|
+
dagster_asset_group_name,
|
|
16
|
+
dagster_asset_tags,
|
|
17
|
+
dagster_partition_def_name,
|
|
18
|
+
dagster_pool_name,
|
|
19
|
+
plugin_id_from_module,
|
|
20
|
+
)
|
|
21
|
+
from shared_plugins.pyairbyte import (
|
|
22
|
+
build_pyairbyte_source,
|
|
23
|
+
require_pyairbyte_selected_stream_names,
|
|
24
|
+
run_pyairbyte_sync,
|
|
25
|
+
)
|
|
26
|
+
from .binding_config import SalesforceBindingConfig
|
|
27
|
+
|
|
28
|
+
PLUGIN_ID = plugin_id_from_module(__file__)
|
|
29
|
+
DOCKER_IMAGE = "airbyte/source-salesforce:2.7.20"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _build_connector_config(cfg: SalesforceBindingConfig) -> dict[str, Any]:
|
|
33
|
+
return {
|
|
34
|
+
**cfg.model_dump(mode="json", exclude_none=True),
|
|
35
|
+
"auth_type": "Client",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _source_updated_at_fields_for_streams(
|
|
40
|
+
stream_names: Sequence[str],
|
|
41
|
+
) -> dict[str, str]:
|
|
42
|
+
return {stream_name: "LastModifiedDate" for stream_name in stream_names}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class SalesforceSyncComponent(dg.Component):
|
|
46
|
+
def build_defs(self, context: dg.ComponentLoadContext) -> dg.Definitions:
|
|
47
|
+
partitions_def = dg.DynamicPartitionsDefinition(
|
|
48
|
+
name=dagster_partition_def_name(PLUGIN_ID)
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
@dg.asset(
|
|
52
|
+
key=dagster_airbyte_sync_asset_key(PLUGIN_ID),
|
|
53
|
+
group_name=dagster_asset_group_name(PLUGIN_ID),
|
|
54
|
+
tags=dagster_asset_tags(PLUGIN_ID),
|
|
55
|
+
automation_condition=non_overlapping_automation_condition(
|
|
56
|
+
dg.AutomationCondition.on_missing()
|
|
57
|
+
| dg.AutomationCondition.on_cron("*/15 * * * *")
|
|
58
|
+
),
|
|
59
|
+
partitions_def=partitions_def,
|
|
60
|
+
pool=dagster_pool_name(PLUGIN_ID),
|
|
61
|
+
)
|
|
62
|
+
def salesforce_sync_asset(
|
|
63
|
+
context: AssetExecutionContext,
|
|
64
|
+
control_plane: dg.ResourceParam[ControlPlaneClient],
|
|
65
|
+
):
|
|
66
|
+
binding = resolve_partition_binding(
|
|
67
|
+
context=context,
|
|
68
|
+
control_plane=control_plane,
|
|
69
|
+
plugin_id=PLUGIN_ID,
|
|
70
|
+
)
|
|
71
|
+
binding_id = str(binding.binding_id)
|
|
72
|
+
require_binding_auth_none(binding)
|
|
73
|
+
cfg = parse_binding_config(binding, SalesforceBindingConfig)
|
|
74
|
+
selected_stream_names = require_pyairbyte_selected_stream_names(binding)
|
|
75
|
+
connector_config = _build_connector_config(cfg)
|
|
76
|
+
source = build_pyairbyte_source(
|
|
77
|
+
docker_image=DOCKER_IMAGE,
|
|
78
|
+
connector_config=connector_config,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
return run_pyairbyte_sync(
|
|
82
|
+
context=context,
|
|
83
|
+
plugin_id=PLUGIN_ID,
|
|
84
|
+
binding_id=binding_id,
|
|
85
|
+
selected_stream_names=selected_stream_names,
|
|
86
|
+
source_updated_at_fields=_source_updated_at_fields_for_streams(
|
|
87
|
+
selected_stream_names
|
|
88
|
+
),
|
|
89
|
+
source=source,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
automation_sensor = dg.AutomationConditionSensorDefinition(
|
|
93
|
+
name="salesforce_automation_sensor",
|
|
94
|
+
target=dg.AssetSelection.assets(salesforce_sync_asset),
|
|
95
|
+
default_status=dg.DefaultSensorStatus.RUNNING,
|
|
96
|
+
minimum_interval_seconds=30,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
return dg.Definitions(
|
|
100
|
+
assets=[salesforce_sync_asset],
|
|
101
|
+
sensors=[automation_sensor],
|
|
102
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
type: plugin_salesforce.component.SalesforceSyncComponent
|