flowtask 5.8.4__cp310-cp310-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-310-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-310-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-310-x86_64-linux-gnu.so +0 -0
  377. flowtask/parsers/json.c +11968 -0
  378. flowtask/parsers/json.cpython-310-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-310-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-310-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-310-x86_64-linux-gnu.so +0 -0
  440. flowtask/utils/json.cpp +13349 -0
  441. flowtask/utils/json.cpython-310-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-310-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,314 @@
1
+ import math
2
+ from urllib.parse import urljoin
3
+ import numpy as np
4
+ import orjson
5
+ import pandas as pd
6
+ from .flow import FlowComponent
7
+ from ..interfaces.http import HTTPService
8
+ from ..exceptions import ComponentError, DataNotFound
9
+ from ..utils.transformations import to_snake_case
10
+
11
+
12
+ class AutoTask(HTTPService, FlowComponent):
13
+ """
14
+ AutoTask Component
15
+
16
+ Overview
17
+
18
+ This component retrieves data from AutoTask using the Autotask REST API.
19
+ It supports filtering data based on a query or specific IDs, handles pagination, and converts picklist values to human-readable labels.
20
+
21
+ .. table:: Properties
22
+ :widths: auto
23
+
24
+ +---------------------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------+
25
+ | Name | Required | Summary |
26
+ +---------------------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------+
27
+ | credentials | Yes | Dictionary containing API credentials: "API_INTEGRATION_CODE", "USERNAME", and "SECRET". Credentials can be retrieved from environment variables. |
28
+ +---------------------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------+
29
+ | zone | Yes | AutoTask zone (e.g., "na"). |
30
+ +---------------------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------+
31
+ | entity | Yes | AutoTask entity to query (e.g., "tickets"). |
32
+ +---------------------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------+
33
+ | query_json | No | JSON object representing the AutoTask query filter (defaults to retrieving all items). Refer to AutoTask documentation for query syntax. |
34
+ +---------------------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------+
35
+ | id_column_name | No | Name of the column in the output DataFrame that should represent the AutoTask record ID (defaults to "id"). |
36
+ +---------------------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------+
37
+ | ids | No | List of AutoTask record IDs to retrieve (overrides query_json filter if provided). |
38
+ +---------------------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------+
39
+ | picklist_fields | No | List of picklist fields in the entity to be converted to human-readable labels. |
40
+ +---------------------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------+
41
+ | user_defined_fields | No | List of user-defined fields in the entity to extract (requires "userDefinedFields" field in the response). |
42
+ +---------------------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------+
43
+ | fillna_values | No | Default value to replace missing data (defaults to None). |
44
+ +---------------------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------+
45
+ | map_field_type | No | Dictionary mapping field names to desired data types in the output DataFrame. |
46
+ +---------------------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------+
47
+ | force_create_columns | No | If True, ensures "IncludeFields" columns always exist, even if empty. Must be used with "IncludeFields" in "query_json". |
48
+ +---------------------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------+
49
+
50
+ Returns a pandas DataFrame containing the retrieved AutoTask data and additional columns for picklist labels (if applicable).
51
+
52
+
53
+
54
+ Example:
55
+
56
+ ```yaml
57
+ AutoTask:
58
+ skipError: skip
59
+ credentials:
60
+ API_INTEGRATION_CODE: AUTOTASK_API_INTEGRATION_CODE
61
+ USERNAME: AUTOTASK_USERNAME
62
+ SECRET: AUTOTASK_SECRET
63
+ entity: TicketNotes
64
+ zone: webservices14
65
+ id_column_name: ticket_note_id
66
+ picklist_fields:
67
+ - noteType
68
+ - publish
69
+ ids: []
70
+ query_json:
71
+ IncludeFields:
72
+ - id
73
+ - createDateTime
74
+ - createdByContactID
75
+ - creatorResourceID
76
+ - description
77
+ - impersonatorCreatorResourceID
78
+ - impersonatorUpdaterResourceID
79
+ - lastActivityDate
80
+ - noteType
81
+ - publish
82
+ - ticketID
83
+ - title
84
+ Filter:
85
+ - op: gte
86
+ field: lastActivityDate
87
+ value: '{two_days_ago}'
88
+ masks:
89
+ '{two_days_ago}':
90
+ - date_diff
91
+ - value: current_date
92
+ diff: 48
93
+ mode: hours
94
+ mask: '%Y-%m-%d %H:%M:%S'
95
+ ```
96
+
97
+ """ # noqa
98
+ _credentials: dict = {"API_INTEGRATION_CODE": str, "USERNAME": str, "SECRET": str}
99
+ force_create_columns: bool = False
100
+
101
+ async def start(self, **kwargs):
102
+ self.headers = None
103
+ self._proxies = None
104
+ self.auth = ""
105
+ self.auth_type = ""
106
+ self.timeout = 180
107
+ self.accept = "application/json"
108
+ self.query_json = self.mask_replacement_recursively(self.query_json)
109
+ self.processing_credentials()
110
+
111
+ self._base_url = (
112
+ f"https://{self.zone}.autotask.net/atservicesrest/v1.0/{self.entity}/"
113
+ )
114
+
115
+ self.headers = {
116
+ "Content-Type": "application/json",
117
+ "ApiIntegrationCode": self.credentials["API_INTEGRATION_CODE"],
118
+ "UserName": self.credentials["USERNAME"],
119
+ "Secret": self.credentials["SECRET"],
120
+ }
121
+
122
+ self.ids_chunks = []
123
+ if self.previous:
124
+ self.data = self.input
125
+
126
+ self.ids_chunks = self.filter_ids(
127
+ id_field=self.id_column_name,
128
+ items=self.data,
129
+ chunk_size=500,
130
+ )
131
+ elif getattr(self, "ids", None):
132
+ self._logger.info("Dropping specified Filters. Using ids instead.")
133
+ self.ids_chunks = [self.ids]
134
+
135
+ return True
136
+
137
+ async def run(self):
138
+ if not self.ids_chunks:
139
+ # Use the Filter specified in the task
140
+ df_items = await self.get_dataframe_from_entity(
141
+ payload=orjson.dumps(self.query_json),
142
+ id_column_name=self.id_column_name,
143
+ )
144
+ else:
145
+ # Use the ids from the previous component or from the ids argument
146
+ df_items = pd.DataFrame()
147
+ for ids_chunk in self.ids_chunks:
148
+ self.query_json.update(
149
+ {
150
+ "Filter": [
151
+ {"op": "in", "field": "id", "value": ids_chunk.tolist()}
152
+ ]
153
+ }
154
+ )
155
+
156
+ items = await self.get_dataframe_from_entity(
157
+ payload=orjson.dumps(self.query_json),
158
+ id_column_name=self.id_column_name,
159
+ )
160
+
161
+ df_items = pd.concat([df_items, items], ignore_index=True)
162
+
163
+ if not df_items.empty and self.picklist_fields:
164
+ df_picklist_values = await self.get_picklist_values(self.picklist_fields)
165
+
166
+ if not getattr(df_picklist_values, "empty", True):
167
+
168
+ for column in [to_snake_case(field) for field in self.picklist_fields]:
169
+ df_filtered = df_picklist_values[df_picklist_values['field'] == column]
170
+
171
+ # Merge the label into df_items
172
+ df_items = df_items.merge(
173
+ df_filtered[['label', 'value']],
174
+ how='left',
175
+ left_on=column,
176
+ right_on='value'
177
+ )
178
+
179
+ # Rename the label column to reflect the original field
180
+ df_items.rename(columns={'label': f'{column}_label'}, inplace=True)
181
+
182
+ # Drop the 'value' column from the merge
183
+ df_items.drop(columns=['value'], inplace=True)
184
+
185
+ if "IncludeFields" in self.query_json and self.force_create_columns:
186
+ required_columns = self._get_force_create_columns()
187
+
188
+ if df_items.empty:
189
+ # Create a DataFrame with one row filled with NaNs based on IncludeFields
190
+ empty_dataset = {field: [pd.NA] for field in required_columns}
191
+ df_items = pd.DataFrame(empty_dataset)
192
+ else:
193
+ df_items = df_items.reindex(columns=required_columns, fill_value=pd.NA)
194
+
195
+ self._result = df_items
196
+ # Add Debugging Block
197
+ if self._debug is True:
198
+ print("::: Printing Result Data === ")
199
+ print("Data: ", self._result)
200
+ for column, t in df_items.dtypes.items():
201
+ print(column, "->", t, "->", df_items[column].iloc[0])
202
+ return self._result
203
+
204
+ async def close(self):
205
+ pass
206
+
207
+ def _get_force_create_columns(self):
208
+ required_columns = list(map(to_snake_case, self.query_json["IncludeFields"]))
209
+
210
+ try:
211
+ idx = required_columns.index("id")
212
+ required_columns[idx] = self.id_column_name
213
+
214
+ return required_columns
215
+
216
+ except ValueError:
217
+ self.logger.error("The item 'id' was not found in the list.")
218
+
219
+ def filter_ids(self, id_field: str, items: pd.DataFrame, chunk_size):
220
+ data = items[id_field].dropna().unique().astype(int)
221
+
222
+ if data.size > 0:
223
+ split_n = math.ceil(data.size / chunk_size)
224
+
225
+ # Split into chunks of n items
226
+ return np.array_split(data, split_n) # Convert to NumPy array and split
227
+
228
+ return [data]
229
+
230
+ def get_autotask_url(self, resource):
231
+ return urljoin(self._base_url, resource)
232
+
233
+ async def get_dataframe_from_entity(self, payload, id_column_name):
234
+ args = {
235
+ "url": self.get_autotask_url("query"),
236
+ "method": "post",
237
+ "data": payload,
238
+ }
239
+
240
+ results = []
241
+ while True:
242
+ result, error = await self.session(**args)
243
+
244
+ if error:
245
+ self._logger.error(f"{__name__}: Error getting {self.entity}")
246
+ raise ComponentError(f"{__name__}: Error getting {self.entity}") from error
247
+
248
+ if result is None:
249
+ self._logger.error(f"API returned None or empty result for {args['url']}")
250
+ raise ComponentError(f"API returned None or empty result for {args['url']}")
251
+
252
+ if "items" not in result:
253
+ self._logger.error(f"'items' not found in API response: {result}")
254
+ raise ComponentError("'items' not found in API response")
255
+
256
+ results.extend(result.get("items", []))
257
+
258
+ args.update({"url": result["pageDetails"].get("nextPageUrl", None)})
259
+
260
+ if not args["url"]:
261
+ break
262
+ try:
263
+ df_results = await self.create_dataframe(results)
264
+ except DataNotFound as e:
265
+ if self.force_create_columns:
266
+ return pd.DataFrame()
267
+
268
+ raise e
269
+
270
+ if not df_results.empty and "userDefinedFields" in df_results.columns:
271
+ df_results_udf = df_results["userDefinedFields"].apply(self.extract_udf)
272
+ df_results = df_results.drop("userDefinedFields", axis=1, errors="ignore").join(df_results_udf)
273
+
274
+ df_results = (
275
+ df_results.rename(columns=lambda x: to_snake_case(x))
276
+ .rename(columns={"id": id_column_name})
277
+ )
278
+
279
+ return df_results
280
+
281
+ @staticmethod
282
+ def extract_udf(row):
283
+ """ Extracts dictionary values into columns"""
284
+ return pd.Series({d['name']: d['value'] for d in row})
285
+
286
+ async def get_picklist_values(self, field_names: list[str]) -> pd.DataFrame:
287
+ result, error = await self.session(
288
+ url=self.get_autotask_url("entityInformation/fields"),
289
+ method="get",
290
+ )
291
+
292
+ if error:
293
+ self._logger.error(f"{__name__}: Error getting {self.entity}")
294
+ raise ComponentError(f"{__name__}: Error getting {self.entity}") from error
295
+
296
+ picklist_data = []
297
+
298
+ for field_name in field_names:
299
+ for field in result["fields"]:
300
+ if field["name"] == field_name:
301
+ self._logger.info(f"Extracting picking list values for {field_name}")
302
+
303
+ if not field["picklistValues"]:
304
+ df = pd.DataFrame(columns=["label", "value"])
305
+ else:
306
+ df = await self.create_dataframe(field["picklistValues"])
307
+ df = df[["label", "value"]]
308
+
309
+ df["field"] = to_snake_case(field_name)
310
+ picklist_data.append(df)
311
+
312
+ # Concatenate all DataFrames and reset the index
313
+ combined_df = pd.concat(picklist_data).reset_index(drop=True).astype({"value": "int"})
314
+ return combined_df[["field", "label", "value"]]
@@ -0,0 +1,80 @@
1
+ import asyncio
2
+ from collections.abc import Callable
3
+ from ..interfaces.AzureClient import AzureClient
4
+ from ..interfaces.http import HTTPService
5
+ from .flow import FlowComponent
6
+
7
+
8
+ class Azure(AzureClient, HTTPService, FlowComponent):
9
+ """
10
+ Azure Component.
11
+
12
+ Overview
13
+
14
+ This component interacts with Azure services using the Azure SDK for Python.
15
+ It requires valid Azure credentials to establish a connection.
16
+
17
+ .. table:: Properties
18
+ :widths: auto
19
+
20
+ +--------------------------+----------+-----------+----------------------------------------------------------------+
21
+ | Name | Required | Summary |
22
+ +--------------------------+----------+-----------+----------------------------------------------------------------+
23
+ | credentials (optional) | Yes | Dictionary containing Azure credentials: "client_id", "tenant_id", |
24
+ | | | and "client_secret". Credentials can be retrieved from environment |
25
+ | | | variables. |
26
+ +--------------------------+----------+-----------+----------------------------------------------------------------+
27
+ | as_dataframe (optional) | No | Specifies if the response should be converted to a pandas DataFrame |
28
+ | | | (default: False). |
29
+ +--------------------------+----------+-----------+----------------------------------------------------------------+
30
+
31
+ This component does not return any data directly. It interacts with
32
+ Azure services based on the configuration and potentially triggers
33
+ downstream components in a task.
34
+ """ # noqa: E501
35
+ accept: str = "application/json"
36
+ no_host: bool = True
37
+
38
+ def __init__(
39
+ self,
40
+ loop: asyncio.AbstractEventLoop = None,
41
+ job: Callable = None,
42
+ stat: Callable = None,
43
+ **kwargs,
44
+ ):
45
+ self.as_dataframe: bool = kwargs.get("as_dataframe", False)
46
+ # Initialize parent classes explicitly
47
+ super().__init__(loop=loop, job=job, stat=stat, **kwargs)
48
+ if 'secret_id' in self.credentials:
49
+ self.credentials['client_secret'] = self.credentials.pop('secret_id')
50
+
51
+ async def close(self, timeout: int = 5):
52
+ """close.
53
+ Closing the connection.
54
+ """
55
+ pass
56
+
57
+ async def open(self, host: str, port: int, credentials: dict, **kwargs):
58
+ """open.
59
+ Starts (open) a connection to external resource.
60
+ """
61
+ self.app = self.get_msal_app()
62
+ return self
63
+
64
+ async def start(self, **kwargs):
65
+ """Start.
66
+
67
+ Processing variables and credentials.
68
+ """
69
+ await super(Azure, self).start(**kwargs)
70
+ self.processing_credentials()
71
+ try:
72
+ self.client_id, self.tenant_id, self.client_secret = (
73
+ self.credentials.get(key)
74
+ for key in ["client_id", "tenant_id", "client_secret"]
75
+ )
76
+ except Exception as err:
77
+ self._logger.error(err)
78
+ raise
79
+
80
+ return True
@@ -0,0 +1,106 @@
1
+ import iso8601
2
+ from datetime import datetime, time, timezone
3
+ from .Azure import Azure
4
+ from ..exceptions import ComponentError, DataNotFound
5
+
6
+ class AzureUsers(Azure):
7
+ """
8
+
9
+ AzureUsers Component
10
+
11
+ Overview
12
+
13
+ This component retrieves a list of users from Azure Active Directory (AAD) using the Microsoft Graph API.
14
+
15
+ .. table:: Properties
16
+ :widths: auto
17
+
18
+ +------------------------+----------+-----------+---------------------------------------------------------------------------------+
19
+ | Name | Required | Summary |
20
+ +------------------------+----------+-----------+---------------------------------------------------------------------------------+
21
+ | credentials | Yes | Dictionary placeholder for Azure AD application credentials. |
22
+ +------------------------+----------+-----------+---------------------------------------------------------------------------------+
23
+ | most_recent (optional) | No | ISO 8601-formatted date and time string to filter users created on or after that date/time. | |
24
+ +------------------------+----------+-----------+---------------------------------------------------------------------------------+
25
+
26
+ **Returns**
27
+
28
+ A pandas DataFrame containing the retrieved user information. Each row represents an Azure user, and columns might include properties like:
29
+
30
+ - `objectId`: Unique identifier for the user in AAD.
31
+ - `displayName`: User's display name.
32
+ - `userPrincipalName`: User's email address (usually the primary login).
33
+ - ... (other user properties depending on the AAD response)
34
+
35
+ **Error Handling**
36
+
37
+ - The component raises a `ComponentError` with a detailed message in case of errors during authentication, API calls, or data processing. This error will be surfaced within your Flowtask workflow.
38
+
39
+
40
+ Example:
41
+
42
+ ```yaml
43
+ AzureUsers:
44
+ recent: '2023-10-01'
45
+ ```
46
+
47
+ """ # noqa: E501
48
+ accept: str = 'application/json'
49
+
50
+ async def get_users(self, most_recent: str = None):
51
+ async def fetch_users(url: str, all_users: list):
52
+ result, error = await self.async_request(url, self.method)
53
+ if error:
54
+ raise ComponentError(
55
+ f"{__name__}: Error in AzureUsers: {error}"
56
+ )
57
+
58
+ all_users.extend(result.get("value", []))
59
+
60
+ next_link = result.get("@odata.nextLink")
61
+ if next_link:
62
+ await fetch_users(next_link, all_users)
63
+
64
+ all_users = []
65
+ if most_recent:
66
+ utc_datetime = (
67
+ iso8601.parse_date(most_recent).isoformat().replace("+00:00", "Z")
68
+ )
69
+ url = f"{self.users_info}?$filter=createdDateTime ge {utc_datetime}"
70
+ else:
71
+ url = f"{self.users_info}"
72
+ await fetch_users(url, all_users)
73
+ return all_users
74
+
75
+ async def run(self):
76
+ """Run Azure Connection for getting Users Info."""
77
+ self._logger.info(
78
+ f"<{__name__}>: Starting Azure Connection for getting Users Info."
79
+ )
80
+ self.app = self.get_msal_app()
81
+ token, self.token_type = self.get_token()
82
+ self.auth["apikey"] = token
83
+ self.headers["Content-Type"] = "application/json"
84
+ self.method = "GET"
85
+ try:
86
+ more_recent = None
87
+ if hasattr(self, "recent"):
88
+ more_recent = self.mask_replacement(self.recent)
89
+ result = await self.get_users(more_recent)
90
+ self._logger.info(f"<{__name__}>: Successfully got Users Info.")
91
+ self._result = await self.create_dataframe(result)
92
+ if self._result is None:
93
+ raise DataNotFound(
94
+ "No data found for Azure Users."
95
+ )
96
+ except Exception as err:
97
+ self._logger.error(err)
98
+ raise ComponentError(f"{__name__}: Error in AzureUsers: {err}") from err
99
+ numrows = len(self._result.index)
100
+ self.add_metric("NUM_USERS", numrows)
101
+ if self._debug is True:
102
+ print(self._result)
103
+ print("::: Printing Column Information === ")
104
+ for column, t in self._result.dtypes.items():
105
+ print(column, "->", t, "->", self._result[column].iloc[0])
106
+ return self._result
@@ -0,0 +1,91 @@
1
+ import asyncio
2
+ from abc import ABC
3
+ from typing import List, Dict, Union
4
+ from collections.abc import Callable
5
+ from ..exceptions import DataNotFound, ComponentError
6
+ from .flow import FlowComponent
7
+
8
+
9
+ class BaseAction(FlowComponent, ABC):
10
+ """
11
+ BaseAction Component
12
+
13
+ Overview
14
+ Basic component for making RESTful queries to URLs.
15
+ This component serves as a foundation for building more specific action components.
16
+ It allows you to define methods (functions) that can be executed asynchronously.
17
+
18
+ .. table:: Properties
19
+ :widths: auto
20
+
21
+ +-----------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------+
22
+ | Name | Required | Summary |
23
+ +-----------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------+
24
+ | loop (optional) | No | Event loop to use for asynchronous operations (defaults to the current event loop). |
25
+ +-----------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------+
26
+ | job (optional) | No | Reference to a job object for logging and tracking purposes. |
27
+ +-----------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------+
28
+ | stat (optional) | No | Reference to a stat object for custom metrics collection. |
29
+ +-----------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------+
30
+ | method (from kwargs) | Yes | Name of the method (function) within the component to be executed. Specified as a keyword argument during initialization. |
31
+ +-----------------------+----------+-----------+---------------------------------------------------------------------------------------------------------------+
32
+
33
+ **Returns**
34
+
35
+ The output data can vary depending on the implemented method. It can be a list, dictionary, or any data structure returned by the executed method.
36
+
37
+ **Error Handling**
38
+
39
+ - `DataNotFound`: This exception is raised if the executed method doesn't return any data.
40
+ - `ComponentError`: This exception is raised for any other errors encountered during execution.
41
+
42
+
43
+ """
44
+
45
+ def __init__(
46
+ self,
47
+ loop: asyncio.AbstractEventLoop = None,
48
+ job: Callable = None,
49
+ stat: Callable = None,
50
+ **kwargs,
51
+ ) -> None:
52
+ """Init Method."""
53
+ self._result: Union[List, Dict] = None
54
+ self._method: str = kwargs.pop("method", None)
55
+ super().__init__(loop=loop, job=job, stat=stat, **kwargs)
56
+ args = self._attrs.get("args", {})
57
+ keys_to_remove = ["loop", "stat", "debug", "memory", "comment", "Group"]
58
+ self._kwargs = {k: v for k, v in args.items() if k not in keys_to_remove}
59
+
60
+ async def start(self, **kwargs):
61
+ if not hasattr(self, self._method):
62
+ raise ComponentError(f"{self.__name__} Error: has no Method {self._method}")
63
+ # Getting the method to be called
64
+ self._fn = getattr(self, self._method)
65
+ await super(BaseAction, self).start(**kwargs)
66
+ # Processing Variables:
67
+ self._kwargs = self.var_replacement(self._kwargs)
68
+ return True
69
+
70
+ async def close(self):
71
+ pass
72
+
73
+ async def run(self):
74
+ try:
75
+ result, error = await self._fn(**self._kwargs)
76
+ if error:
77
+ self._logger.warning(
78
+ f"Error {self.__name__}.{self._fn.__name__}: {error}"
79
+ )
80
+ return False
81
+ if result is None:
82
+ raise DataNotFound(
83
+ f"No data found for {self.__name__}.{self._fn.__name__}"
84
+ )
85
+ self._result = result
86
+ self.add_metric(f"{self.__name__}.{self._fn.__name__}", result)
87
+ except DataNotFound:
88
+ raise
89
+ except Exception as e:
90
+ raise ComponentError(f"Error running {self.__name__}: {e}")
91
+ return self._result