flowtask 5.8.4__cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.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.
Files changed (470) hide show
  1. flowtask/__init__.py +93 -0
  2. flowtask/__main__.py +38 -0
  3. flowtask/bots/__init__.py +6 -0
  4. flowtask/bots/check.py +93 -0
  5. flowtask/bots/codebot.py +51 -0
  6. flowtask/components/ASPX.py +148 -0
  7. flowtask/components/AddDataset.py +352 -0
  8. flowtask/components/Amazon.py +523 -0
  9. flowtask/components/AutoTask.py +314 -0
  10. flowtask/components/Azure.py +80 -0
  11. flowtask/components/AzureUsers.py +106 -0
  12. flowtask/components/BaseAction.py +91 -0
  13. flowtask/components/BaseLoop.py +198 -0
  14. flowtask/components/BestBuy.py +800 -0
  15. flowtask/components/CSVToGCS.py +120 -0
  16. flowtask/components/CompanyScraper/__init__.py +1 -0
  17. flowtask/components/CompanyScraper/parsers/__init__.py +6 -0
  18. flowtask/components/CompanyScraper/parsers/base.py +102 -0
  19. flowtask/components/CompanyScraper/parsers/explorium.py +192 -0
  20. flowtask/components/CompanyScraper/parsers/leadiq.py +206 -0
  21. flowtask/components/CompanyScraper/parsers/rocket.py +133 -0
  22. flowtask/components/CompanyScraper/parsers/siccode.py +109 -0
  23. flowtask/components/CompanyScraper/parsers/visualvisitor.py +130 -0
  24. flowtask/components/CompanyScraper/parsers/zoominfo.py +118 -0
  25. flowtask/components/CompanyScraper/scrapper.py +1054 -0
  26. flowtask/components/CopyTo.py +177 -0
  27. flowtask/components/CopyToBigQuery.py +243 -0
  28. flowtask/components/CopyToMongoDB.py +291 -0
  29. flowtask/components/CopyToPg.py +609 -0
  30. flowtask/components/CopyToRethink.py +207 -0
  31. flowtask/components/CreateGCSBucket.py +102 -0
  32. flowtask/components/CreateReport/CreateReport.py +228 -0
  33. flowtask/components/CreateReport/__init__.py +9 -0
  34. flowtask/components/CreateReport/charts/__init__.py +15 -0
  35. flowtask/components/CreateReport/charts/bar.py +51 -0
  36. flowtask/components/CreateReport/charts/base.py +66 -0
  37. flowtask/components/CreateReport/charts/pie.py +64 -0
  38. flowtask/components/CreateReport/utils.py +9 -0
  39. flowtask/components/CustomerSatisfaction.py +196 -0
  40. flowtask/components/DataInput.py +200 -0
  41. flowtask/components/DateList.py +255 -0
  42. flowtask/components/DbClient.py +163 -0
  43. flowtask/components/DialPad.py +146 -0
  44. flowtask/components/DocumentDBQuery.py +200 -0
  45. flowtask/components/DownloadFrom.py +371 -0
  46. flowtask/components/DownloadFromD2L.py +113 -0
  47. flowtask/components/DownloadFromFTP.py +181 -0
  48. flowtask/components/DownloadFromIMAP.py +315 -0
  49. flowtask/components/DownloadFromS3.py +198 -0
  50. flowtask/components/DownloadFromSFTP.py +265 -0
  51. flowtask/components/DownloadFromSharepoint.py +110 -0
  52. flowtask/components/DownloadFromSmartSheet.py +114 -0
  53. flowtask/components/DownloadS3File.py +229 -0
  54. flowtask/components/Dummy.py +59 -0
  55. flowtask/components/DuplicatePhoto.py +411 -0
  56. flowtask/components/EmployeeEvaluation.py +237 -0
  57. flowtask/components/ExecuteSQL.py +323 -0
  58. flowtask/components/ExtractHTML.py +178 -0
  59. flowtask/components/FileBase.py +178 -0
  60. flowtask/components/FileCopy.py +181 -0
  61. flowtask/components/FileDelete.py +82 -0
  62. flowtask/components/FileExists.py +146 -0
  63. flowtask/components/FileIteratorDelete.py +112 -0
  64. flowtask/components/FileList.py +194 -0
  65. flowtask/components/FileOpen.py +75 -0
  66. flowtask/components/FileRead.py +120 -0
  67. flowtask/components/FileRename.py +106 -0
  68. flowtask/components/FilterIf.py +284 -0
  69. flowtask/components/FilterRows/FilterRows.py +200 -0
  70. flowtask/components/FilterRows/__init__.py +10 -0
  71. flowtask/components/FilterRows/functions.py +4 -0
  72. flowtask/components/GCSToBigQuery.py +103 -0
  73. flowtask/components/GoogleA4.py +150 -0
  74. flowtask/components/GoogleGeoCoding.py +344 -0
  75. flowtask/components/GooglePlaces.py +315 -0
  76. flowtask/components/GoogleSearch.py +539 -0
  77. flowtask/components/HTTPClient.py +268 -0
  78. flowtask/components/ICIMS.py +146 -0
  79. flowtask/components/IF.py +179 -0
  80. flowtask/components/IcimsFolderCopy.py +173 -0
  81. flowtask/components/ImageFeatures/__init__.py +5 -0
  82. flowtask/components/ImageFeatures/process.py +233 -0
  83. flowtask/components/IteratorBase.py +251 -0
  84. flowtask/components/LangchainLoader/__init__.py +5 -0
  85. flowtask/components/LangchainLoader/loader.py +194 -0
  86. flowtask/components/LangchainLoader/loaders/__init__.py +22 -0
  87. flowtask/components/LangchainLoader/loaders/abstract.py +362 -0
  88. flowtask/components/LangchainLoader/loaders/basepdf.py +50 -0
  89. flowtask/components/LangchainLoader/loaders/docx.py +91 -0
  90. flowtask/components/LangchainLoader/loaders/html.py +119 -0
  91. flowtask/components/LangchainLoader/loaders/pdfblocks.py +146 -0
  92. flowtask/components/LangchainLoader/loaders/pdfmark.py +79 -0
  93. flowtask/components/LangchainLoader/loaders/pdftables.py +135 -0
  94. flowtask/components/LangchainLoader/loaders/qa.py +67 -0
  95. flowtask/components/LangchainLoader/loaders/txt.py +55 -0
  96. flowtask/components/LeadIQ.py +650 -0
  97. flowtask/components/Loop.py +253 -0
  98. flowtask/components/Lowes.py +334 -0
  99. flowtask/components/MS365Usage.py +156 -0
  100. flowtask/components/MSTeamsMessages.py +320 -0
  101. flowtask/components/MarketClustering.py +1051 -0
  102. flowtask/components/MergeFiles.py +362 -0
  103. flowtask/components/MilvusOutput.py +87 -0
  104. flowtask/components/NearByStores.py +175 -0
  105. flowtask/components/NetworkNinja/__init__.py +6 -0
  106. flowtask/components/NetworkNinja/models/__init__.py +52 -0
  107. flowtask/components/NetworkNinja/models/abstract.py +177 -0
  108. flowtask/components/NetworkNinja/models/account.py +39 -0
  109. flowtask/components/NetworkNinja/models/client.py +19 -0
  110. flowtask/components/NetworkNinja/models/district.py +14 -0
  111. flowtask/components/NetworkNinja/models/events.py +101 -0
  112. flowtask/components/NetworkNinja/models/forms.py +499 -0
  113. flowtask/components/NetworkNinja/models/market.py +16 -0
  114. flowtask/components/NetworkNinja/models/organization.py +34 -0
  115. flowtask/components/NetworkNinja/models/photos.py +125 -0
  116. flowtask/components/NetworkNinja/models/project.py +44 -0
  117. flowtask/components/NetworkNinja/models/region.py +28 -0
  118. flowtask/components/NetworkNinja/models/store.py +203 -0
  119. flowtask/components/NetworkNinja/models/user.py +151 -0
  120. flowtask/components/NetworkNinja/router.py +854 -0
  121. flowtask/components/Odoo.py +175 -0
  122. flowtask/components/OdooInjector.py +192 -0
  123. flowtask/components/OpenFromXML.py +126 -0
  124. flowtask/components/OpenWeather.py +41 -0
  125. flowtask/components/OpenWithBase.py +616 -0
  126. flowtask/components/OpenWithPandas.py +715 -0
  127. flowtask/components/PGPDecrypt.py +199 -0
  128. flowtask/components/PandasIterator.py +187 -0
  129. flowtask/components/PandasToFile.py +189 -0
  130. flowtask/components/Paradox.py +339 -0
  131. flowtask/components/ParamIterator.py +117 -0
  132. flowtask/components/ParseHTML.py +84 -0
  133. flowtask/components/PlacerStores.py +249 -0
  134. flowtask/components/Pokemon.py +507 -0
  135. flowtask/components/PositiveBot.py +62 -0
  136. flowtask/components/PowerPointSlide.py +400 -0
  137. flowtask/components/PrintMessage.py +127 -0
  138. flowtask/components/ProductCompetitors/__init__.py +5 -0
  139. flowtask/components/ProductCompetitors/parsers/__init__.py +7 -0
  140. flowtask/components/ProductCompetitors/parsers/base.py +72 -0
  141. flowtask/components/ProductCompetitors/parsers/bestbuy.py +86 -0
  142. flowtask/components/ProductCompetitors/parsers/lowes.py +103 -0
  143. flowtask/components/ProductCompetitors/scrapper.py +155 -0
  144. flowtask/components/ProductCompliant.py +169 -0
  145. flowtask/components/ProductInfo/__init__.py +1 -0
  146. flowtask/components/ProductInfo/parsers/__init__.py +5 -0
  147. flowtask/components/ProductInfo/parsers/base.py +83 -0
  148. flowtask/components/ProductInfo/parsers/brother.py +97 -0
  149. flowtask/components/ProductInfo/parsers/canon.py +167 -0
  150. flowtask/components/ProductInfo/parsers/epson.py +118 -0
  151. flowtask/components/ProductInfo/parsers/hp.py +131 -0
  152. flowtask/components/ProductInfo/parsers/samsung.py +97 -0
  153. flowtask/components/ProductInfo/scraper.py +319 -0
  154. flowtask/components/ProductPricing.py +118 -0
  155. flowtask/components/QS.py +261 -0
  156. flowtask/components/QSBase.py +201 -0
  157. flowtask/components/QueryIterator.py +273 -0
  158. flowtask/components/QueryToInsert.py +327 -0
  159. flowtask/components/QueryToPandas.py +432 -0
  160. flowtask/components/RESTClient.py +195 -0
  161. flowtask/components/RethinkDBQuery.py +189 -0
  162. flowtask/components/Rsync.py +74 -0
  163. flowtask/components/RunSSH.py +59 -0
  164. flowtask/components/RunShell.py +71 -0
  165. flowtask/components/SalesForce.py +20 -0
  166. flowtask/components/SaveImageBank/__init__.py +257 -0
  167. flowtask/components/SchedulingVisits.py +592 -0
  168. flowtask/components/ScrapPage.py +216 -0
  169. flowtask/components/ScrapSearch.py +79 -0
  170. flowtask/components/SendNotify.py +257 -0
  171. flowtask/components/SentimentAnalysis.py +694 -0
  172. flowtask/components/ServiceScrapper/__init__.py +5 -0
  173. flowtask/components/ServiceScrapper/parsers/__init__.py +1 -0
  174. flowtask/components/ServiceScrapper/parsers/base.py +94 -0
  175. flowtask/components/ServiceScrapper/parsers/costco.py +93 -0
  176. flowtask/components/ServiceScrapper/scrapper.py +199 -0
  177. flowtask/components/SetVariables.py +156 -0
  178. flowtask/components/SubTask.py +182 -0
  179. flowtask/components/SuiteCRM.py +48 -0
  180. flowtask/components/Switch.py +175 -0
  181. flowtask/components/TableBase.py +148 -0
  182. flowtask/components/TableDelete.py +312 -0
  183. flowtask/components/TableInput.py +143 -0
  184. flowtask/components/TableOutput/TableOutput.py +384 -0
  185. flowtask/components/TableOutput/__init__.py +3 -0
  186. flowtask/components/TableSchema.py +534 -0
  187. flowtask/components/Target.py +223 -0
  188. flowtask/components/ThumbnailGenerator.py +156 -0
  189. flowtask/components/ToPandas.py +67 -0
  190. flowtask/components/TransformRows/TransformRows.py +507 -0
  191. flowtask/components/TransformRows/__init__.py +9 -0
  192. flowtask/components/TransformRows/functions.py +559 -0
  193. flowtask/components/TransposeRows.py +176 -0
  194. flowtask/components/UPCDatabase.py +86 -0
  195. flowtask/components/UnGzip.py +171 -0
  196. flowtask/components/Uncompress.py +172 -0
  197. flowtask/components/UniqueRows.py +126 -0
  198. flowtask/components/Unzip.py +107 -0
  199. flowtask/components/UpdateOperationalVars.py +147 -0
  200. flowtask/components/UploadTo.py +299 -0
  201. flowtask/components/UploadToS3.py +136 -0
  202. flowtask/components/UploadToSFTP.py +160 -0
  203. flowtask/components/UploadToSharepoint.py +205 -0
  204. flowtask/components/UserFunc.py +122 -0
  205. flowtask/components/VivaTracker.py +140 -0
  206. flowtask/components/WSDLClient.py +123 -0
  207. flowtask/components/Wait.py +18 -0
  208. flowtask/components/Walmart.py +199 -0
  209. flowtask/components/Workplace.py +134 -0
  210. flowtask/components/XMLToPandas.py +267 -0
  211. flowtask/components/Zammad/__init__.py +41 -0
  212. flowtask/components/Zammad/models.py +0 -0
  213. flowtask/components/ZoomInfoScraper.py +409 -0
  214. flowtask/components/__init__.py +104 -0
  215. flowtask/components/abstract.py +18 -0
  216. flowtask/components/flow.py +530 -0
  217. flowtask/components/google.py +335 -0
  218. flowtask/components/group.py +221 -0
  219. flowtask/components/py.typed +0 -0
  220. flowtask/components/reviewscrap.py +132 -0
  221. flowtask/components/tAutoincrement.py +117 -0
  222. flowtask/components/tConcat.py +109 -0
  223. flowtask/components/tExplode.py +119 -0
  224. flowtask/components/tFilter.py +184 -0
  225. flowtask/components/tGroup.py +236 -0
  226. flowtask/components/tJoin.py +270 -0
  227. flowtask/components/tMap/__init__.py +9 -0
  228. flowtask/components/tMap/functions.py +54 -0
  229. flowtask/components/tMap/tMap.py +450 -0
  230. flowtask/components/tMelt.py +112 -0
  231. flowtask/components/tMerge.py +114 -0
  232. flowtask/components/tOrder.py +93 -0
  233. flowtask/components/tPandas.py +94 -0
  234. flowtask/components/tPivot.py +71 -0
  235. flowtask/components/tPluckCols.py +76 -0
  236. flowtask/components/tUnnest.py +82 -0
  237. flowtask/components/user.py +401 -0
  238. flowtask/conf.py +457 -0
  239. flowtask/download.py +102 -0
  240. flowtask/events/__init__.py +11 -0
  241. flowtask/events/events/__init__.py +20 -0
  242. flowtask/events/events/abstract.py +95 -0
  243. flowtask/events/events/alerts/__init__.py +362 -0
  244. flowtask/events/events/alerts/colfunctions.py +131 -0
  245. flowtask/events/events/alerts/functions.py +158 -0
  246. flowtask/events/events/dummy.py +12 -0
  247. flowtask/events/events/exec.py +124 -0
  248. flowtask/events/events/file/__init__.py +7 -0
  249. flowtask/events/events/file/base.py +51 -0
  250. flowtask/events/events/file/copy.py +23 -0
  251. flowtask/events/events/file/delete.py +16 -0
  252. flowtask/events/events/interfaces/__init__.py +9 -0
  253. flowtask/events/events/interfaces/client.py +67 -0
  254. flowtask/events/events/interfaces/credentials.py +28 -0
  255. flowtask/events/events/interfaces/notifications.py +58 -0
  256. flowtask/events/events/jira.py +122 -0
  257. flowtask/events/events/log.py +26 -0
  258. flowtask/events/events/logerr.py +52 -0
  259. flowtask/events/events/notify.py +59 -0
  260. flowtask/events/events/notify_event.py +160 -0
  261. flowtask/events/events/publish.py +54 -0
  262. flowtask/events/events/sendfile.py +104 -0
  263. flowtask/events/events/task.py +97 -0
  264. flowtask/events/events/teams.py +98 -0
  265. flowtask/events/events/webhook.py +58 -0
  266. flowtask/events/manager.py +287 -0
  267. flowtask/exceptions.c +39393 -0
  268. flowtask/exceptions.cpython-312-x86_64-linux-gnu.so +0 -0
  269. flowtask/extensions/__init__.py +3 -0
  270. flowtask/extensions/abstract.py +82 -0
  271. flowtask/extensions/logging/__init__.py +65 -0
  272. flowtask/hooks/__init__.py +9 -0
  273. flowtask/hooks/actions/__init__.py +22 -0
  274. flowtask/hooks/actions/abstract.py +66 -0
  275. flowtask/hooks/actions/dummy.py +23 -0
  276. flowtask/hooks/actions/jira.py +74 -0
  277. flowtask/hooks/actions/rest.py +320 -0
  278. flowtask/hooks/actions/sampledata.py +37 -0
  279. flowtask/hooks/actions/sensor.py +23 -0
  280. flowtask/hooks/actions/task.py +9 -0
  281. flowtask/hooks/actions/ticket.py +37 -0
  282. flowtask/hooks/actions/zammad.py +55 -0
  283. flowtask/hooks/hook.py +62 -0
  284. flowtask/hooks/models.py +17 -0
  285. flowtask/hooks/service.py +187 -0
  286. flowtask/hooks/step.py +91 -0
  287. flowtask/hooks/types/__init__.py +23 -0
  288. flowtask/hooks/types/base.py +129 -0
  289. flowtask/hooks/types/brokers/__init__.py +11 -0
  290. flowtask/hooks/types/brokers/base.py +54 -0
  291. flowtask/hooks/types/brokers/mqtt.py +35 -0
  292. flowtask/hooks/types/brokers/rabbitmq.py +82 -0
  293. flowtask/hooks/types/brokers/redis.py +83 -0
  294. flowtask/hooks/types/brokers/sqs.py +44 -0
  295. flowtask/hooks/types/fs.py +232 -0
  296. flowtask/hooks/types/http.py +49 -0
  297. flowtask/hooks/types/imap.py +200 -0
  298. flowtask/hooks/types/jira.py +279 -0
  299. flowtask/hooks/types/mail.py +205 -0
  300. flowtask/hooks/types/postgres.py +98 -0
  301. flowtask/hooks/types/responses/__init__.py +8 -0
  302. flowtask/hooks/types/responses/base.py +5 -0
  303. flowtask/hooks/types/sharepoint.py +288 -0
  304. flowtask/hooks/types/ssh.py +141 -0
  305. flowtask/hooks/types/tagged.py +59 -0
  306. flowtask/hooks/types/upload.py +85 -0
  307. flowtask/hooks/types/watch.py +71 -0
  308. flowtask/hooks/types/web.py +36 -0
  309. flowtask/interfaces/AzureClient.py +137 -0
  310. flowtask/interfaces/AzureGraph.py +839 -0
  311. flowtask/interfaces/Boto3Client.py +326 -0
  312. flowtask/interfaces/DropboxClient.py +173 -0
  313. flowtask/interfaces/ExcelHandler.py +94 -0
  314. flowtask/interfaces/FTPClient.py +131 -0
  315. flowtask/interfaces/GoogleCalendar.py +201 -0
  316. flowtask/interfaces/GoogleClient.py +133 -0
  317. flowtask/interfaces/GoogleDrive.py +127 -0
  318. flowtask/interfaces/GoogleGCS.py +89 -0
  319. flowtask/interfaces/GoogleGeocoding.py +93 -0
  320. flowtask/interfaces/GoogleLang.py +114 -0
  321. flowtask/interfaces/GooglePub.py +61 -0
  322. flowtask/interfaces/GoogleSheet.py +68 -0
  323. flowtask/interfaces/IMAPClient.py +137 -0
  324. flowtask/interfaces/O365Calendar.py +113 -0
  325. flowtask/interfaces/O365Client.py +220 -0
  326. flowtask/interfaces/OneDrive.py +284 -0
  327. flowtask/interfaces/Outlook.py +155 -0
  328. flowtask/interfaces/ParrotBot.py +130 -0
  329. flowtask/interfaces/SSHClient.py +378 -0
  330. flowtask/interfaces/Sharepoint.py +496 -0
  331. flowtask/interfaces/__init__.py +36 -0
  332. flowtask/interfaces/azureauth.py +119 -0
  333. flowtask/interfaces/cache.py +201 -0
  334. flowtask/interfaces/client.py +82 -0
  335. flowtask/interfaces/compress.py +525 -0
  336. flowtask/interfaces/credentials.py +124 -0
  337. flowtask/interfaces/d2l.py +239 -0
  338. flowtask/interfaces/databases/__init__.py +5 -0
  339. flowtask/interfaces/databases/db.py +223 -0
  340. flowtask/interfaces/databases/documentdb.py +55 -0
  341. flowtask/interfaces/databases/rethink.py +39 -0
  342. flowtask/interfaces/dataframes/__init__.py +11 -0
  343. flowtask/interfaces/dataframes/abstract.py +21 -0
  344. flowtask/interfaces/dataframes/arrow.py +71 -0
  345. flowtask/interfaces/dataframes/dt.py +69 -0
  346. flowtask/interfaces/dataframes/pandas.py +167 -0
  347. flowtask/interfaces/dataframes/polars.py +60 -0
  348. flowtask/interfaces/db.py +263 -0
  349. flowtask/interfaces/env.py +46 -0
  350. flowtask/interfaces/func.py +137 -0
  351. flowtask/interfaces/http.py +1780 -0
  352. flowtask/interfaces/locale.py +40 -0
  353. flowtask/interfaces/log.py +75 -0
  354. flowtask/interfaces/mask.py +143 -0
  355. flowtask/interfaces/notification.py +154 -0
  356. flowtask/interfaces/playwright.py +339 -0
  357. flowtask/interfaces/powerpoint.py +368 -0
  358. flowtask/interfaces/py.typed +0 -0
  359. flowtask/interfaces/qs.py +376 -0
  360. flowtask/interfaces/result.py +87 -0
  361. flowtask/interfaces/selenium_service.py +779 -0
  362. flowtask/interfaces/smartsheet.py +154 -0
  363. flowtask/interfaces/stat.py +39 -0
  364. flowtask/interfaces/task.py +96 -0
  365. flowtask/interfaces/template.py +118 -0
  366. flowtask/interfaces/vectorstores/__init__.py +1 -0
  367. flowtask/interfaces/vectorstores/abstract.py +133 -0
  368. flowtask/interfaces/vectorstores/milvus.py +669 -0
  369. flowtask/interfaces/zammad.py +107 -0
  370. flowtask/models.py +193 -0
  371. flowtask/parsers/__init__.py +15 -0
  372. flowtask/parsers/_yaml.c +11978 -0
  373. flowtask/parsers/_yaml.cpython-312-x86_64-linux-gnu.so +0 -0
  374. flowtask/parsers/argparser.py +235 -0
  375. flowtask/parsers/base.c +15155 -0
  376. flowtask/parsers/base.cpython-312-x86_64-linux-gnu.so +0 -0
  377. flowtask/parsers/json.c +11968 -0
  378. flowtask/parsers/json.cpython-312-x86_64-linux-gnu.so +0 -0
  379. flowtask/parsers/maps.py +49 -0
  380. flowtask/parsers/toml.c +11968 -0
  381. flowtask/parsers/toml.cpython-312-x86_64-linux-gnu.so +0 -0
  382. flowtask/plugins/__init__.py +16 -0
  383. flowtask/plugins/components/__init__.py +0 -0
  384. flowtask/plugins/handler/__init__.py +45 -0
  385. flowtask/plugins/importer.py +31 -0
  386. flowtask/plugins/sources/__init__.py +0 -0
  387. flowtask/runner.py +283 -0
  388. flowtask/scheduler/__init__.py +9 -0
  389. flowtask/scheduler/functions.py +493 -0
  390. flowtask/scheduler/handlers/__init__.py +8 -0
  391. flowtask/scheduler/handlers/manager.py +504 -0
  392. flowtask/scheduler/handlers/models.py +58 -0
  393. flowtask/scheduler/handlers/service.py +72 -0
  394. flowtask/scheduler/notifications.py +65 -0
  395. flowtask/scheduler/scheduler.py +993 -0
  396. flowtask/services/__init__.py +0 -0
  397. flowtask/services/bots/__init__.py +0 -0
  398. flowtask/services/bots/telegram.py +264 -0
  399. flowtask/services/files/__init__.py +11 -0
  400. flowtask/services/files/manager.py +522 -0
  401. flowtask/services/files/model.py +37 -0
  402. flowtask/services/files/service.py +767 -0
  403. flowtask/services/jira/__init__.py +3 -0
  404. flowtask/services/jira/jira_actions.py +191 -0
  405. flowtask/services/tasks/__init__.py +13 -0
  406. flowtask/services/tasks/launcher.py +213 -0
  407. flowtask/services/tasks/manager.py +323 -0
  408. flowtask/services/tasks/service.py +275 -0
  409. flowtask/services/tasks/task_manager.py +376 -0
  410. flowtask/services/tasks/tasks.py +155 -0
  411. flowtask/storages/__init__.py +16 -0
  412. flowtask/storages/exceptions.py +12 -0
  413. flowtask/storages/files/__init__.py +8 -0
  414. flowtask/storages/files/abstract.py +29 -0
  415. flowtask/storages/files/filesystem.py +66 -0
  416. flowtask/storages/tasks/__init__.py +19 -0
  417. flowtask/storages/tasks/abstract.py +26 -0
  418. flowtask/storages/tasks/database.py +33 -0
  419. flowtask/storages/tasks/filesystem.py +108 -0
  420. flowtask/storages/tasks/github.py +119 -0
  421. flowtask/storages/tasks/memory.py +45 -0
  422. flowtask/storages/tasks/row.py +25 -0
  423. flowtask/tasks/__init__.py +0 -0
  424. flowtask/tasks/abstract.py +526 -0
  425. flowtask/tasks/command.py +118 -0
  426. flowtask/tasks/pile.py +486 -0
  427. flowtask/tasks/py.typed +0 -0
  428. flowtask/tasks/task.py +778 -0
  429. flowtask/template/__init__.py +161 -0
  430. flowtask/tests.py +257 -0
  431. flowtask/types/__init__.py +8 -0
  432. flowtask/types/typedefs.c +11347 -0
  433. flowtask/types/typedefs.cpython-312-x86_64-linux-gnu.so +0 -0
  434. flowtask/utils/__init__.py +24 -0
  435. flowtask/utils/constants.py +117 -0
  436. flowtask/utils/encoders.py +21 -0
  437. flowtask/utils/executor.py +112 -0
  438. flowtask/utils/functions.cpp +14280 -0
  439. flowtask/utils/functions.cpython-312-x86_64-linux-gnu.so +0 -0
  440. flowtask/utils/json.cpp +13349 -0
  441. flowtask/utils/json.cpython-312-x86_64-linux-gnu.so +0 -0
  442. flowtask/utils/mail.py +63 -0
  443. flowtask/utils/parseqs.c +13324 -0
  444. flowtask/utils/parserqs.cpython-312-x86_64-linux-gnu.so +0 -0
  445. flowtask/utils/stats.py +308 -0
  446. flowtask/utils/transformations.py +74 -0
  447. flowtask/utils/uv.py +12 -0
  448. flowtask/utils/validators.py +97 -0
  449. flowtask/version.py +11 -0
  450. flowtask-5.8.4.dist-info/LICENSE +201 -0
  451. flowtask-5.8.4.dist-info/METADATA +209 -0
  452. flowtask-5.8.4.dist-info/RECORD +470 -0
  453. flowtask-5.8.4.dist-info/WHEEL +6 -0
  454. flowtask-5.8.4.dist-info/entry_points.txt +3 -0
  455. flowtask-5.8.4.dist-info/top_level.txt +2 -0
  456. plugins/components/CreateQR.py +39 -0
  457. plugins/components/TestComponent.py +28 -0
  458. plugins/components/Use1.py +13 -0
  459. plugins/components/Workplace.py +117 -0
  460. plugins/components/__init__.py +3 -0
  461. plugins/sources/__init__.py +0 -0
  462. plugins/sources/get_populartimes.py +78 -0
  463. plugins/sources/google.py +150 -0
  464. plugins/sources/hubspot.py +679 -0
  465. plugins/sources/icims.py +679 -0
  466. plugins/sources/mobileinsight.py +501 -0
  467. plugins/sources/newrelic.py +262 -0
  468. plugins/sources/uap.py +268 -0
  469. plugins/sources/venu.py +244 -0
  470. plugins/sources/vocinity.py +314 -0
@@ -0,0 +1,160 @@
1
+ # Logging:
2
+ from navconfig.logging import logging
3
+
4
+ ## Notify System
5
+ from notify import Notify
6
+ from notify.providers.email import Email
7
+ from notify.providers.slack import Slack
8
+ from notify.providers.teams import Teams
9
+ from notify.models import (
10
+ Actor,
11
+ Chat,
12
+ Channel,
13
+ TeamsCard,
14
+ TeamsChannel
15
+ )
16
+ from ...conf import (
17
+ SEND_NOTIFICATIONS,
18
+ EVENT_CHAT_ID,
19
+ EVENT_CHAT_BOT,
20
+ NOTIFY_ON_ERROR,
21
+ NOTIFY_ON_SUCCESS,
22
+ NOTIFY_ON_FAILURE,
23
+ NOTIFY_ON_WARNING,
24
+ DEFAULT_RECIPIENT,
25
+ EMAIL_USERNAME,
26
+ EMAIL_PASSWORD,
27
+ EMAIL_PORT,
28
+ EMAIL_HOST,
29
+ ENVIRONMENT,
30
+ SLACK_DEFAULT_CHANNEL,
31
+ SLACK_DEFAULT_CHANNEL_NAME,
32
+ MS_TEAMS_DEFAULT_TEAMS_ID,
33
+ MS_TEAMS_DEFAULT_CHANNEL_ID,
34
+ MS_TEAMS_DEFAULT_CHANNEL_NAME,
35
+ SHOW_VERSION
36
+ )
37
+ from ...utils.functions import check_empty
38
+ from .abstract import AbstractEvent
39
+ from ...version import __version__
40
+
41
+
42
+ class NotifyEvent(AbstractEvent):
43
+ """Using Notify to send notifications for task Execution."""
44
+
45
+ def __init__(self, *args, event: str = "done", **kwargs):
46
+ super(NotifyEvent, self).__init__(*args, **kwargs)
47
+ self._logger = logging.getLogger("FlowTask.Notify")
48
+ self._event_ = event
49
+ if event == "done":
50
+ self.event = NOTIFY_ON_SUCCESS
51
+ elif event == "warning":
52
+ self.event = NOTIFY_ON_WARNING
53
+ elif event == "error":
54
+ self.event = NOTIFY_ON_ERROR
55
+ elif event == "exception":
56
+ self.event = NOTIFY_ON_FAILURE
57
+ else:
58
+ self.event = NOTIFY_ON_SUCCESS
59
+
60
+ def getNotify(self, notify, **kwargs):
61
+ if notify == "telegram":
62
+ # defining the Default chat object:
63
+ recipient = Chat(**{"chat_id": EVENT_CHAT_ID, "chat_name": "Navigator"})
64
+ # send notifications to Telegram bot
65
+ args = {"bot_token": EVENT_CHAT_BOT, **kwargs}
66
+ ntf = Notify("telegram", **args)
67
+ elif notify == "slack":
68
+ recipient = Channel(
69
+ channel_id=SLACK_DEFAULT_CHANNEL,
70
+ channel_name=SLACK_DEFAULT_CHANNEL_NAME,
71
+ )
72
+ ntf = Slack()
73
+ elif notify == "email":
74
+ account = {
75
+ "host": EMAIL_HOST,
76
+ "port": EMAIL_PORT,
77
+ "username": EMAIL_USERNAME,
78
+ "password": EMAIL_PASSWORD,
79
+ **kwargs,
80
+ }
81
+ recipient = Actor(**DEFAULT_RECIPIENT)
82
+ ntf = Email(debug=True, **account)
83
+ elif notify == 'teams':
84
+ team_id = kwargs.pop("team_id", MS_TEAMS_DEFAULT_TEAMS_ID)
85
+ recipient = TeamsChannel(
86
+ name=MS_TEAMS_DEFAULT_CHANNEL_NAME,
87
+ team_id=team_id,
88
+ channel_id=MS_TEAMS_DEFAULT_CHANNEL_ID
89
+ )
90
+ ntf = Teams(
91
+ as_user=True,
92
+ team_id=team_id,
93
+ )
94
+ else:
95
+ # Any other Notify Provider:
96
+ recipient = Actor(**DEFAULT_RECIPIENT)
97
+ ntf = Notify(notify, **kwargs)
98
+ return [ntf, recipient]
99
+
100
+ async def __call__(self, *args, **kwargs):
101
+ if SEND_NOTIFICATIONS is False:
102
+ return
103
+ task = kwargs.pop("task", None)
104
+ result = kwargs.pop("result", None)
105
+ message = kwargs.pop("message", None)
106
+ trace = kwargs.pop("stacktrace", None)
107
+ error = kwargs.pop("error", None)
108
+ program = task.getProgram()
109
+ task_name = task.taskname
110
+ component = kwargs.pop("component", None)
111
+ if error is not None:
112
+ self.event = NOTIFY_ON_ERROR
113
+ if program and task and component:
114
+ message = f"🛑 ::{ENVIRONMENT} - Task {program}.{task_name}, Error on {component}: {error!s}"
115
+ elif program and task:
116
+ message = (
117
+ f"🛑 ::{ENVIRONMENT} - Error on {program}.{task_name}: {error!s}"
118
+ )
119
+ elif trace is not None:
120
+ self.event = NOTIFY_ON_FAILURE
121
+ message = f"🛑 ::{ENVIRONMENT} - {program}.{task_name}: {error!s}"
122
+ else:
123
+ message = f"🛑 ::{ENVIRONMENT} - {program}.{task_name}: {error!s}"
124
+ elif self._event_ == "warning":
125
+ message = f" ⚠️ :: {ENVIRONMENT} - *{program}.{task_name}*: Warning {component}->{str(message)!s}"
126
+ else:
127
+ if message is not None and result is not None:
128
+ # success event:
129
+ self.event = NOTIFY_ON_SUCCESS
130
+ message = f" ✅ :: {ENVIRONMENT} - {program}.{task_name}: {message!s}"
131
+ elif not check_empty(result):
132
+ message = f" ✅ :: {ENVIRONMENT} - {program}.{task_name}: {message!s}"
133
+ else:
134
+ message = f" ⚠️ :: {ENVIRONMENT} - {program}.{task_name}: {message!s}, Empty Result."
135
+
136
+ if SHOW_VERSION:
137
+ message = f"{message} - Version: {__version__}"
138
+ ntf, recipients = self.getNotify(self.event, **kwargs)
139
+ args = {"recipient": [recipients], "message": message}
140
+ if self.event == 'teams':
141
+ channel = recipients
142
+ msg = TeamsCard(
143
+ text=str(message),
144
+ summary=f"Task Summary: {program}.{task_name}",
145
+ title=f"Task {program}.{task_name}",
146
+ )
147
+ async with ntf as conn:
148
+ return await conn.send(
149
+ recipient=channel,
150
+ message=msg
151
+ )
152
+ elif ntf.provider_type == "email":
153
+ args["subject"] = message
154
+ elif ntf.provider == "telegram":
155
+ args["disable_notification"] = True
156
+ else:
157
+ args["subject"] = message
158
+ async with ntf as t:
159
+ result = await t.send(**args)
160
+ return result
@@ -0,0 +1,54 @@
1
+ import socket
2
+ from datetime import datetime, timezone
3
+ from redis import asyncio as aioredis
4
+ from navconfig.logging import logging
5
+ from ...utils.json import json_encoder
6
+ from ...conf import (
7
+ ENVIRONMENT,
8
+ PUBSUB_REDIS
9
+ )
10
+ from .abstract import AbstractEvent
11
+
12
+ EVENT_HOST = socket.gethostbyname(socket.gethostname())
13
+
14
+
15
+ class PublishEvent(AbstractEvent):
16
+ async def __call__(self, *args, **kwargs):
17
+ status = kwargs.pop("status", "event")
18
+ task = kwargs.pop("task", None)
19
+ program = task.getProgram()
20
+ task_name = task.taskname.replace(
21
+ ".", ":"
22
+ ) # Convert dots to colons for Redis channel name
23
+ channel_name = f"{program}:{task_name}"
24
+ task_id = task.task_id
25
+ redis = await aioredis.from_url(
26
+ PUBSUB_REDIS,
27
+ encoding="utf-8",
28
+ decode_responses=True
29
+ )
30
+ try:
31
+ stat = task.stats # getting the stat object:
32
+ stats = json_encoder(stat.to_json())
33
+ except AttributeError:
34
+ stats = None
35
+ msg = {
36
+ "task": f"{program}.{task_name}",
37
+ "task_id": task_id,
38
+ "status": status,
39
+ "environment": ENVIRONMENT,
40
+ "host": EVENT_HOST,
41
+ "stats": stats,
42
+ "end_time": datetime.now(timezone.utc),
43
+ }
44
+ message = json_encoder(msg)
45
+ try:
46
+ await redis.publish(channel_name, message)
47
+ except Exception as e:
48
+ logging.warning(f"Event Publisher Error: {e}")
49
+ finally:
50
+ await redis.close()
51
+ try:
52
+ await redis.connection_pool.disconnect()
53
+ except Exception:
54
+ pass
@@ -0,0 +1,104 @@
1
+ from typing import Union
2
+ from collections.abc import Callable, Iterable
3
+ import asyncio
4
+ from pathlib import Path
5
+ from notify.models import Actor
6
+ from notify import Notify
7
+ from ...exceptions import FileNotFound, ActionError
8
+ from .interfaces import ClientInterface
9
+ from .abstract import AbstractEvent
10
+
11
+
12
+ def expand_path(filename: Union[str, Path]) -> Iterable[Path]:
13
+ if isinstance(filename, str):
14
+ p = Path(filename)
15
+ else:
16
+ p = filename
17
+ return list(Path(p.parent).expanduser().glob(p.name))
18
+
19
+
20
+ class SendFile(ClientInterface, AbstractEvent):
21
+ def __init__(self, *args, **kwargs):
22
+ self.list_attachment: list = []
23
+ self.notify: Callable = None
24
+ super(SendFile, self).__init__(*args, **kwargs)
25
+
26
+ async def __call__(self, *args, **kwargs):
27
+ # determine the recipients:
28
+ # TODO: add support for mailing lists
29
+ try:
30
+ self._recipients = [Actor(**user) for user in self.recipients]
31
+ except Exception as err:
32
+ raise RuntimeError(f"Error formatting Recipients: {err}") from err
33
+ if not self._recipients:
34
+ raise RuntimeError("SendNotify: Invalid Number of Recipients.")
35
+
36
+ # File Attachment:
37
+ # TODO: multiple attachments
38
+ if hasattr(self, "directory"):
39
+ d = self.mask_replacement(
40
+ self.directory # pylint: disable=access-member-before-definition
41
+ )
42
+ p = Path(d) # pylint: disable=E0203
43
+ if p.exists() and p.is_dir():
44
+ self.directory = p
45
+ else:
46
+ self._logger.error(f"Path doesn't exists: {self.directory}")
47
+ else:
48
+ self.directory = None
49
+
50
+ if hasattr(self, "filename"):
51
+ file = self.mask_replacement(self.filename)
52
+ files = []
53
+ if self.directory:
54
+ fs = self.directory.joinpath(file)
55
+ files = expand_path(fs)
56
+ else:
57
+ files = expand_path(file)
58
+ for file in files:
59
+ if file.exists():
60
+ self.list_attachment.append(file)
61
+ else:
62
+ raise FileNotFound(f"File doesn't exists: {file}")
63
+
64
+ # Mask transform of message
65
+ for key, value in self.message.items():
66
+ self.message[key] = self.mask_replacement(value)
67
+
68
+ try:
69
+ await self.open()
70
+ async with self.notify as mail:
71
+ try:
72
+ result = await mail.send(
73
+ recipient=self._recipients,
74
+ attachments=self.list_attachment,
75
+ **self.message,
76
+ )
77
+ self._logger.debug(f"Notification Status: {result}")
78
+ except Exception as err:
79
+ raise ActionError(f"SendNotify Error: {err}") from err
80
+ return None
81
+ finally:
82
+ await self.close()
83
+
84
+ async def close(self):
85
+ """close.
86
+ Closing the connection.
87
+ """
88
+ if self.notify:
89
+ try:
90
+ await self.notify.close()
91
+ except Exception as err:
92
+ print(err)
93
+
94
+ async def open(self):
95
+ """open.
96
+ Starts (open) a connection to an external resource.
97
+ """
98
+ try:
99
+ self.notify = Notify(
100
+ "email", loop=asyncio.get_event_loop(), **self.credentials
101
+ )
102
+ except Exception as err:
103
+ raise ActionError(f"Error Creating Notification App: {err}") from err
104
+ return self
@@ -0,0 +1,97 @@
1
+ import asyncio
2
+ import pandas as pd
3
+ from navconfig import DEBUG
4
+ from navconfig.logging import logging
5
+ from .abstract import AbstractEvent
6
+ from ...exceptions import (
7
+ NotSupported,
8
+ TaskNotFound,
9
+ TaskFailed,
10
+ FileError,
11
+ FileNotFound,
12
+ DataNotFound,
13
+ )
14
+
15
+
16
+ class RunTask(AbstractEvent):
17
+ def __init__(self, *args, **kwargs):
18
+ super(RunTask, self).__init__(*args, **kwargs)
19
+ self.program = kwargs.pop("program", None)
20
+ self.task = kwargs.pop("task", None)
21
+
22
+ def run_task_in_thread(self, task_coroutine):
23
+ loop = asyncio.new_event_loop() # Create a new event loop for the thread
24
+ asyncio.set_event_loop(loop)
25
+ loop.run_until_complete(task_coroutine)
26
+ loop.close()
27
+
28
+ async def task_execution(self):
29
+ # avoid circular import
30
+ from flowtask.tasks.task import Task # noqa
31
+
32
+ result = {}
33
+ task = Task(
34
+ task=self.task,
35
+ program=self.program,
36
+ loop=asyncio.get_event_loop(),
37
+ enable_stat=False,
38
+ ignore_results=True,
39
+ debug=DEBUG,
40
+ )
41
+ try:
42
+ state = await task.start()
43
+ if not state:
44
+ logging.warning(
45
+ f"Task {self.program}.{self.task} return False on Start Time."
46
+ )
47
+ except Exception as err:
48
+ logging.error(err)
49
+ raise
50
+ try:
51
+ state = await task.run()
52
+ try:
53
+ result["stats"] = task.stats.stats
54
+ except Exception as err:
55
+ result["stats"] = None
56
+ result["error"] = err
57
+ ### gettting the result of Task execution
58
+ if isinstance(state, pd.DataFrame):
59
+ numrows = len(state.index)
60
+ columns = list(state.columns)
61
+ num_cols = len(columns)
62
+ state = {
63
+ "type": "Dataframe",
64
+ "numrows": numrows,
65
+ "columns": columns,
66
+ "num_cols": num_cols,
67
+ }
68
+ else:
69
+ state = f"{state!r}"
70
+ result["result"] = state
71
+ await task.close()
72
+ return result
73
+ except DataNotFound as err:
74
+ raise
75
+ except NotSupported as err:
76
+ raise
77
+ except TaskNotFound as err:
78
+ raise TaskNotFound(f"Task: {self.task}: {err}") from err
79
+ except TaskFailed as err:
80
+ raise TaskFailed(f"Task {self.task} failed: {err}") from err
81
+ except FileNotFound:
82
+ raise
83
+ except FileError as err:
84
+ raise FileError(f"Task {self.task}, File Not Found error: {err}") from err
85
+ except Exception as err:
86
+ raise TaskFailed(f"Error: Task {self.task} failed: {err}") from err
87
+
88
+ async def __call__(self, *args, **kwargs):
89
+ self._logger.debug(f":: Running Task: {self.program}.{self.task}")
90
+ return await self.task_execution()
91
+ # task_coroutine = self.task_execution()
92
+ # task_thread = threading.Thread(
93
+ # target=self.run_task_in_thread,
94
+ # args=(task_coroutine,)
95
+ # )
96
+ # task_thread.start()
97
+ # task_thread.join() # Wait for the thread to finish
@@ -0,0 +1,98 @@
1
+ import codecs
2
+ import orjson
3
+ from notify.models import TeamsCard, TeamsChannel
4
+ from notify.providers.teams import Teams
5
+ from notify.conf import MS_TEAMS_DEFAULT_TEAMS_ID, MS_TEAMS_DEFAULT_CHANNEL_ID
6
+ from ...utils.json import json_encoder
7
+ from ...interfaces.env import EnvSupport
8
+ from .abstract import AbstractEvent
9
+
10
+
11
+ class TeamsMessage(AbstractEvent):
12
+ def __init__(self, *args, **kwargs):
13
+ super(TeamsMessage, self).__init__(*args, **kwargs)
14
+ self.channel = kwargs.get('channel', MS_TEAMS_DEFAULT_CHANNEL_ID)
15
+ self.team_id = kwargs.get('team_id', MS_TEAMS_DEFAULT_TEAMS_ID)
16
+ self.team_id = self.get_env_value(self.team_id, default=self.team_id)
17
+ self.channel = self.get_env_value(self.channel, default=self.channel)
18
+ self.channel_name = kwargs.get('channel_name', 'General')
19
+ self.channel_name = self.get_env_value(self.channel_name, default=self.channel_name)
20
+ self._text = self.mask_replacement(kwargs.pop("text", ''))
21
+ self._title = self.mask_replacement(kwargs.pop("title", 'Task Info:'))
22
+
23
+ async def __call__(self, *args, **kwargs):
24
+ tm = Teams(
25
+ as_user=True,
26
+ team_id=self.team_id,
27
+ )
28
+ channel = TeamsChannel(
29
+ name=self.channel_name,
30
+ team_id=self.team_id,
31
+ channel_id=self.channel,
32
+ )
33
+ status = kwargs.pop("status", "done")
34
+ task = kwargs.pop("task", None)
35
+ program = task.getProgram()
36
+ task_name = f"{program}.{task.taskname}"
37
+ task_id = task.task_id
38
+ message = kwargs.pop("message", f"Task Completed {task_name}, {task_id}")
39
+ message = self.mask_replacement(message)
40
+ summary = kwargs.pop("summary", f"Task Summary: {task_name}")
41
+ summary = self.mask_replacement(summary)
42
+ try:
43
+ stat = task.stats # getting the stat object:
44
+ stats = stat.to_json()
45
+ except AttributeError:
46
+ stats = []
47
+ if status == "done":
48
+ icon = "✅"
49
+ elif status in ("error", "failed", "exception", "task error"):
50
+ icon = "🛑"
51
+ elif status in (
52
+ "warning",
53
+ "file_not_found",
54
+ "not_found",
55
+ "data_not_found",
56
+ "done_warning",
57
+ ):
58
+ icon = "⚠️"
59
+ elif status in ("empty_file"):
60
+ icon = "📄"
61
+ else:
62
+ icon = "✅"
63
+ txt = f"{icon} {message}"
64
+ if self.type == "card":
65
+ msg = TeamsCard(
66
+ title=f"Task {task_name} uid:{task_id}",
67
+ text=txt,
68
+ summary=summary,
69
+ )
70
+ if hasattr(self, "with_stats"):
71
+ # iterate over task stats:
72
+ for stat, value in stats["steps"].items():
73
+ section = msg.addSection(activityTitle=stat, text=stat)
74
+ stats_json = orjson.dumps(value, option=orjson.OPT_INDENT_2 | orjson.OPT_APPEND_NEWLINE).decode()
75
+ section.addFacts(
76
+ facts=[{"name": stat, "value": stats_json}]
77
+ )
78
+ if hasattr(self, 'with_codereview'):
79
+ # Add Code Review
80
+ section = msg.addSection(activityTitle="Code Review", text="Code Review")
81
+ codereview = codecs.decode(json_encoder(stats['Review']), 'unicode_escape')
82
+ section.addFacts(
83
+ facts=[{"name": "Code Review", "value": codereview}]
84
+ )
85
+ else:
86
+ # only one single block of text:
87
+ section = msg.addSection(
88
+ activityTitle=self._title,
89
+ text=self._text,
90
+ )
91
+ section.addFacts(
92
+ facts=[{"name": "Info", "value": self._text}]
93
+ )
94
+ async with tm as conn:
95
+ return await conn.send(
96
+ recipient=channel,
97
+ message=msg
98
+ )
@@ -0,0 +1,58 @@
1
+ import aiohttp
2
+ from ...utils.json import json_encoder
3
+ from .abstract import AbstractEvent
4
+
5
+
6
+ class WebHook(AbstractEvent):
7
+ def __init__(self, *args, **kwargs):
8
+ self.url = kwargs.pop("url", None)
9
+ super(WebHook, self).__init__(*args, **kwargs)
10
+
11
+ async def __call__(self, *args, **kwargs):
12
+ if not self.url:
13
+ raise ValueError("URL was not provided for WebHook event action.")
14
+ status = kwargs.pop("status", "event")
15
+ task = kwargs.pop("task", None)
16
+ program = task.getProgram()
17
+ task_name = f"{program}.{task.taskname}"
18
+ task_id = task.task_id
19
+ try:
20
+ stat = task.stats # getting the stat object:
21
+ stats = json_encoder(stat.to_json())
22
+ except AttributeError:
23
+ stats = None
24
+
25
+ # Extract optional authentication parameters
26
+ auth_type = self._kwargs.get("auth_type", None)
27
+ auth_value = self._kwargs.get("auth_value", None)
28
+
29
+ headers = {}
30
+ if auth_type and auth_value:
31
+ if auth_type.lower() == "basic":
32
+ headers["Authorization"] = f"Basic {auth_value}"
33
+ elif auth_type.lower() == "bearer":
34
+ headers["Authorization"] = f"Bearer {auth_value}"
35
+ else:
36
+ raise ValueError(f"Unsupported authentication type: {auth_type}")
37
+
38
+ # Prepare the payload. You can customize this based on your needs.
39
+ payload = {
40
+ "task": task_name,
41
+ "id": str(task_id),
42
+ "status": status,
43
+ "message": kwargs.get("message", "Task Completed."),
44
+ "stats": stats,
45
+ }
46
+ async with aiohttp.ClientSession() as session:
47
+ async with session.post(
48
+ self.url, json=payload, headers=headers
49
+ ) as response:
50
+ if response.status != 200:
51
+ # Handle non-200 responses if necessary
52
+ response = await response.text()
53
+ self._logger.warning(
54
+ f"Error on WebHook response: {response}, status: {response.status}"
55
+ )
56
+ else:
57
+ # Handle successful webhook call if necessary
58
+ return