dagster-dingtalk 0.1.14__py3-none-any.whl → 0.1.16__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,10 +1,9 @@
1
1
  # noinspection PyProtectedMember
2
2
  from dagster._core.libraries import DagsterLibraryRegistry
3
+ from dagster_dingtalk.version import __version__
3
4
 
4
- from dagster_dingtalk.resources import DingTalkAppResource
5
- from dagster_dingtalk.resources import DingTalkWebhookResource
5
+ from dagster_dingtalk.resources import DingTalkAppResource, DingTalkWebhookResource
6
6
  from dagster_dingtalk.app_client import DingTalkClient as DingTalkAppClient
7
- # from dagster_dingtalk.operations import DingTalkWebhookOp
8
- from dagster_dingtalk.version import __version__
7
+ import dagster_dingtalk.operations as dingtalk_op
9
8
 
10
9
  DagsterLibraryRegistry.register("dagster-dingtalk", __version__)
@@ -5,7 +5,10 @@ from datetime import datetime
5
5
  from enum import Enum
6
6
  from pathlib import Path
7
7
  from typing import List, Literal, Dict, Tuple
8
+
9
+ import httpx
8
10
  from httpx import Client
11
+ from pydantic import BaseModel, Field
9
12
 
10
13
 
11
14
  # noinspection NonAsciiCharacters
@@ -26,6 +29,7 @@ class DingTalkClient:
26
29
  self.通讯录管理 = 通讯录管理_API(self)
27
30
  self.文档文件 = 文档文件_API(self)
28
31
  self.互动卡片 = 互动卡片_API(self)
32
+ self.OA审批 = OA审批_API(self)
29
33
 
30
34
  def __get_access_token(self) -> str:
31
35
  access_token_cache = Path("/tmp/.dingtalk_cache")
@@ -210,6 +214,7 @@ class 文档文件_API:
210
214
  def __init__(self, _client:DingTalkClient):
211
215
  self.__client:DingTalkClient = _client
212
216
  self.媒体文件 = 文档文件_媒体文件_API(_client)
217
+ self.文件传输 = 文档文件_文件传输_API(_client)
213
218
 
214
219
  # noinspection NonAsciiCharacters
215
220
  class 文档文件_媒体文件_API:
@@ -238,6 +243,84 @@ class 文档文件_媒体文件_API:
238
243
  response = self.__client.oapi.post(url=f"/media/upload?type={media_type}", files={'media': f})
239
244
  return response.json()
240
245
 
246
+ # noinspection NonAsciiCharacters
247
+ class 文档文件_文件传输_API:
248
+ def __init__(self, _client:DingTalkClient):
249
+ self.__client:DingTalkClient = _client
250
+
251
+ def 获取文件上传信息(self, space_id:int, union_id:str, multi_part:bool = False) -> dict:
252
+ """
253
+ 调用本接口,上传图片、语音媒体资源文件以及普通文件,接口返回媒体资源标识 media_id。
254
+
255
+ https://open.dingtalk.com/document/orgapp/upload-media-files
256
+
257
+ :param space_id: 空间Id。
258
+ :param union_id: 操作者unionId。
259
+ :param multi_part: 是否需要分片上传。默认值为 False
260
+
261
+ :return:
262
+ {
263
+ "uploadKey": str,
264
+ "storageDriver": str,
265
+ "protocol": str,
266
+ "headerSignatureInfo": {
267
+ "resourceUrls" : ["resourceUrl"],
268
+ "headers" : {
269
+ "key" : "header_value"
270
+ },
271
+ }
272
+ }
273
+ """
274
+ response = self.__client.api.post(
275
+ url=f"/v1.0/storage/spaces/{space_id}/files/uploadInfos/query",
276
+ params={'unionId': union_id},
277
+ json={
278
+ "protocol": "HEADER_SIGNATURE",
279
+ "multipart": multi_part
280
+ }
281
+ )
282
+ return response.json()
283
+
284
+ def 提交文件(self, url:str, headers:dict, file_path:Path|str, space_id:int, union_id:str,
285
+ upload_key:str, convert_to_online_doc:bool = False) -> dict:
286
+ """
287
+ 调用本接口,上传图片、语音媒体资源文件以及普通文件,接口返回媒体资源标识 media_id。
288
+
289
+ https://open.dingtalk.com/document/orgapp/upload-media-files
290
+
291
+ :param url: 获取文件上传信息得到的 resourceUrl。
292
+ :param headers: 获取文件上传信息得到的 headers。
293
+ :param file_path: 文件路径
294
+ :param space_id: 空间Id。
295
+ :param union_id: 操作者unionId。
296
+ :param upload_key: 添加文件唯一标识。
297
+ :param convert_to_online_doc: 是否转换成在线文档。默认值 False
298
+
299
+ :return:
300
+ {
301
+ "uploadKey": str,
302
+ "storageDriver": str,
303
+ "protocol": str,
304
+ "headerSignatureInfo": dict,
305
+ }
306
+ """
307
+ with open(file_path, 'rb') as f:
308
+ httpx.put(
309
+ url=url,
310
+ files={"file":f},
311
+ headers=headers
312
+ )
313
+
314
+ response = self.__client.api.post(
315
+ url = f"/v2.0/storage/spaces/files/{space_id}/commit?unionId={union_id}",
316
+ json = {
317
+ "uploadKey": upload_key,
318
+ "name": file_path.split("/")[-1],
319
+ "convertToOnlineDoc": convert_to_online_doc
320
+ }
321
+ )
322
+ return response.json()
323
+
241
324
  # noinspection NonAsciiCharacters
242
325
  class 互动卡片_API:
243
326
  def __init__(self, _client:DingTalkClient):
@@ -325,3 +408,171 @@ class 互动卡片_API:
325
408
  )
326
409
 
327
410
  return response.json()
411
+
412
+ # noinspection NonAsciiCharacters
413
+ class OA审批_API:
414
+ def __init__(self, _client:DingTalkClient):
415
+ self.__client:DingTalkClient = _client
416
+ self.审批实例 = OA审批_审批实例_API(_client)
417
+ self.审批钉盘 = OA审批_审批钉盘_API(_client)
418
+
419
+ # noinspection NonAsciiCharacters
420
+ class OA审批_审批实例_API:
421
+ def __init__(self, _client:DingTalkClient):
422
+ self.__client:DingTalkClient = _client
423
+
424
+ class CommentAttachment(BaseModel):
425
+ spaceId: str = Field(description="钉盘空间ID")
426
+ fileSize: str = Field(description="文件大小")
427
+ fileId: str = Field(description="文件ID")
428
+ fileName: str = Field(description="文件名称")
429
+ fileType: str = Field(description="文件类型")
430
+
431
+ def 获取单个审批实例详情(self, instance_id:str) -> dict:
432
+ """
433
+ 调用本接口可以获取审批实例详情数据,根据审批实例ID,获取审批实例详情,包括审批实例标题、发起人的userId、审批人userId、操作记录列表等内容。
434
+
435
+ https://open.dingtalk.com/document/orgapp/obtains-the-details-of-a-single-approval-instance-pop
436
+
437
+ :param instance_id: 审批实例ID。
438
+
439
+ :return:
440
+ {
441
+ "success": boolean,
442
+ "result": {}
443
+ }
444
+ """
445
+ response = self.__client.api.get(url="/v1.0/workflow/processInstances", params={'processInstanceId': instance_id})
446
+ return response.json()
447
+
448
+ def 撤销审批实例(self, instance_id:str, is_system:bool = True, remark:str|None = None, operating_user_id:str = None) -> dict:
449
+ """
450
+ 撤销发起的处于流程中的审批实例。审批发起15秒内不能撤销审批流程。本接口只能撤销流程中的审批实例,不能撤销已审批完成的审批实例。
451
+
452
+ https://open.dingtalk.com/document/orgapp/revoke-an-approval-instance
453
+
454
+ :param instance_id: 审批实例ID。
455
+ :param is_system: 是否通过系统操作。默认为 True。当为 false 时,需要传发起人才能撤销。
456
+ :param remark: 终止说明。
457
+ :param operating_user_id: 操作人的userId。is_system 为 false 时必填。
458
+
459
+ :return:
460
+ {
461
+ "success": boolean,
462
+ "result": {}
463
+ }
464
+ """
465
+ response = self.__client.api.post(
466
+ url="/v1.0/workflow/processInstances",
467
+ json={
468
+ "processInstanceId" : instance_id,
469
+ "isSystem" : is_system,
470
+ "remark" : remark,
471
+ "operatingUserId" : operating_user_id
472
+ }
473
+ )
474
+ return response.json()
475
+
476
+ def 添加审批评论(
477
+ self, instance_id:str, text:str, comment_user_id: str,
478
+ photos: List[str]|None = None, attachments: List[CommentAttachment]|None = None
479
+ ) -> dict:
480
+ """
481
+ 调用本接口可以获取审批实例详情数据,根据审批实例ID,获取审批实例详情,包括审批实例标题、发起人的userId、审批人userId、操作记录列表等内容。
482
+
483
+ 其中,添加审批评论附件需调用获取审批钉盘空间信息接口,获取钉盘空间的上传权限,并获取审批钉盘空间spaceId。
484
+
485
+ https://open.dingtalk.com/document/orgapp/obtains-the-details-of-a-single-approval-instance-pop
486
+
487
+ :param instance_id: 审批实例 ID。
488
+ :param text: 评论的内容。
489
+ :param comment_user_id: 评论人的 UserId
490
+ :param photos: 图片的 URL 链接的列表,默认为 None。
491
+ :param attachments: 附件列表,默认为 None。添加审批评论附件需将文件上传至审批钉盘空间,可以获取到相关接口参数。
492
+
493
+ :return:
494
+ {
495
+ "success": boolean,
496
+ "result": boolean
497
+ }
498
+ """
499
+
500
+ data = {
501
+ 'processInstanceId': instance_id,
502
+ 'text': text,
503
+ 'commentUserId': comment_user_id,
504
+ }
505
+
506
+ if photos or attachments:
507
+ data.update({'file': {"photos": photos, "attachments": attachments}})
508
+
509
+ response = self.__client.api.post(
510
+ url="/v1.0/workflow/processInstances/comments",
511
+ json=data
512
+ )
513
+ return response.json()
514
+
515
+ def 获取审批实例ID列表(
516
+ self, process_code:str, start_time:datetime, end_time:datetime, next_token: int = 0, max_results: int = 20,
517
+ statuses: Literal["RUNNING", "TERMINATED", "COMPLETED"]|None = None, user_ids = List[str]
518
+ ) -> dict:
519
+ """
520
+ 获取权限范围内的相关部门审批实例ID列表。
521
+
522
+ https://open.dingtalk.com/document/orgapp/obtain-an-approval-list-of-instance-ids
523
+
524
+ :param user_ids:
525
+ :param process_code: 审批流模板的 code。
526
+ :param start_time: 审批实例开始时间。
527
+ :param end_time: 审批实例结束时间。
528
+ :param next_token: 分页游标, 首次调用传 0, 默认值为 0
529
+ :param max_results: 分页小,最多传20,默认值为 20
530
+ :param statuses: 筛选流程实例状态,默认为 None,表示不筛选。 RUNNING-审批中 TERMINATED-已撤销 COMPLETED-审批完成
531
+
532
+ :return:
533
+ {
534
+ "success": boolean,
535
+ "result": {}
536
+ }
537
+ """
538
+ response = self.__client.api.post(
539
+ url="/v1.0/workflow/processes/instanceIds/query",
540
+ json={
541
+ "processCode" : process_code,
542
+ "startTime" : int(start_time.timestamp()*1000),
543
+ "endTime" : int(end_time.timestamp()*1000),
544
+ "nextToken" : next_token,
545
+ "maxResults" : max_results,
546
+ "userIds" : user_ids,
547
+ "statuses" : statuses
548
+ })
549
+ return response.json()
550
+
551
+ # noinspection NonAsciiCharacters
552
+ class OA审批_审批钉盘_API:
553
+ def __init__(self, _client:DingTalkClient):
554
+ self.__client:DingTalkClient = _client
555
+
556
+ def 获取审批钉盘空间信息(self, user_id:str) -> dict:
557
+ """
558
+ 获取审批钉盘空间的ID并授予当前用户上传附件的权限。
559
+
560
+ https://open.dingtalk.com/document/orgapp/obtains-the-information-about-approval-nail-disk
561
+
562
+ :param user_id: 用户的userId。
563
+
564
+ :return:
565
+ {
566
+ "success": bool,
567
+ "result": {
568
+ "spaceId": int
569
+ }
570
+ }
571
+ """
572
+ response = self.__client.api.post(
573
+ url="/v1.0/workflow/processInstances/spaces/infos/query",
574
+ json={
575
+ "userId" : user_id,
576
+ "agentId" : self.__client.agent_id
577
+ })
578
+ return response.json()
@@ -1,20 +1,82 @@
1
- from dagster import In, OpExecutionContext, op
1
+ from dagster import In, OpExecutionContext, op, Out
2
+ from .app_client import DingTalkClient
3
+ from .resources import DingTalkWebhookResource
2
4
 
3
- # noinspection PyProtectedMember
4
- from dagster._annotations import experimental
5
5
 
6
-
7
- @experimental
8
- @op(description="使用钉钉 Webhook 发送文本消息",
6
+ @op(description="钉钉Webhook发送文本消息",
9
7
  required_resource_keys={'dingtalk_webhook'},
10
- ins={"text": In(str)})
11
- def op_send_simple_text(context: OpExecutionContext, text):
12
- webhook = context.resources.dingtalk_webhook
13
- webhook.send_text(text)
8
+ ins={
9
+ "text": In(str),
10
+ "at": In(default_value=None, description="@列表,传List[str]解析为userId,传List[int]解析为phone,传ALL解析为全部。")
11
+ })
12
+ def op_send_text(context: OpExecutionContext, text, at):
13
+ webhook:DingTalkWebhookResource = context.resources.dingtalk_webhook
14
+ if isinstance(at, str) and at == 'ALL':
15
+ webhook.send_text(text=text, at_all=True)
16
+ if isinstance(at, list) and isinstance(at[0], str):
17
+ webhook.send_text(text=text, at_user_ids=at)
18
+ if isinstance(at, list) and isinstance(at[0], int):
19
+ at = [str(mobile) for mobile in at]
20
+ webhook.send_text(text=text, at_mobiles=at)
21
+ if not at:
22
+ webhook.send_text(text=text)
23
+
14
24
 
15
- @op(description="使用钉钉 Webhook 发送 Markdown 消息",
25
+ @op(description="钉钉Webhook发送Markdown消息",
16
26
  required_resource_keys={'dingtalk_webhook'},
17
- ins={"text": In(str), "title": In(str, default_value='')})
18
- def op_simple_markdown(context: OpExecutionContext, text, title):
19
- webhook = context.resources.dingtalk_webhook
20
- webhook.send_text(text, title)
27
+ ins={
28
+ "text": In(str, description="Markdown 内容"),
29
+ "title": In(str, default_value='', description="标题"),
30
+ "at": In(default_value=None, description="传 List[str] @userIds ,传 List[int] @mobiles ,传 \"ALL\" @所有人。")
31
+ })
32
+ def op_send_markdown(context: OpExecutionContext, text, title, at):
33
+ webhook:DingTalkWebhookResource = context.resources.dingtalk_webhook
34
+ if isinstance(at, str) and at == 'ALL':
35
+ webhook.send_markdown(text=text, title=title, at_all=True)
36
+ if isinstance(at, list) and isinstance(at[0], str):
37
+ webhook.send_markdown(text=text, title=title, at_user_ids=at)
38
+ if isinstance(at, list) and isinstance(at[0], int):
39
+ at = [str(mobile) for mobile in at]
40
+ webhook.send_markdown(text=text, title=title, at_mobiles=at)
41
+ if not at:
42
+ webhook.send_markdown(text=text, title=title)
43
+
44
+
45
+ @op(description="更新钉钉互动卡片",
46
+ required_resource_keys={"dingtalk"},
47
+ ins={"card_param_map":In(), "out_track_id":In(str), "update_by_key":In(bool, default_value=True)},
48
+ out={"is_success":Out(bool, is_required=False)})
49
+ def renew_card(context:OpExecutionContext, card_param_map, out_track_id, update_by_key):
50
+ try:
51
+ dingtalk_yunxiao: DingTalkClient = context.resources.dingtalk_yunxiao
52
+ res = dingtalk_yunxiao.互动卡片.更新卡片(out_track_id=out_track_id, card_param_map=card_param_map, update_card_data_by_key=update_by_key)
53
+ context.log.info(res)
54
+ if res.get('success') and res.get('result'):
55
+ return True
56
+ else:
57
+ return False
58
+ except Exception as e:
59
+ context.log.error(e)
60
+ return False
61
+
62
+
63
+ @op(description="创建并发送钉钉互动卡片",
64
+ ins={"search_type_name":In(str), "alert_content":In(str), "card_template_id":In(str), "card_param_map":In(), "out_track_id":In(str), "open_space_id":In(str)},
65
+ out={"is_success":Out(bool, is_required=False)}, required_resource_keys={"dingtalk"})
66
+ def send_revenue_dt_card(context:OpExecutionContext, search_type_name, alert_content,card_template_id, card_param_map, out_track_id, open_space_id):
67
+ try:
68
+ dingtalk_yunxiao: DingTalkClient = context.resources.dingtalk_yunxiao
69
+ res = dingtalk_yunxiao.互动卡片.创建并投放卡片(
70
+ search_type_name=search_type_name,
71
+ search_desc=alert_content,
72
+ card_template_id=card_template_id,
73
+ card_param_map=card_param_map,
74
+ alert_content=alert_content,
75
+ out_track_id=out_track_id,
76
+ open_space_ids=[open_space_id]
77
+ )
78
+ context.log.info(res)
79
+ return res.get("success")
80
+ except Exception as e:
81
+ context.log.error(e)
82
+ return False
@@ -48,7 +48,7 @@ class DingTalkWebhookResource(ConfigurableResource):
48
48
  - **secret** (str, optional):
49
49
  如使用加签安全配置,则需传签名密钥。默认值为 None。
50
50
  - **alias** (str, optional):
51
- 如提供别名,可以在使用 `MultiDingTalkWebhookResource` 中使用别名进行 webhook 选择。默认值为 None。
51
+ 别名,仅用作标记。默认值为 None。
52
52
  - **base_url** (str, optional):
53
53
  通用地址,一般无需更改。默认值为 “https://oapi.dingtalk.com/robot/send”。
54
54
 
@@ -303,8 +303,6 @@ class DingTalkWebhookResource(ConfigurableResource):
303
303
 
304
304
  class DingTalkAppResource(ConfigurableResource):
305
305
  """
306
- 该 Dagster 资源允许定义一个钉钉的 API Client,更加便捷地调用钉钉服务端企业内部应用 API
307
-
308
306
  [钉钉服务端 API](https://open.dingtalk.com/document/orgapp/api-overview) 企业内部应用部分的第三方封装。
309
307
 
310
308
  通过此资源,可以调用部分钉钉服务端 API。具体封装的 API 可以在 IDE 中通过引入 `DingTalkAppClient` 类来查看 IDE 提示:
@@ -1 +1 @@
1
- __version__ = "0.1.14"
1
+ __version__ = "0.1.16"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dagster-dingtalk
3
- Version: 0.1.14
3
+ Version: 0.1.16
4
4
  Summary: A dagster plugin for the DingTalk
5
5
  Author: YiZixuan
6
6
  Author-email: sqkkyzx@qq.com
@@ -16,32 +16,37 @@ Description-Content-Type: text/markdown
16
16
 
17
17
  # 钉钉与 Dagster 集成
18
18
 
19
- ---
19
+ 该 Dagster 集成是为了更便捷的调用钉钉(DingTalk)的API,集成提供了两个 Dagster Resource。
20
20
 
21
- ## 介绍
21
+ ## 安装
22
+ 要安装库,请在现有的Dagster环境中使用pip。
22
23
 
23
- 该 Dagster 集成是为了更便捷的调用钉钉(DingTalk)的API,集成提供了两个 Dagster Resource。
24
+ ```bash
25
+ pip install dagster-dingtalk
26
+ ```
27
+
28
+ ## 资源
24
29
 
30
+ ### DingTalkWebhookResource
25
31
 
26
- ## DingTalkWebhookResource
32
+ ---
27
33
 
28
34
  该资源允许定义单个钉钉自定义机器人的 Webhook 端点,以便于发送文本、Markdown、Link、 ActionCard、FeedCard 消息,消息具体样式可参考
29
35
  [钉钉开放平台 | 自定义机器人发送消息的消息类型](https://open.dingtalk.com/document/orgapp/custom-bot-send-message-type)。
30
36
 
31
- ### 配置项:
37
+ #### 配置:
32
38
 
33
39
  - **access_token** (str):
34
40
  机器人 Webhook 地址中的 access_token 值。
35
41
  - **secret** (str, optional):
36
42
  如使用加签安全配置,则需传签名密钥。默认值为 None。
37
43
  - **alias** (str, optional):
38
- 如提供别名,可以在使用 `MultiDingTalkWebhookResource` 中使用别名进行 webhook 选择。默认值为 None。
44
+ 别名,仅用作标记。默认值为 None。
39
45
  - **base_url** (str, optional):
40
46
  通用地址,一般无需更改。默认值为 “https://oapi.dingtalk.com/robot/send”。
41
47
 
42
- ### 用例:
48
+ #### 用例 1:使用单个资源
43
49
 
44
- ##### 1. 使用单个资源:
45
50
  ```python
46
51
  from dagster_dingtalk import DingTalkWebhookResource
47
52
  from dagster import op, In, OpExecutionContext, job, Definitions
@@ -61,7 +66,10 @@ defs = Definitions(
61
66
  )
62
67
  ```
63
68
 
64
- ##### 2. 启动时动态构建企业内部应用资源, 可参考 [Dagster文档 | 在启动时配置资源](https://docs.dagster.io/concepts/resources#configuring-resources-at-launch-time)
69
+ #### 用例 2:启动时动态构建 Webhook 资源
70
+
71
+ 如果你事先不确定会用到哪个 webhook 机器人,或是需要根据代码逻辑动态选择 webhook ,dagster 提供了一种 [在运行时配置资源](https://docs.dagster.io/concepts/resources#configuring-resources-at-launch-time)
72
+ 的原生支持。以下是示例:
65
73
 
66
74
  ```python
67
75
  from dagster_dingtalk import DingTalkWebhookResource
@@ -94,30 +102,13 @@ def schedule_user_info():
94
102
  ))
95
103
  ```
96
104
 
97
- ### 注意:
98
-
99
- 应该永远避免直接将密钥字符串直接配置给资源,这会导致在 dagster 前端用户界面暴露密钥。
100
- 应当从环境变量中读取密钥。你可以在代码中注册临时的环境变量,或从系统中引入环境变量。
101
-
102
- ```python
103
- import os
104
- from dagster import EnvVar
105
- from dagster_dingtalk import DingTalkWebhookResource
106
-
107
- # 直接在代码中注册临时的环境变量
108
- os.environ.update({'access_token_name': "<your-access_token>"})
109
- os.environ.update({'secret_name': "<your-secret>"})
110
-
111
- webhook = DingTalkWebhookResource(access_token=EnvVar("access_token_name"), secret=EnvVar("secret_name"))
112
- ```
113
-
114
- ## DingTalkAppResource
115
105
 
116
- Dagster 资源允许定义一个钉钉的 API Client,更加便捷地调用钉钉服务端企业内部应用 API
106
+ ### DingTalkAppResource
117
107
 
118
- [钉钉服务端 API](https://open.dingtalk.com/document/orgapp/api-overview) 企业内部应用部分的第三方封装。
108
+ ---
119
109
 
120
- 通过此资源,可以调用部分钉钉服务端 API。具体封装的 API 可以在 IDE 中通过引入 `DingTalkAppClient` 类来查看 IDE 提示:
110
+ Dagster 资源允许定义一个可以调用 [钉钉服务端 API](https://open.dingtalk.com/document/orgapp/api-overview) Client,
111
+ 具有一些常用 HTTP API 的封装。你可以在 IDE 中通过引入 `DingTalkAppClient` 类来查看 IDE 提示:
121
112
 
122
113
  ```python
123
114
  from dagster_dingtalk import DingTalkAppClient
@@ -125,7 +116,18 @@ from dagster_dingtalk import DingTalkAppClient
125
116
  dingtalk: DingTalkAppClient
126
117
  ```
127
118
 
128
- ### 配置项:
119
+ **请注意:`DingTalkAppClient` 未使用钉钉官方 SDK 实现,并采用了 ASCII 字符来命名实例方法。**
120
+
121
+ > 这是为了与
122
+ > [钉钉服务端 API 文档](https://open.dingtalk.com/document/orgapp/api-overview) 里的中文 API
123
+ > 保持完全一致命名,以便于更符合直觉地进行调用和快速查阅文档。因此,可以按
124
+ > [钉钉服务端 API 文档](https://open.dingtalk.com/document/orgapp/api-overview)
125
+ > 中的层级,通过链式调用来发起 API 请求。例如:
126
+ >
127
+ > `dingtalk.智能人事.花名册.获取花名册元数据()`
128
+
129
+
130
+ #### 配置:
129
131
 
130
132
  - **AppID** (str):
131
133
  应用应用唯一标识 AppID,作为缓存标识符使用。不传入则不缓存鉴权。
@@ -138,9 +140,7 @@ dingtalk: DingTalkAppClient
138
140
  - **ClientSecret** (str):
139
141
  应用的 Client Secret ,原 AppSecret 和 SuiteSecret
140
142
 
141
- ### 用例
142
-
143
- ##### 1. 使用单一的企业内部应用资源。
143
+ #### 用例 1:使用确定的企业内部应用配置资源
144
144
 
145
145
  ```python
146
146
  from dagster_dingtalk import DingTalkAppResource, DingTalkAppClient
@@ -165,7 +165,9 @@ defs = Definitions(
165
165
  )})
166
166
  ```
167
167
 
168
- ##### 2. 启动时动态构建企业内部应用资源, 可参考 [Dagster文档 | 在启动时配置资源](https://docs.dagster.io/concepts/resources#configuring-resources-at-launch-time)
168
+ #### 用例 2:运行时动态构建企业内部应用资源
169
+
170
+ 可参考 [Dagster文档 | 在启动时配置资源](https://docs.dagster.io/concepts/resources#configuring-resources-at-launch-time)
169
171
 
170
172
  ```python
171
173
  from dagster_dingtalk import DingTalkAppResource, DingTalkAppClient
@@ -204,7 +206,22 @@ def schedule_user_info():
204
206
  ))
205
207
  ```
206
208
 
207
- ### 注意:
208
209
 
209
- 应该永远避免直接将密钥字符串直接配置给资源,这会导致在 dagster 前端用户界面暴露密钥。你可以在代码中注册临时的环境变量,或从系统中引入环境变量。
210
+ ## 提醒:
211
+
212
+ 应该永远避免直接将密钥字符串直接配置给资源,这会导致在 dagster 前端用户界面暴露密钥。
213
+ 应当从环境变量中读取密钥。你可以在代码中注册临时的环境变量,或从系统中引入环境变量。
214
+
215
+ ```python
216
+ import os
217
+ from dagster import EnvVar
218
+ from dagster_dingtalk import DingTalkWebhookResource
219
+
220
+ # 直接在代码中注册临时的环境变量
221
+ os.environ.update({'access_token_name': "<your-access_token>"})
222
+ os.environ.update({'secret_name': "<your-secret>"})
223
+
224
+ webhook = DingTalkWebhookResource(access_token=EnvVar("access_token_name"), secret=EnvVar("secret_name"))
225
+ ```
226
+
210
227
 
@@ -0,0 +1,8 @@
1
+ dagster_dingtalk/__init__.py,sha256=CqR5mJA2IrgCFi90KhgTvVLucIn5p978cF7VhXj84u4,418
2
+ dagster_dingtalk/app_client.py,sha256=VNCZhZZ3IntleW5zcUeevtnvtfTnaaRDh3nMJow4btg,23814
3
+ dagster_dingtalk/operations.py,sha256=C1wwXCW7mpKhLC1-Y7TCP_72L9e93a9ceVHRWhNda-Q,3891
4
+ dagster_dingtalk/resources.py,sha256=1u8-oXRa7H_e0CAYkTJDxbjEmt3ZcD_ntBNvrS_rwr8,17430
5
+ dagster_dingtalk/version.py,sha256=yF88-8vL8keLe6gCTumymw0UoMkWkSrJnzLru4zBCLQ,23
6
+ dagster_dingtalk-0.1.16.dist-info/METADATA,sha256=zfr64W7ct1gXJAcQP9sqFVJbrnmQd1j98jnmGyzZ90I,8011
7
+ dagster_dingtalk-0.1.16.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
8
+ dagster_dingtalk-0.1.16.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- dagster_dingtalk/__init__.py,sha256=X7r8JoydXOsT9Sis4rBpVSKQeKJnnZ_t_qFae-ASF7E,466
2
- dagster_dingtalk/app_client.py,sha256=STTBxNzs2rhyHX7gsDuTpftJcctbTPKRAFIZV7zsF08,13800
3
- dagster_dingtalk/operations.py,sha256=3cCZCxh-dAdzzb75WCTKVdzeMV8yu_JJpIeULS7XaNg,761
4
- dagster_dingtalk/resources.py,sha256=HUZX9PSZqyLxiHfsWC-CKsccQC4K0XtBy_LK3af7VTk,17626
5
- dagster_dingtalk/version.py,sha256=PIBqEOI-nqKFL9oJAWQQwlHuujG9Cd7EmdxDrThNQto,23
6
- dagster_dingtalk-0.1.14.dist-info/METADATA,sha256=4gXJVegi44soyMyQevPsiumcjiIqWWkxbj1TssT1XH0,7608
7
- dagster_dingtalk-0.1.14.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
8
- dagster_dingtalk-0.1.14.dist-info/RECORD,,