dagster-dingtalk 0.1.6__py3-none-any.whl → 0.1.9__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
dagster_dingtalk/resources.py
CHANGED
@@ -15,7 +15,7 @@ from dagster import (
|
|
15
15
|
InitResourceContext, ResourceDependency,
|
16
16
|
)
|
17
17
|
from httpx import Client
|
18
|
-
from pydantic import Field, PrivateAttr
|
18
|
+
from pydantic import Field, PrivateAttr
|
19
19
|
|
20
20
|
|
21
21
|
class DingTalkWebhookResource(ConfigurableResource):
|
@@ -24,9 +24,9 @@ class DingTalkWebhookResource(ConfigurableResource):
|
|
24
24
|
alias: Optional[str] = Field(default=None, description="如提供别名,将来可以使用别名进行选择")
|
25
25
|
base_url: str = Field(default="https://oapi.dingtalk.com/robot/send", description="Webhook的通用地址,无需更改")
|
26
26
|
|
27
|
-
def
|
27
|
+
def webhook_url(self):
|
28
28
|
if self.secret is None:
|
29
|
-
return self.
|
29
|
+
return f"{self.base_url}?access_token={self.access_token}"
|
30
30
|
else:
|
31
31
|
timestamp = round(time.time() * 1000)
|
32
32
|
hmac_code = hmac.new(
|
@@ -46,12 +46,12 @@ class DingTalkWebhookResource(ConfigurableResource):
|
|
46
46
|
at["atUserIds"] = at_user_ids
|
47
47
|
if at_mobiles:
|
48
48
|
at["atMobiles"] = at_mobiles
|
49
|
-
httpx.post(url=self.webhook_url, json={"msgtype": "text", "text": {"content": text}, "at": at})
|
49
|
+
httpx.post(url=self.webhook_url(), json={"msgtype": "text", "text": {"content": text}, "at": at})
|
50
50
|
|
51
51
|
def send_link(self, text: str, message_url:str, title:str|None = None, pic_url:str = ""):
|
52
52
|
title = title or self._gen_title(text)
|
53
53
|
httpx.post(
|
54
|
-
url=self.webhook_url,
|
54
|
+
url=self.webhook_url(),
|
55
55
|
json={"msgtype": "link", "link": {"title": title, "text": text, "picUrl": pic_url, "messageUrl": message_url}}
|
56
56
|
)
|
57
57
|
|
@@ -64,7 +64,7 @@ class DingTalkWebhookResource(ConfigurableResource):
|
|
64
64
|
at["atUserIds"] = at_user_ids
|
65
65
|
if at_mobiles:
|
66
66
|
at["atMobiles"] = at_mobiles
|
67
|
-
httpx.post(url=self.webhook_url,json={"msgtype": "markdown", "markdown": {"title": title, "text": text}, "at": at})
|
67
|
+
httpx.post(url=self.webhook_url(),json={"msgtype": "markdown", "markdown": {"title": title, "text": text}, "at": at})
|
68
68
|
|
69
69
|
def send_action_card(self, text: List[str]|str, title:str|None = None, btn_orientation:Literal["0","1"] = "0",
|
70
70
|
single_jump:Tuple[str,str]|None = None, btns_jump:List[Tuple[str,str]]|None = None):
|
@@ -73,10 +73,10 @@ class DingTalkWebhookResource(ConfigurableResource):
|
|
73
73
|
action_card = {"title": title, "text": text, "btnOrientation": btn_orientation}
|
74
74
|
if btns_jump:
|
75
75
|
action_card["btns"] = [{"title": action_title, "actionURL": action_url} for action_title, action_url in btns_jump]
|
76
|
-
httpx.post(url=self.webhook_url, json={"msgtype": "actionCard", "actionCard": action_card})
|
76
|
+
httpx.post(url=self.webhook_url(), json={"msgtype": "actionCard", "actionCard": action_card})
|
77
77
|
elif single_jump:
|
78
78
|
action_card["singleTitle"], action_card["singleURL"] = single_jump
|
79
|
-
httpx.post(url=self.webhook_url, json={"msgtype": "actionCard", "actionCard": action_card})
|
79
|
+
httpx.post(url=self.webhook_url(), json={"msgtype": "actionCard", "actionCard": action_card})
|
80
80
|
else:
|
81
81
|
pass
|
82
82
|
|
@@ -85,7 +85,7 @@ class DingTalkWebhookResource(ConfigurableResource):
|
|
85
85
|
{"title": title, "messageURL": message_url, "picURL": pic_url}
|
86
86
|
for title, message_url, pic_url in links
|
87
87
|
]
|
88
|
-
httpx.post(url=self.webhook_url, json={"msgtype": "feedCard", "feedCard": {"links": links_data}})
|
88
|
+
httpx.post(url=self.webhook_url(), json={"msgtype": "feedCard", "feedCard": {"links": links_data}})
|
89
89
|
|
90
90
|
|
91
91
|
# noinspection NonAsciiCharacters
|
@@ -134,9 +134,12 @@ class MultiDingTalkWebhookResource(ConfigurableResource):
|
|
134
134
|
|
135
135
|
def select(self, key:str = "_FIRST_"):
|
136
136
|
try:
|
137
|
-
if key == "_FIRST_":
|
138
|
-
|
139
|
-
|
137
|
+
if key == "_FIRST_" or key is None:
|
138
|
+
webhook = self.Webhooks[0]
|
139
|
+
else:
|
140
|
+
webhook = self._webhooks[key]
|
141
|
+
webhook.webhook_url()
|
142
|
+
return webhook
|
140
143
|
except KeyError:
|
141
144
|
raise f"该 AccessToken 或 别名 <{key}> 不存在于提供的 Webhooks 中。请使用 DingTalkWebhookResource 定义单个 Webhook 后,将其加入 Webhooks 。"
|
142
145
|
|
@@ -200,7 +203,7 @@ class DingTalkResource(ConfigurableResource):
|
|
200
203
|
f.write(pickle.dumps(all_access_token))
|
201
204
|
return access_token
|
202
205
|
|
203
|
-
def
|
206
|
+
def init_client(self):
|
204
207
|
if not hasattr(self, '_client'):
|
205
208
|
self._client = DingTalkClient(
|
206
209
|
self._get_access_token(),
|
@@ -210,22 +213,19 @@ class DingTalkResource(ConfigurableResource):
|
|
210
213
|
)
|
211
214
|
|
212
215
|
def setup_for_execution(self, context: InitResourceContext) -> None:
|
213
|
-
self.
|
216
|
+
self.init_client()
|
214
217
|
|
215
218
|
def teardown_after_execution(self, context: InitResourceContext) -> None:
|
216
219
|
self._client.api.close()
|
217
220
|
self._client.oapi.close()
|
218
221
|
|
219
222
|
def 智能人事(self):
|
220
|
-
self._init_client()
|
221
223
|
return API_智能人事(self._client)
|
222
224
|
|
223
225
|
def 通讯录管理(self):
|
224
|
-
self._init_client()
|
225
226
|
return API_通讯录管理(self._client)
|
226
227
|
|
227
228
|
def 文档文件(self):
|
228
|
-
self._init_client()
|
229
229
|
return API_文档文件(self._client)
|
230
230
|
|
231
231
|
|
@@ -273,9 +273,12 @@ class MultiDingTalkResource(ConfigurableResource):
|
|
273
273
|
|
274
274
|
def select(self, app_id:str = "_FIRST_"):
|
275
275
|
try:
|
276
|
-
if app_id == "_FIRST_":
|
277
|
-
|
278
|
-
|
276
|
+
if app_id == "_FIRST_" or app_id is None:
|
277
|
+
app = self.Apps[0]
|
278
|
+
else:
|
279
|
+
app = self._apps[app_id]
|
280
|
+
app.init_client()
|
281
|
+
return app
|
279
282
|
except KeyError:
|
280
283
|
raise f"该 AppID <{app_id}> 不存在于提供的 AppLists 中。请使用 DingTalkResource 定义单个 App 后,将其加入 AppLists 。"
|
281
284
|
|
@@ -285,14 +288,14 @@ class API_智能人事:
|
|
285
288
|
def __init__(self, _client:DingTalkClient):
|
286
289
|
self._client = _client
|
287
290
|
|
288
|
-
def 花名册_获取花名册元数据(self):
|
291
|
+
def 花名册_获取花名册元数据(self) -> dict:
|
289
292
|
response = self._client.oapi.post(
|
290
293
|
url="/topapi/smartwork/hrm/roster/meta/get",
|
291
294
|
json={"agentid": self._client.agent_id},
|
292
295
|
)
|
293
296
|
return response.json()
|
294
297
|
|
295
|
-
def 花名册_获取员工花名册字段信息(self, user_id_list:List[str], field_filter_list:List[str]|None = None, text_to_select_convert:bool|None = None):
|
298
|
+
def 花名册_获取员工花名册字段信息(self, user_id_list:List[str], field_filter_list:List[str]|None = None, text_to_select_convert:bool|None = None) -> dict:
|
296
299
|
body_dict = {"userIdList": user_id_list, "appAgentId": self._client.agent_id}
|
297
300
|
if field_filter_list is not None:
|
298
301
|
body_dict["fieldFilterList"] = field_filter_list
|
@@ -309,28 +312,28 @@ class API_智能人事:
|
|
309
312
|
待离职: '5'
|
310
313
|
无状态: '-1'
|
311
314
|
|
312
|
-
def 员工管理_获取待入职员工列表(self, offset:int, size:int):
|
315
|
+
def 员工管理_获取待入职员工列表(self, offset:int, size:int) -> dict:
|
313
316
|
response = self._client.oapi.post(
|
314
317
|
"/topapi/smartwork/hrm/employee/querypreentry",
|
315
318
|
json={"offset": offset, "size": size},
|
316
319
|
)
|
317
320
|
return response.json()
|
318
321
|
|
319
|
-
def 员工管理_获取在职员工列表(self, status_list:List[在职员工状态], offset:int, size:int):
|
322
|
+
def 员工管理_获取在职员工列表(self, status_list:List[在职员工状态], offset:int, size:int) -> dict:
|
320
323
|
response = self._client.oapi.post(
|
321
324
|
"/topapi/smartwork/hrm/employee/querypreentry",
|
322
325
|
json={"status_list": status_list, "offset": offset, "size": size},
|
323
326
|
)
|
324
327
|
return response.json()
|
325
328
|
|
326
|
-
def 员工管理_获取离职员工列表(self, next_token:int, max_results:int):
|
329
|
+
def 员工管理_获取离职员工列表(self, next_token:int, max_results:int) -> dict:
|
327
330
|
response = self._client.api.get(
|
328
331
|
"/v1.0/hrm/employees/dismissions",
|
329
332
|
params={"nextToken": next_token, "maxResults": max_results},
|
330
333
|
)
|
331
334
|
return response.json()
|
332
335
|
|
333
|
-
def 员工管理_批量获取员工离职信息(self, user_id_list:List[str]):
|
336
|
+
def 员工管理_批量获取员工离职信息(self, user_id_list:List[str]) -> dict:
|
334
337
|
response = self._client.api.get(
|
335
338
|
"/v1.0/hrm/employees/dimissionInfo",
|
336
339
|
params={"userIdList": user_id_list},
|
@@ -343,11 +346,11 @@ class API_通讯录管理:
|
|
343
346
|
def __init__(self, _client:DingTalkClient):
|
344
347
|
self._client = _client
|
345
348
|
|
346
|
-
def 查询用户详情(self, user_id:str, language:str = "zh_CN"):
|
349
|
+
def 查询用户详情(self, user_id:str, language:str = "zh_CN") -> dict:
|
347
350
|
response = self._client.oapi.post(url="/topapi/v2/user/get", json={"language": language, "userid": user_id})
|
348
351
|
return response.json()
|
349
352
|
|
350
|
-
def 查询离职记录列表(self, start_time:datetime, end_time:datetime|None, next_token:str, max_results:int):
|
353
|
+
def 查询离职记录列表(self, start_time:datetime, end_time:datetime|None, next_token:str, max_results:int) -> dict:
|
351
354
|
params = {"startTime": start_time.strftime("%Y-%m-%dT%H:%M:%SZ"), "nextToken": next_token, "maxResults": max_results}
|
352
355
|
if end_time is not None:
|
353
356
|
params["endTime"] = end_time.strftime("%Y-%m-%dT%H:%M:%SZ")
|
@@ -360,7 +363,7 @@ class API_文档文件:
|
|
360
363
|
def __init__(self, _client:DingTalkClient):
|
361
364
|
self._client = _client
|
362
365
|
|
363
|
-
def 媒体文件_上传媒体文件(self, file_path:Path|str, media_type:Literal['image', 'voice', 'video', 'file']):
|
366
|
+
def 媒体文件_上传媒体文件(self, file_path:Path|str, media_type:Literal['image', 'voice', 'video', 'file']) -> dict:
|
364
367
|
with open(file_path, 'rb') as f:
|
365
368
|
response = self._client.oapi.post(url=f"/media/upload?type={media_type}", files={'media': f})
|
366
369
|
return response.json()
|
@@ -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=PHCQ63OUXGCanseXjIz54cZJGZIiWqSBbtT7_Cmx8vQ,15226
|
4
|
+
dagster_dingtalk/version.py,sha256=sXLh7g3KC4QCFxcZGBTpG2scR7hmmBsMjq6LqRptkRg,22
|
5
|
+
dagster_dingtalk-0.1.9.dist-info/METADATA,sha256=TOQRFp0JYbf6AHAiQmWCdVE_JMotFmXASAPTFkgcS4Y,1659
|
6
|
+
dagster_dingtalk-0.1.9.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
7
|
+
dagster_dingtalk-0.1.9.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
dagster_dingtalk/__init__.py,sha256=ktvoURpkJwIzcyQfUvnel1KA4DukRgavAgLl7f0Cy_0,440
|
2
|
-
dagster_dingtalk/operations.py,sha256=xJJlOVmFjpaDTMkHZXxj5LbXqRtIQwREl9ZJdXIMOyE,788
|
3
|
-
dagster_dingtalk/resources.py,sha256=P5PW7xpIZ5FXyWsgIODR7RNRzysYeq7q0yrofIA3RdQ,15015
|
4
|
-
dagster_dingtalk/version.py,sha256=sXLh7g3KC4QCFxcZGBTpG2scR7hmmBsMjq6LqRptkRg,22
|
5
|
-
dagster_dingtalk-0.1.6.dist-info/METADATA,sha256=oQkzvE9EHHrNTT8kMLn2EiQw0Gh0uQKhVxjXAyIAR2Y,1659
|
6
|
-
dagster_dingtalk-0.1.6.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
7
|
-
dagster_dingtalk-0.1.6.dist-info/RECORD,,
|
File without changes
|