dagster-dingtalk 0.1.14__py3-none-any.whl → 0.1.16__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,,