dagster-dingtalk 0.1.4__py3-none-any.whl → 0.1.5b1__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.
@@ -1,8 +1,9 @@
1
1
  # noinspection PyProtectedMember
2
2
  from dagster._core.libraries import DagsterLibraryRegistry
3
3
 
4
- from dagster_dingtalk.resources import DingTalkAPIResource, DingTalkWebhookResource
5
- from dagster_dingtalk.operations import DingTalkWebhookOp
4
+ from dagster_dingtalk.resources import DingTalkResource, MultiDingTalkResource
5
+ from dagster_dingtalk.resources import DingTalkWebhookResource, MultiDingTalkWebhookResource
6
+ # from dagster_dingtalk.operations import DingTalkWebhookOp
6
7
  from dagster_dingtalk.version import __version__
7
8
 
8
9
  DagsterLibraryRegistry.register("dagster-dingtalk", __version__)
@@ -1,22 +1,21 @@
1
1
  from dagster import In, OpExecutionContext, op
2
- from pydantic import Field
3
2
 
4
3
 
5
4
  class DingTalkWebhookOp:
6
5
  @staticmethod
7
6
  @op(description="使用钉钉 Webhook 发送文本消息",
8
- config_schema={"dingtalk_webhook_key": str},
7
+ required_resource_keys={'dingtalk_webhook'},
9
8
  ins={"text": In(str)},
10
9
  )
11
10
  def send_simple_text(context: OpExecutionContext, text):
12
- webhook = getattr(context.resources, context.op_config["dingtalk_webhook_key"])
11
+ webhook = context.resources.dingtalk_webhook
13
12
  webhook.send_text(text)
14
13
 
15
14
  @staticmethod
16
15
  @op(description="使用钉钉 Webhook 发送 Markdown 消息",
17
- config_schema={"dingtalk_webhook_key": str},
16
+ required_resource_keys={'dingtalk_webhook'},
18
17
  ins={"text": In(str), "title": In(str, default_value='')},
19
18
  )
20
19
  def send_simple_markdown(context: OpExecutionContext, text, title):
21
- webhook = getattr(context.resources, context.op_config["dingtalk_webhook_key"])
20
+ webhook = context.resources.dingtalk_webhook
22
21
  webhook.send_text(text, title)
@@ -12,19 +12,19 @@ import httpx
12
12
 
13
13
  from dagster import (
14
14
  ConfigurableResource,
15
- InitResourceContext,
15
+ InitResourceContext, ResourceDependency,
16
16
  )
17
17
  from httpx import Client
18
- from pydantic import Field, PrivateAttr
18
+ from pydantic import Field, PrivateAttr, BaseModel
19
19
 
20
20
 
21
21
  class DingTalkWebhookResource(ConfigurableResource):
22
- base_url: str = Field(default="https://oapi.dingtalk.com/robot/send", description="Webhook的通用地址,无需更改")
23
22
  access_token: str = Field(description="Webhook地址中的 access_token 部分")
24
23
  secret: Optional[str] = Field(default=None, description="如使用加签安全配置,需传签名密钥")
24
+ alias: Optional[str] = Field(default=None, description="如提供别名,将来可以使用别名进行选择")
25
+ base_url: str = Field(default="https://oapi.dingtalk.com/robot/send", description="Webhook的通用地址,无需更改")
25
26
 
26
27
  def _sign_webhook_url(self):
27
-
28
28
  if self.secret is None:
29
29
  return self.webhook_url
30
30
  else:
@@ -88,7 +88,60 @@ class DingTalkWebhookResource(ConfigurableResource):
88
88
  httpx.post(url=self.webhook_url, json={"msgtype": "feedCard", "feedCard": {"links": links_data}})
89
89
 
90
90
 
91
- class DingTalkMultiClient:
91
+ # noinspection NonAsciiCharacters
92
+ class MultiDingTalkWebhookResource(ConfigurableResource):
93
+ """
94
+ 该资源提供了预先定义多个 webhook 资源,并在运行时动态选择的方法。
95
+
96
+ 使用示例:
97
+
98
+ ```
99
+ from dagster_dingtalk import DingTalkResource, MultiDingTalkResource
100
+
101
+ app_apple = DingTalkResource(AppID="apple", ClientId="", ClientSecret="")
102
+ app_book = DingTalkResource(AppID="book", ClientId="", ClientSecret="")
103
+
104
+ @op(required_resource_keys={"dingtalk"}, ins={"app_id":In(str)})
105
+ def print_app_id(context:OpExecutionContext, app_id):
106
+ dingtalk:DingTalkResource = context.resources.dingtalk
107
+ select_app = dingtalk.select_app(app_id)
108
+ context.log.info(dingtalk_app.AppName)
109
+
110
+ @job
111
+ def print_app_id_job():
112
+ print_app_id()
113
+
114
+ defs = Definitions(
115
+ jobs=[print_app_id_job],
116
+ resources={
117
+ "dingtalk": MultiDingTalkResource(
118
+ Apps=[app_apple, app_book]
119
+ )
120
+ },
121
+ )
122
+ ```
123
+
124
+ """
125
+
126
+ Webhooks: ResourceDependency[List[DingTalkWebhookResource]] = Field(description="多个 Webhook 资源的列表")
127
+
128
+ _webhooks = PrivateAttr()
129
+
130
+ def setup_for_execution(self, context: InitResourceContext) -> None:
131
+ _webhooks_token_key = {webhook.access_token:webhook for webhook in self.Webhooks}
132
+ _webhooks_alias_key = {webhook.alias:webhook for webhook in self.Webhooks if webhook.alias}
133
+ self._webhooks = _webhooks_token_key | _webhooks_alias_key
134
+
135
+ def select(self, key:str = "_FIRST_"):
136
+ try:
137
+ if key == "_FIRST_":
138
+ return self.Webhooks[0]
139
+ return self._webhooks[key]
140
+ except KeyError:
141
+ raise f"该 AccessToken 或 别名 <{key}> 不存在于提供的 Webhooks 中。请使用 DingTalkWebhookResource 定义单个 Webhook 后,将其加入 Webhooks 。"
142
+
143
+
144
+ class DingTalkClient:
92
145
  def __init__(self, access_token: str, app_id: str, agent_id: int, robot_code: str) -> None:
93
146
  self.access_token: str = access_token
94
147
  self.app_id: str = app_id
@@ -99,7 +152,7 @@ class DingTalkMultiClient:
99
152
 
100
153
 
101
154
  # noinspection NonAsciiCharacters
102
- class DingTalkAPIResource(ConfigurableResource):
155
+ class DingTalkResource(ConfigurableResource):
103
156
  """
104
157
  [钉钉服务端 API](https://open.dingtalk.com/document/orgapp/api-overview) 企业内部应用部分的第三方封装。
105
158
  通过此资源,可以调用部分钉钉服务端API。
@@ -112,15 +165,15 @@ class DingTalkAPIResource(ConfigurableResource):
112
165
  AppName: Optional[str] = Field(default=None, description="应用名。")
113
166
  ClientId: str = Field(description="应用的 Client ID (原 AppKey 和 SuiteKey)")
114
167
  ClientSecret: str = Field(description="应用的 Client Secret (原 AppSecret 和 SuiteSecret)")
115
- RobotCode: Optional[str] = Field(default=None, description="应用的机器人 RobotCode")
168
+ RobotCode: Optional[str] = Field(default=None, description="应用的机器人 RobotCode,不传时使用 self.ClientId ")
116
169
 
117
- _client: DingTalkMultiClient = PrivateAttr()
170
+ _client: DingTalkClient = PrivateAttr()
118
171
 
119
172
  @classmethod
120
173
  def _is_dagster_maintained(cls) -> bool:
121
174
  return False
122
175
 
123
- def _get_access_token(self, context: InitResourceContext) -> str:
176
+ def _get_access_token(self) -> str:
124
177
  access_token_cache = Path("~/.dingtalk_cache")
125
178
 
126
179
  if access_token_cache.exists():
@@ -134,7 +187,7 @@ class DingTalkAPIResource(ConfigurableResource):
134
187
  if access_token and expire_in < int(time.time()):
135
188
  return access_token
136
189
  else:
137
- context.log.info(f"应用{self.AppName}<{self.AppID}> 鉴权缓存过期或不存在,正在重新获取...")
190
+ print(f"应用{self.AppName}<{self.AppID}> 鉴权缓存过期或不存在,正在重新获取...")
138
191
  response = httpx.post(
139
192
  url="https://api.dingtalk.com/v1.0/oauth2/accessToken",
140
193
  json={"appKey": self.ClientId, "appSecret": self.ClientSecret},
@@ -147,30 +200,82 @@ class DingTalkAPIResource(ConfigurableResource):
147
200
  return access_token
148
201
 
149
202
  def setup_for_execution(self, context: InitResourceContext) -> None:
150
- self._client = DingTalkMultiClient(
151
- self._get_access_token(context),
152
- self.AppID,
153
- self.AgentID,
154
- self.RobotCode,
155
- )
203
+ self._client = DingTalkClient(self._get_access_token(), self.AppID, self.AgentID, self.RobotCode or self.ClientId)
156
204
 
157
205
  def teardown_after_execution(self, context: InitResourceContext) -> None:
158
206
  self._client.api.close()
159
207
  self._client.oapi.close()
160
208
 
161
209
  def 智能人事(self):
210
+ if not hasattr(self, '_client'):
211
+ self._client = DingTalkClient(self._get_access_token(), self.AppID, self.AgentID, self.RobotCode or self.ClientId)
162
212
  return API_智能人事(self._client)
163
213
 
164
214
  def 通讯录管理(self):
215
+ if not hasattr(self, '_client'):
216
+ self._client = DingTalkClient(self._get_access_token(), self.AppID, self.AgentID, self.RobotCode or self.ClientId)
165
217
  return API_通讯录管理(self._client)
166
218
 
167
219
  def 文档文件(self):
220
+ if not hasattr(self, '_client'):
221
+ self._client = DingTalkClient(self._get_access_token(), self.AppID, self.AgentID, self.RobotCode or self.ClientId)
168
222
  return API_文档文件(self._client)
169
223
 
170
224
 
225
+ # noinspection NonAsciiCharacters
226
+ class MultiDingTalkResource(ConfigurableResource):
227
+ """
228
+ 该资源提供了预先定义多个应用资源,并在运行时动态选择的方法。
229
+
230
+ 使用示例:
231
+
232
+ ```
233
+ from dagster_dingtalk import DingTalkResource, MultiDingTalkResource
234
+
235
+ app_apple = DingTalkResource(AppID="apple", ClientId="", ClientSecret="")
236
+ app_book = DingTalkResource(AppID="book", ClientId="", ClientSecret="")
237
+
238
+ @op(required_resource_keys={"dingtalk"}, ins={"app_id":In(str)})
239
+ def print_app_id(context:OpExecutionContext, app_id):
240
+ dingtalk:DingTalkResource = context.resources.dingtalk
241
+ select_app = dingtalk.select_app(app_id)
242
+ context.log.info(dingtalk_app.AppName)
243
+
244
+ @job
245
+ def print_app_id_job():
246
+ print_app_id()
247
+
248
+ defs = Definitions(
249
+ jobs=[print_app_id_job],
250
+ resources={
251
+ "dingtalk": MultiDingTalkResource(
252
+ Apps=[app_apple, app_book]
253
+ )
254
+ },
255
+ )
256
+ ```
257
+
258
+ """
259
+
260
+ Apps: ResourceDependency[List[DingTalkResource]] = Field(description="多个单应用资源的列表")
261
+
262
+ _apps = PrivateAttr()
263
+
264
+ def setup_for_execution(self, context: InitResourceContext) -> None:
265
+ self._apps = {app.AppID:app for app in self.Apps}
266
+
267
+ def select(self, app_id:str = "_FIRST_"):
268
+ try:
269
+ if app_id == "_FIRST_":
270
+ return self.Apps[0]
271
+ return self._apps[app_id]
272
+ except KeyError:
273
+ raise f"该 AppID <{app_id}> 不存在于提供的 AppLists 中。请使用 DingTalkResource 定义单个 App 后,将其加入 AppLists 。"
274
+
275
+
171
276
  # noinspection NonAsciiCharacters
172
277
  class API_智能人事:
173
- def __init__(self, _client:DingTalkMultiClient):
278
+ def __init__(self, _client:DingTalkClient):
174
279
  self._client = _client
175
280
 
176
281
  def 花名册_获取花名册元数据(self):
@@ -228,7 +333,7 @@ class API_智能人事:
228
333
 
229
334
  # noinspection NonAsciiCharacters
230
335
  class API_通讯录管理:
231
- def __init__(self, _client:DingTalkMultiClient):
336
+ def __init__(self, _client:DingTalkClient):
232
337
  self._client = _client
233
338
 
234
339
  def 查询用户详情(self, user_id:str, language:str = "zh_CN"):
@@ -245,7 +350,7 @@ class API_通讯录管理:
245
350
 
246
351
  # noinspection NonAsciiCharacters
247
352
  class API_文档文件:
248
- def __init__(self, _client:DingTalkMultiClient):
353
+ def __init__(self, _client:DingTalkClient):
249
354
  self._client = _client
250
355
 
251
356
  def 媒体文件_上传媒体文件(self, file_path:Path|str, media_type:Literal['image', 'voice', 'video', 'file']):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dagster-dingtalk
3
- Version: 0.1.4
3
+ Version: 0.1.5b1
4
4
  Summary: A dagster plugin for the DingTalk
5
5
  Author: YiZixuan
6
6
  Author-email: sqkkyzx@qq.com
@@ -0,0 +1,7 @@
1
+ dagster_dingtalk/__init__.py,sha256=ktvoURpkJwIzcyQfUvnel1KA4DukRgavAgLl7f0Cy_0,440
2
+ dagster_dingtalk/operations.py,sha256=xJJlOVmFjpaDTMkHZXxj5LbXqRtIQwREl9ZJdXIMOyE,788
3
+ dagster_dingtalk/resources.py,sha256=6S8pVSz0ZMumaibfsJ_ZTxJVUZOleotg1c4hzt_VPDk,15156
4
+ dagster_dingtalk/version.py,sha256=sXLh7g3KC4QCFxcZGBTpG2scR7hmmBsMjq6LqRptkRg,22
5
+ dagster_dingtalk-0.1.5b1.dist-info/METADATA,sha256=JeVAne_YvTbPe_Av_NPbuu5KpsKCsO0uJzNvarEfvLo,1661
6
+ dagster_dingtalk-0.1.5b1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
7
+ dagster_dingtalk-0.1.5b1.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- dagster_dingtalk/__init__.py,sha256=o6bZAaJFfoQEphn9ZaxGBYwq45EsDEBCeTRNUDCWLz0,350
2
- dagster_dingtalk/operations.py,sha256=MOgt-a1k2OKxEaICm7-hq_JD2IpqxnI8-K9GUCfprTI,886
3
- dagster_dingtalk/resources.py,sha256=uZ-DV8_7RswiT9t0zv8IOiu5nkQcc1yPwNESRTlMDnY,11089
4
- dagster_dingtalk/version.py,sha256=sXLh7g3KC4QCFxcZGBTpG2scR7hmmBsMjq6LqRptkRg,22
5
- dagster_dingtalk-0.1.4.dist-info/METADATA,sha256=o1hdiDJpcjOzt9tFNat7zRuzbKNDKNSxbV4eLk6psWs,1659
6
- dagster_dingtalk-0.1.4.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
7
- dagster_dingtalk-0.1.4.dist-info/RECORD,,