flowtask 5.8.4__cp39-cp39-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-39-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-39-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-39-x86_64-linux-gnu.so +0 -0
  377. flowtask/parsers/json.c +11968 -0
  378. flowtask/parsers/json.cpython-39-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-39-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-39-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-39-x86_64-linux-gnu.so +0 -0
  440. flowtask/utils/json.cpp +13349 -0
  441. flowtask/utils/json.cpython-39-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-39-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
flowtask/tasks/task.py ADDED
@@ -0,0 +1,778 @@
1
+ import asyncio
2
+ import traceback
3
+ from typing import Any, Optional
4
+ from collections.abc import Callable
5
+ from asyncdb.exceptions import NoDataFound, ProviderError
6
+ # Flowtask Core:
7
+ from ..interfaces.log import SkipErrors
8
+ from ..utils.stats import StepMonitor
9
+ from ..models import TaskState, setTaskState
10
+ from ..exceptions import (
11
+ TaskFailed,
12
+ TaskDefinition,
13
+ TaskError,
14
+ TaskParseError,
15
+ TaskNotFound,
16
+ NotSupported,
17
+ ComponentError,
18
+ DataNotFound,
19
+ FileNotFound,
20
+ FileError,
21
+ DataError,
22
+ EmptyFile,
23
+ )
24
+ from ..tasks.pile import TaskPile
25
+ from ..utils import cPrint, check_empty, AttrDict
26
+ from .abstract import AbstractTask
27
+ from ..events import NotifyEvent, LogError
28
+ from ..events.events.exec import LogExecution, SaveExecution
29
+ from ..bots import CodeReview, ENABLE_BOT_REVIEWER
30
+
31
+
32
+ class Task(AbstractTask):
33
+ """
34
+ Task.
35
+
36
+ Object contain a Flow Task.
37
+ """
38
+
39
+ def __init__(
40
+ self,
41
+ task_id: str = None,
42
+ task: str = None,
43
+ program: str = None,
44
+ loop: asyncio.AbstractEventLoop = None,
45
+ parser: Callable = None,
46
+ worker: Callable = None,
47
+ **kwargs,
48
+ ) -> None:
49
+ self._pile_: TaskPile = None
50
+ self._steps = None
51
+ self._vars = None
52
+ super(Task, self).__init__(
53
+ task_id=task_id,
54
+ task=task,
55
+ program=program,
56
+ loop=loop,
57
+ parser=parser,
58
+ **kwargs,
59
+ )
60
+ self._taskname = task
61
+ self._conditions = {}
62
+ self._attrs = {}
63
+ self.ignore_steps = []
64
+ self.run_only = []
65
+ self._stepattrs = {}
66
+ self._kwargs = {}
67
+ self._masks = {}
68
+ self._resultset: Any = None
69
+ self._codereview = None
70
+ self._task_payload = None
71
+ if not self._taskname:
72
+ raise TaskError(
73
+ 'Missing Task Name, \
74
+ HINT: add --task (in command line) or parameter "task" \
75
+ with a task name'
76
+ )
77
+ # change root-level attributes on fly
78
+ if parser:
79
+ self._attrs = parser.attributes
80
+ attrs = kwargs.pop('attributes', {})
81
+ self._attrs = {**self._attrs, **attrs}
82
+ # disable Events:
83
+ self._no_events: bool = kwargs.pop("no_events", False)
84
+ self.logger.notice(
85
+ f"Disabled Events: {self._no_events}"
86
+ )
87
+ # for component-based attributes (ex: --DownloadFromIMAP_1:host)
88
+ if parser:
89
+ self._stepattrs = parser.stepattrs
90
+ # Steps:
91
+ steps = kwargs.pop('steps', {})
92
+ if steps:
93
+ self._stepattrs = {**self._stepattrs, **steps}
94
+ # Is a Subtask?
95
+ self.is_subtask: bool = kwargs.pop('is_subtask', False)
96
+ # override attributes:
97
+ self._override_attributes = kwargs.pop("override_attributes", False)
98
+ self.ignore_steps = kwargs.pop('ignore_steps', [])
99
+ self.run_only = kwargs.pop('run_only', [])
100
+ if parser:
101
+ self._override_attributes = self._options.override_attributes
102
+ # ignoring components in task execution.
103
+ self.ignore_steps = self._options.ignore
104
+ # list of "run only" components:
105
+ self.run_only = self._options.run_only
106
+ # variables: can be passed between components as reusable values.
107
+ if parser:
108
+ self._variables = self._options.variables
109
+ # parsing variables:
110
+ variables = kwargs.pop('variables', {})
111
+ if isinstance(variables, dict):
112
+ self._variables = {**self._variables, **variables}
113
+ self.logger.debug(
114
+ f"CURRENTLY NEW Variables: {self._variables}"
115
+ )
116
+ # masks: replacing masks with values or even new functions
117
+ if parser:
118
+ self._masks = self._options.masks
119
+ self._conditions = self._options.conditions
120
+ self._args = self._options.args
121
+ try:
122
+ conditions = kwargs["conditions"]
123
+ except KeyError:
124
+ conditions = {}
125
+ self._conditions = {**self._conditions, **conditions}
126
+ self.logger.debug(
127
+ f"CURRENTLY NEW CONDS: {self._conditions}"
128
+ )
129
+ self.worker = worker
130
+ if kwargs:
131
+ # remain args go to kwargs:
132
+ self._kwargs = {**kwargs}
133
+ # add also the Log execution for InfluxDB
134
+ self.event_defaults(
135
+ LogExecution(disable_notification=self._no_notify)
136
+ )
137
+ ## set the Task State:
138
+ running = getattr(self._events, "running")
139
+ running.add(setTaskState)
140
+ completed = getattr(self._events, "completed")
141
+ completed.add(setTaskState)
142
+ # Special Events:
143
+ self._events.exception += NotifyEvent(event="exception")
144
+ self._events.data_not_found += NotifyEvent(event="warning")
145
+ self._events.data_error += NotifyEvent(event="error")
146
+ self._events.file_not_found += NotifyEvent(event="error")
147
+ self._events.file_empty += NotifyEvent(event="error")
148
+ # Internal On Finished Events:
149
+ self._events.done += NotifyEvent(event="done")
150
+ self._events.on_error += NotifyEvent(event="error")
151
+ self._events.completed += SaveExecution(disable_notification=self._no_notify)
152
+ # and Log for Errors:
153
+ logerr = LogError()
154
+ self._events.file_not_found += logerr
155
+ self._events.data_not_found += logerr
156
+ self._events.exception += logerr
157
+ # Code Review on Errors or Exceptions:
158
+ if ENABLE_BOT_REVIEWER is True:
159
+ self._codereview = CodeReview(task=self)
160
+ self._events.exception += self._codereview
161
+ self._events.on_error += self._codereview
162
+
163
+ async def close(self):
164
+ """close.
165
+
166
+ Closing the remaining connections.
167
+ """
168
+ if self.is_subtask is False:
169
+ await super(Task, self).close()
170
+ self._pile_ = None
171
+ self._steps = None
172
+ self._args = None
173
+
174
+ @property
175
+ def variables(self):
176
+ return self._vars
177
+
178
+ @property
179
+ def taskname(self):
180
+ return self._taskname
181
+
182
+ def __repr__(self) -> str:
183
+ return f"{self._program}.{self._taskname}"
184
+
185
+ def pile(self):
186
+ return self._pile_
187
+
188
+ async def prepare(self):
189
+ if self._task_:
190
+ # calling steps
191
+ try:
192
+ self._pile_ = TaskPile(self._task_, program=self._program)
193
+ except (KeyError, TaskDefinition) as exc:
194
+ raise TaskDefinition(
195
+ f"Bad Task Definition: {exc!s}"
196
+ ) from exc
197
+ except Exception as exc:
198
+ raise TaskDefinition(
199
+ f"Task Exception {self._program}.{self._taskname}: {exc!s}"
200
+ ) from exc
201
+ ## Processing Event list:
202
+ try:
203
+ self._events.LoadEvents(
204
+ self._task_.get('events')
205
+ )
206
+ except KeyError:
207
+ pass
208
+ return True
209
+ else:
210
+ raise TaskDefinition(
211
+ f"Flowtkas: Invalid Task: {self._program}.{self._taskname}"
212
+ )
213
+
214
+ def get_component(self, step, prev):
215
+ step_name = step.name
216
+ if self.enable_stat is True:
217
+ stat = StepMonitor(name=step_name, parent=self.stat)
218
+ self.stat.add_step(stat)
219
+ else:
220
+ stat = None
221
+ params = step.params()
222
+ params["program"] = self._program
223
+ params["ENV"] = self._env
224
+ # params:
225
+ params["params"] = self._params
226
+ # parameters
227
+ params["parameters"] = self._parameters
228
+ # useful to change variables in set var components
229
+ params["_vars"] = self._kwargs
230
+ # variables dictionary
231
+ try:
232
+ variables = params["variables"]
233
+ except KeyError:
234
+ variables = {}
235
+ if prev:
236
+ variables = {**variables, **prev.variables}
237
+ params["variables"] = {**self._variables, **variables}
238
+ params["_masks"] = self._masks # override mask value
239
+ try:
240
+ arguments = params["arguments"]
241
+ except KeyError:
242
+ arguments = []
243
+ if not self._arguments:
244
+ self._arguments = []
245
+ params["arguments"] = arguments + self._arguments
246
+ # argument list for components (or tasks) that need argument lists
247
+ params["_args"] = self._args
248
+ # for components with conditions, we can add more conditions
249
+ try:
250
+ conditions = params["conditions"]
251
+ except KeyError:
252
+ conditions = {}
253
+ params["conditions"] = {**conditions, **self._conditions}
254
+ # attributes only usable component-only
255
+ if step_name in self._stepattrs or step_name.startswith('SubTask'):
256
+ # this can rewrite attributes for steps
257
+ if self._override_attributes:
258
+ newattrs = self._stepattrs.get(step_name, {})
259
+ self._attrs = {**self._attrs, **newattrs}
260
+ else:
261
+ self._attrs = {**self._attrs, **self._stepattrs}
262
+ # will be a dictionary with ComponentName: parameter
263
+ params["attributes"] = self._attrs
264
+ # the current Pile of components
265
+ params["TaskPile"] = self._pile_
266
+ params["debug"] = self._debug
267
+ params["argparser"] = self._argparser
268
+ params["taskstorage"] = self.taskstore
269
+ component = None
270
+ component = step.component
271
+ # get dependency
272
+ depends = step.getDepends(prev)
273
+ if "TaskPile" in params["parameters"]:
274
+ del params["parameters"]["TaskPile"]
275
+ try:
276
+ comp = component(
277
+ job=depends, loop=self._loop, stat=stat, step_name=step_name, **params # stats object
278
+ )
279
+ self.logger.debug(f"Task.{self.task_id}: Component {comp}")
280
+ comp.TaskName = step_name
281
+ comp.set_filestore(self._filestore)
282
+ comp.set_taskstore(self.taskstore)
283
+ return comp
284
+ except Exception as err:
285
+ raise ComponentError(
286
+ f"DI: Component Error on {self._taskname}, \
287
+ Component: {step_name} error: {err}"
288
+ ) from err
289
+
290
+ def resultset(self):
291
+ return self._resultset
292
+
293
+ async def exchange_variables(self, component, result: Any = None):
294
+ # TODO: saving results on Redis, variables on Memory, etc.
295
+ self._variables = component.variables
296
+ self._resultset = result
297
+
298
+ def _on_error(self, status: str, exc: BaseException, step_name: str = None):
299
+ if isinstance(exc, str):
300
+ error = exc
301
+ else:
302
+ error = str(exc)
303
+ try:
304
+ self.logger.error(str(exc))
305
+ self._state = TaskState.ERROR
306
+ trace = traceback.format_exc()
307
+ self._events.on_error(
308
+ message=error,
309
+ component=self._taskname,
310
+ task=self,
311
+ status=status,
312
+ error=exc,
313
+ stacktrace=trace
314
+ )
315
+ except AttributeError as err:
316
+ self.logger.error(f"Error {self._taskname}={self.task_id}, {err}")
317
+ raise TaskError(f"Error on Event System: {err}") from err
318
+ finally:
319
+ # call the OnComplete Event
320
+ if self._no_events is False:
321
+ self._events.completed(
322
+ message=f":: Task Error: {self._program}.{self._taskname}",
323
+ task=self,
324
+ status="error",
325
+ error=exc,
326
+ )
327
+ if step_name:
328
+ raise ComponentError(f"{error!s}")
329
+ else:
330
+ raise exc
331
+
332
+ def _on_exception(self, status: str, exc: BaseException, step_name: str = None):
333
+ try:
334
+ self._state = TaskState.EXCEPTION
335
+ trace = traceback.format_exc()
336
+ self._events.exception(
337
+ message=f"{exc!s}",
338
+ component=step_name,
339
+ task=self,
340
+ status=status,
341
+ stacktrace=trace,
342
+ )
343
+ except AttributeError as err:
344
+ self.logger.error(f"Error {self._taskname}={self.task_id}, {err}")
345
+ raise TaskError(f"Error on Event System: {err}") from err
346
+ finally:
347
+ # call the OnComplete Event
348
+ if self._no_events is False:
349
+ self._events.completed(
350
+ message=f":: Task Ended: {self._program}.{self._taskname}",
351
+ task=self,
352
+ status=status,
353
+ error=exc,
354
+ )
355
+ if step_name:
356
+ raise ComponentError(
357
+ f"Error Getting Component {step_name}, error: {exc}"
358
+ )
359
+ elif isinstance(exc, TaskParseError):
360
+ raise TaskParseError(
361
+ f"{self._program}.{self._taskname}: {exc!s}"
362
+ )
363
+ else:
364
+ raise TaskError(
365
+ f"Task Error {self._program}.{self._taskname}: {exc!s}"
366
+ )
367
+
368
+ def get_task_code(self):
369
+ return self._task_payload
370
+
371
+ async def start(self, payload: Optional[str] = None):
372
+ # starting a Task
373
+ await super(Task, self).start()
374
+ self.logger.info(
375
+ f"Task Started {self._taskname}"
376
+ )
377
+ # Open Task:
378
+ try:
379
+ payload = await self.taskstore.open_task(
380
+ task=self._taskname,
381
+ program=self._program,
382
+ payload=payload
383
+ )
384
+ self._task_payload = payload
385
+ if not payload:
386
+ raise TaskNotFound(
387
+ f"Task Missing or empty: {self._taskname}"
388
+ )
389
+ except TaskParseError as exc:
390
+ self._on_exception(
391
+ status="Parsing Error",
392
+ exc=exc
393
+ )
394
+ except TaskNotFound as exc:
395
+ self._on_exception(
396
+ status="Task Not Found",
397
+ exc=exc
398
+ )
399
+ except Exception as exc:
400
+ self._on_exception(
401
+ status="Task Error",
402
+ exc=exc
403
+ )
404
+ # task is loaded, we need to check syntax.
405
+ # TODO: check syntax of YAML and TOML versions
406
+ try:
407
+ self.check_syntax(payload)
408
+ except TaskParseError as exc:
409
+ self._on_exception(
410
+ status="Parsing Error",
411
+ exc=exc
412
+ )
413
+ # can prepare the task before run.
414
+ try:
415
+ self._task_ = AttrDict(payload)
416
+ if "timezone" in self._task_:
417
+ # re-set timezone based on a Task parameter
418
+ self.set_timezone(self._task_.timezone)
419
+ await self.prepare()
420
+ return True
421
+ except TaskDefinition as exc:
422
+ self._on_exception(
423
+ status="Error on Task Definition",
424
+ exc=exc
425
+ )
426
+ except NotSupported as exc:
427
+ self._on_exception(
428
+ status="Not Supported", exc=exc
429
+ )
430
+ except Exception as exc:
431
+ self._on_exception(
432
+ status="Unknown Exception",
433
+ exc=exc
434
+ )
435
+
436
+ def _task_running(self):
437
+ try:
438
+ self._state = TaskState.RUNNING
439
+ if self._no_events is False:
440
+ self._events.running(
441
+ message=f":: Task.{self.task_id} Running: {self._program}.{self._taskname}",
442
+ task=self,
443
+ status="running",
444
+ disable_notification=self._no_notify,
445
+ )
446
+ except AttributeError as exc:
447
+ raise TaskError(f"Error on Event System: {exc}") from exc
448
+ except Exception as err: # pytest: disable=W0718
449
+ self.logger.error(
450
+ f"Failed to set Running status on task {self._taskname}={self.task_id}, {err}"
451
+ )
452
+
453
+ def _on_done(self, result):
454
+ try:
455
+ self._state = TaskState.DONE
456
+ if self._no_events is False:
457
+ self._events.done(
458
+ message=f":: Task Ended: {self._program}.{self._taskname}",
459
+ result=result,
460
+ task=self,
461
+ status="done",
462
+ disable_notification=self._no_notify,
463
+ )
464
+ except AttributeError as err:
465
+ self.logger.error(f"Error {self._taskname}={self.task_id}, {err}")
466
+ raise TaskError(f"Error at Task Done: {err}") from err
467
+ finally:
468
+ if self._no_events is False:
469
+ # call the OnComplete Event
470
+ self._events.completed(
471
+ message=f":: Task Ended: {self._program}.{self._taskname}",
472
+ status="done",
473
+ task=self,
474
+ result=result,
475
+ )
476
+
477
+ def _data_error(self, status: str, exc: BaseException, step_name: str = None):
478
+ try:
479
+ self._state = TaskState.DONE_WITH_WARNINGS
480
+ self._events.data_error(
481
+ message=f"Data Error: {exc}",
482
+ component=step_name,
483
+ task=self,
484
+ status=status,
485
+ )
486
+ except AttributeError as err:
487
+ self.logger.error(f"Error {self._taskname}={self.task_id}, {err}")
488
+ raise TaskError(f"Error on Event System: {err}") from err
489
+ finally:
490
+ # call the OnComplete Event
491
+ if self._no_events is False:
492
+ self._events.completed(
493
+ message=f":: Data Error: {self._program}.{self._taskname}",
494
+ status=status,
495
+ task=self,
496
+ error=exc,
497
+ )
498
+ # and raise the exception:
499
+ if isinstance(exc, BaseException):
500
+ raise exc
501
+ else:
502
+ raise TaskError(str(exc))
503
+
504
+ def _not_found(self, status: str, exc: BaseException, step_name: str = None):
505
+ try:
506
+ self._state = TaskState.DONE_WITH_NODATA
507
+ if self._no_events is False:
508
+ self._events.data_not_found(
509
+ message=f"Not Found: {exc}",
510
+ component=step_name,
511
+ task=self,
512
+ status=status,
513
+ )
514
+ except AttributeError as err:
515
+ self.logger.error(f"Error {self._taskname}={self.task_id}, {err}")
516
+ raise TaskError(f"Error on Event System: {err}") from err
517
+ finally:
518
+ # call the OnComplete Event
519
+ if self._no_events is False:
520
+ self._events.completed(
521
+ message=f":: Not Found: {self._program}.{self._taskname}",
522
+ status=status,
523
+ task=self,
524
+ error=exc,
525
+ )
526
+ # and raise the exception:
527
+ if isinstance(exc, BaseException):
528
+ raise exc
529
+ else:
530
+ raise TaskError(str(exc))
531
+
532
+ def _file_empty(self, status: str, exc: BaseException, step_name: str = None):
533
+ try:
534
+ self._state = TaskState.ERROR
535
+ if self._no_events is False:
536
+ self._events.file_empty(
537
+ message=f"Empty File: {exc}",
538
+ error=exc,
539
+ component=step_name,
540
+ task=self,
541
+ status=status,
542
+ )
543
+ except AttributeError as err:
544
+ self.logger.error(f"Error {self._taskname}={self.task_id}, {err}")
545
+ raise TaskError(f"Error on Event System: {err}") from err
546
+ finally:
547
+ # call the OnComplete Event
548
+ if self._no_events is False:
549
+ self._events.completed(
550
+ message=f":: Empty File: {self._program}.{self._taskname}",
551
+ status=status,
552
+ task=self,
553
+ error=exc,
554
+ )
555
+ # and raise the exception:
556
+ if isinstance(exc, BaseException):
557
+ raise exc
558
+ else:
559
+ raise TaskError(str(exc))
560
+
561
+ def _file_not_found(self, status: str, exc: BaseException, step_name: str = None):
562
+ try:
563
+ self._state = TaskState.ERROR
564
+ if self._no_events is False:
565
+ self._events.file_not_found(
566
+ message=f"File Not Found: {exc}",
567
+ error=exc,
568
+ component=step_name,
569
+ task=self,
570
+ status=status,
571
+ )
572
+ except AttributeError as err:
573
+ self.logger.error(f"Error {self._taskname}={self.task_id}, {err}")
574
+ raise TaskError(f"Error on Event System: {err}") from err
575
+ finally:
576
+ # call the OnComplete Event
577
+ if self._no_events is False:
578
+ self._events.completed(
579
+ message=f":: Not Found: {self._program}.{self._taskname}",
580
+ status=status,
581
+ task=self,
582
+ error=exc,
583
+ )
584
+ # and raise the exception:
585
+ raise exc
586
+
587
+ async def run(self):
588
+ # run Task and returning the result.
589
+ result = None
590
+ comp = None
591
+ prev = None
592
+ _exit = False
593
+ failed: list = []
594
+ try:
595
+ task_name = self._task_.name
596
+ except TypeError:
597
+ task_name = self._taskname
598
+ self._task_running()
599
+ for step in self._pile_:
600
+ self.logger.notice(f"Step: {step.name}, Task: {self.task_id}")
601
+ step_name = step.name
602
+ if step_name in self.ignore_steps:
603
+ # we can ignore this component for execution
604
+ continue
605
+ if len(self.run_only) > 0:
606
+ # we only need to run the existing list of components
607
+ if step_name not in self.run_only:
608
+ continue
609
+ prev = comp
610
+ try:
611
+ comp = self.get_component(step, prev)
612
+ step.setStep(comp) # put the Component initialized in the Pile.
613
+ except Exception as err:
614
+ self._on_exception(status="exception", exc=err, step_name=step_name)
615
+ if self._debug:
616
+ cPrint(f":: Running {step_name} from {task_name}", level="DEBUG")
617
+ # try START
618
+ try:
619
+ start = getattr(comp, "start")
620
+ parameters = comp.user_params()
621
+ if callable(start):
622
+ if asyncio.iscoroutinefunction(start):
623
+ await comp.start(**parameters)
624
+ else:
625
+ comp.start()
626
+ else:
627
+ self._on_error(
628
+ status="not_started",
629
+ exc=f"DI: Error calling Start on Component {step_name}",
630
+ step_name=step_name,
631
+ )
632
+ except EmptyFile as exc:
633
+ self._file_empty(status="empty_file", exc=exc, step_name=step_name)
634
+ except FileNotFound as exc:
635
+ self._file_not_found(
636
+ status="file_not_found", exc=exc, step_name=step_name
637
+ )
638
+ except (NoDataFound, DataNotFound) as exc:
639
+ self._not_found(status="not_found", exc=exc, step_name=step_name)
640
+ except (ProviderError, ComponentError, NotSupported, FileError) as exc:
641
+ self._on_error(status="error", exc=exc, step_name=step_name)
642
+ except Exception as err:
643
+ self._on_exception(step_name, err)
644
+ try:
645
+ run = getattr(comp, "run", None)
646
+ if asyncio.iscoroutinefunction(run):
647
+ result = await comp.run()
648
+ elif callable(run):
649
+ result = comp.run()
650
+ else:
651
+ raise TaskFailed(
652
+ f"DI: Component {step_name} is not callable"
653
+ )
654
+ # close operations
655
+ close = getattr(comp, "close", None)
656
+ if asyncio.iscoroutinefunction(close):
657
+ await comp.close()
658
+ else:
659
+ comp.close()
660
+ if check_empty(result):
661
+ if comp.skipError == SkipErrors.SKIP:
662
+ print(f"::: SKIPPING Error on {step_name} :::: ")
663
+ failed.append(comp)
664
+ _exit = False
665
+ continue
666
+ failed.append(comp)
667
+ _exit = True
668
+ break
669
+ except EmptyFile as exc:
670
+ # its a data component a no data was found
671
+ if comp.skipError == SkipErrors.SKIP:
672
+ failed.append(comp)
673
+ self.logger.warning(
674
+ f"SKIP Failed Component: {comp!r} with error: {exc}"
675
+ )
676
+ # can skip error for this component
677
+ continue
678
+ self._file_empty(
679
+ status="empty_file",
680
+ exc=exc,
681
+ step_name=step_name
682
+ )
683
+ except (NoDataFound, DataNotFound) as err:
684
+ # its a data component a no data was found
685
+ if comp.skipError == SkipErrors.SKIP:
686
+ failed.append(comp)
687
+ self.logger.warning(
688
+ f"SKIP Failed Component: {comp!r} with error: {err}"
689
+ )
690
+ # can skip error for this component
691
+ continue
692
+ self._not_found(
693
+ status="not_found",
694
+ exc=err,
695
+ step_name=step_name
696
+ )
697
+ except FileNotFound as err:
698
+ if comp.skipError == SkipErrors.SKIP:
699
+ failed.append(comp)
700
+ self.logger.warning(
701
+ f"SKIP Failed Component: {comp!r} with error: {err}"
702
+ )
703
+ # can skip error for this component
704
+ continue
705
+ self._file_not_found(status="not_found", exc=err, step_name=step_name)
706
+ except (FileError, DataError) as err:
707
+ if comp.skipError == SkipErrors.SKIP:
708
+ failed.append(comp)
709
+ self.logger.warning(
710
+ f"SKIP Failed Component: {comp!r} with error: {err}"
711
+ )
712
+ comp = prev
713
+ # can skip error for this component
714
+ continue
715
+ self._data_error(status="data_error", exc=err, step_name=step_name)
716
+ except (ProviderError, ComponentError, NotSupported) as err:
717
+ if comp.skipError == SkipErrors.SKIP:
718
+ # can skip error for this component
719
+ failed.append(comp)
720
+ self.logger.warning(
721
+ f"SKIP Failed Component: {comp!r} with error: {err}"
722
+ )
723
+ empty = check_empty(comp.output())
724
+ if empty:
725
+ # avoid when failed, lost the chain of results:
726
+ others = comp.previous
727
+ if isinstance(others, list):
728
+ previous = others[0]
729
+ comp.result = previous.output()
730
+ else:
731
+ try:
732
+ comp.result = others.output()
733
+ except AttributeError:
734
+ self.logger.warning(
735
+ "There is no Previous Component Output"
736
+ )
737
+ comp.result = None
738
+ _exit = False
739
+ continue
740
+ else:
741
+ self._on_error(status="error", exc=err, step_name=step_name)
742
+ except Exception as err:
743
+ self._on_exception(step_name, err)
744
+ # passing variables between components
745
+ await self.exchange_variables(comp, result=result)
746
+ try:
747
+ # stop stats:
748
+ if self.enable_stat is True:
749
+ self._final_stats = await self.stat.stop()
750
+ except Exception as err:
751
+ self.logger.error(str(err))
752
+ # Empty Pile
753
+ self._pile_ = []
754
+ if _exit is True:
755
+ # TODO: checking the failed list for returning errors.
756
+ self.logger.error(f"Task Steps Failed: {failed!r}")
757
+ self._state = TaskState.DONE_WITH_WARNINGS
758
+ self._not_found(status="done_warning", exc=f"Not Found on: {failed!r}")
759
+ return False
760
+ else:
761
+ if check_empty(result):
762
+ if self.is_subtask is False:
763
+ self._state = TaskState.DONE_WITH_NODATA
764
+ # mark data not found, is a warning
765
+ self._not_found(status="not_found", exc=None)
766
+ else:
767
+ self._state = TaskState.DONE_WITH_NODATA
768
+ else:
769
+ if self.is_subtask is False:
770
+ # avoid firing OnDone when is a subtask
771
+ self._on_done(result)
772
+ if self._ignore_results is True:
773
+ return True
774
+ else:
775
+ return result
776
+
777
+ def plot(self, filename: str = None) -> None:
778
+ self.pile().plot_task(filename=filename)