flowtask 5.8.4__cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (470) hide show
  1. flowtask/__init__.py +93 -0
  2. flowtask/__main__.py +38 -0
  3. flowtask/bots/__init__.py +6 -0
  4. flowtask/bots/check.py +93 -0
  5. flowtask/bots/codebot.py +51 -0
  6. flowtask/components/ASPX.py +148 -0
  7. flowtask/components/AddDataset.py +352 -0
  8. flowtask/components/Amazon.py +523 -0
  9. flowtask/components/AutoTask.py +314 -0
  10. flowtask/components/Azure.py +80 -0
  11. flowtask/components/AzureUsers.py +106 -0
  12. flowtask/components/BaseAction.py +91 -0
  13. flowtask/components/BaseLoop.py +198 -0
  14. flowtask/components/BestBuy.py +800 -0
  15. flowtask/components/CSVToGCS.py +120 -0
  16. flowtask/components/CompanyScraper/__init__.py +1 -0
  17. flowtask/components/CompanyScraper/parsers/__init__.py +6 -0
  18. flowtask/components/CompanyScraper/parsers/base.py +102 -0
  19. flowtask/components/CompanyScraper/parsers/explorium.py +192 -0
  20. flowtask/components/CompanyScraper/parsers/leadiq.py +206 -0
  21. flowtask/components/CompanyScraper/parsers/rocket.py +133 -0
  22. flowtask/components/CompanyScraper/parsers/siccode.py +109 -0
  23. flowtask/components/CompanyScraper/parsers/visualvisitor.py +130 -0
  24. flowtask/components/CompanyScraper/parsers/zoominfo.py +118 -0
  25. flowtask/components/CompanyScraper/scrapper.py +1054 -0
  26. flowtask/components/CopyTo.py +177 -0
  27. flowtask/components/CopyToBigQuery.py +243 -0
  28. flowtask/components/CopyToMongoDB.py +291 -0
  29. flowtask/components/CopyToPg.py +609 -0
  30. flowtask/components/CopyToRethink.py +207 -0
  31. flowtask/components/CreateGCSBucket.py +102 -0
  32. flowtask/components/CreateReport/CreateReport.py +228 -0
  33. flowtask/components/CreateReport/__init__.py +9 -0
  34. flowtask/components/CreateReport/charts/__init__.py +15 -0
  35. flowtask/components/CreateReport/charts/bar.py +51 -0
  36. flowtask/components/CreateReport/charts/base.py +66 -0
  37. flowtask/components/CreateReport/charts/pie.py +64 -0
  38. flowtask/components/CreateReport/utils.py +9 -0
  39. flowtask/components/CustomerSatisfaction.py +196 -0
  40. flowtask/components/DataInput.py +200 -0
  41. flowtask/components/DateList.py +255 -0
  42. flowtask/components/DbClient.py +163 -0
  43. flowtask/components/DialPad.py +146 -0
  44. flowtask/components/DocumentDBQuery.py +200 -0
  45. flowtask/components/DownloadFrom.py +371 -0
  46. flowtask/components/DownloadFromD2L.py +113 -0
  47. flowtask/components/DownloadFromFTP.py +181 -0
  48. flowtask/components/DownloadFromIMAP.py +315 -0
  49. flowtask/components/DownloadFromS3.py +198 -0
  50. flowtask/components/DownloadFromSFTP.py +265 -0
  51. flowtask/components/DownloadFromSharepoint.py +110 -0
  52. flowtask/components/DownloadFromSmartSheet.py +114 -0
  53. flowtask/components/DownloadS3File.py +229 -0
  54. flowtask/components/Dummy.py +59 -0
  55. flowtask/components/DuplicatePhoto.py +411 -0
  56. flowtask/components/EmployeeEvaluation.py +237 -0
  57. flowtask/components/ExecuteSQL.py +323 -0
  58. flowtask/components/ExtractHTML.py +178 -0
  59. flowtask/components/FileBase.py +178 -0
  60. flowtask/components/FileCopy.py +181 -0
  61. flowtask/components/FileDelete.py +82 -0
  62. flowtask/components/FileExists.py +146 -0
  63. flowtask/components/FileIteratorDelete.py +112 -0
  64. flowtask/components/FileList.py +194 -0
  65. flowtask/components/FileOpen.py +75 -0
  66. flowtask/components/FileRead.py +120 -0
  67. flowtask/components/FileRename.py +106 -0
  68. flowtask/components/FilterIf.py +284 -0
  69. flowtask/components/FilterRows/FilterRows.py +200 -0
  70. flowtask/components/FilterRows/__init__.py +10 -0
  71. flowtask/components/FilterRows/functions.py +4 -0
  72. flowtask/components/GCSToBigQuery.py +103 -0
  73. flowtask/components/GoogleA4.py +150 -0
  74. flowtask/components/GoogleGeoCoding.py +344 -0
  75. flowtask/components/GooglePlaces.py +315 -0
  76. flowtask/components/GoogleSearch.py +539 -0
  77. flowtask/components/HTTPClient.py +268 -0
  78. flowtask/components/ICIMS.py +146 -0
  79. flowtask/components/IF.py +179 -0
  80. flowtask/components/IcimsFolderCopy.py +173 -0
  81. flowtask/components/ImageFeatures/__init__.py +5 -0
  82. flowtask/components/ImageFeatures/process.py +233 -0
  83. flowtask/components/IteratorBase.py +251 -0
  84. flowtask/components/LangchainLoader/__init__.py +5 -0
  85. flowtask/components/LangchainLoader/loader.py +194 -0
  86. flowtask/components/LangchainLoader/loaders/__init__.py +22 -0
  87. flowtask/components/LangchainLoader/loaders/abstract.py +362 -0
  88. flowtask/components/LangchainLoader/loaders/basepdf.py +50 -0
  89. flowtask/components/LangchainLoader/loaders/docx.py +91 -0
  90. flowtask/components/LangchainLoader/loaders/html.py +119 -0
  91. flowtask/components/LangchainLoader/loaders/pdfblocks.py +146 -0
  92. flowtask/components/LangchainLoader/loaders/pdfmark.py +79 -0
  93. flowtask/components/LangchainLoader/loaders/pdftables.py +135 -0
  94. flowtask/components/LangchainLoader/loaders/qa.py +67 -0
  95. flowtask/components/LangchainLoader/loaders/txt.py +55 -0
  96. flowtask/components/LeadIQ.py +650 -0
  97. flowtask/components/Loop.py +253 -0
  98. flowtask/components/Lowes.py +334 -0
  99. flowtask/components/MS365Usage.py +156 -0
  100. flowtask/components/MSTeamsMessages.py +320 -0
  101. flowtask/components/MarketClustering.py +1051 -0
  102. flowtask/components/MergeFiles.py +362 -0
  103. flowtask/components/MilvusOutput.py +87 -0
  104. flowtask/components/NearByStores.py +175 -0
  105. flowtask/components/NetworkNinja/__init__.py +6 -0
  106. flowtask/components/NetworkNinja/models/__init__.py +52 -0
  107. flowtask/components/NetworkNinja/models/abstract.py +177 -0
  108. flowtask/components/NetworkNinja/models/account.py +39 -0
  109. flowtask/components/NetworkNinja/models/client.py +19 -0
  110. flowtask/components/NetworkNinja/models/district.py +14 -0
  111. flowtask/components/NetworkNinja/models/events.py +101 -0
  112. flowtask/components/NetworkNinja/models/forms.py +499 -0
  113. flowtask/components/NetworkNinja/models/market.py +16 -0
  114. flowtask/components/NetworkNinja/models/organization.py +34 -0
  115. flowtask/components/NetworkNinja/models/photos.py +125 -0
  116. flowtask/components/NetworkNinja/models/project.py +44 -0
  117. flowtask/components/NetworkNinja/models/region.py +28 -0
  118. flowtask/components/NetworkNinja/models/store.py +203 -0
  119. flowtask/components/NetworkNinja/models/user.py +151 -0
  120. flowtask/components/NetworkNinja/router.py +854 -0
  121. flowtask/components/Odoo.py +175 -0
  122. flowtask/components/OdooInjector.py +192 -0
  123. flowtask/components/OpenFromXML.py +126 -0
  124. flowtask/components/OpenWeather.py +41 -0
  125. flowtask/components/OpenWithBase.py +616 -0
  126. flowtask/components/OpenWithPandas.py +715 -0
  127. flowtask/components/PGPDecrypt.py +199 -0
  128. flowtask/components/PandasIterator.py +187 -0
  129. flowtask/components/PandasToFile.py +189 -0
  130. flowtask/components/Paradox.py +339 -0
  131. flowtask/components/ParamIterator.py +117 -0
  132. flowtask/components/ParseHTML.py +84 -0
  133. flowtask/components/PlacerStores.py +249 -0
  134. flowtask/components/Pokemon.py +507 -0
  135. flowtask/components/PositiveBot.py +62 -0
  136. flowtask/components/PowerPointSlide.py +400 -0
  137. flowtask/components/PrintMessage.py +127 -0
  138. flowtask/components/ProductCompetitors/__init__.py +5 -0
  139. flowtask/components/ProductCompetitors/parsers/__init__.py +7 -0
  140. flowtask/components/ProductCompetitors/parsers/base.py +72 -0
  141. flowtask/components/ProductCompetitors/parsers/bestbuy.py +86 -0
  142. flowtask/components/ProductCompetitors/parsers/lowes.py +103 -0
  143. flowtask/components/ProductCompetitors/scrapper.py +155 -0
  144. flowtask/components/ProductCompliant.py +169 -0
  145. flowtask/components/ProductInfo/__init__.py +1 -0
  146. flowtask/components/ProductInfo/parsers/__init__.py +5 -0
  147. flowtask/components/ProductInfo/parsers/base.py +83 -0
  148. flowtask/components/ProductInfo/parsers/brother.py +97 -0
  149. flowtask/components/ProductInfo/parsers/canon.py +167 -0
  150. flowtask/components/ProductInfo/parsers/epson.py +118 -0
  151. flowtask/components/ProductInfo/parsers/hp.py +131 -0
  152. flowtask/components/ProductInfo/parsers/samsung.py +97 -0
  153. flowtask/components/ProductInfo/scraper.py +319 -0
  154. flowtask/components/ProductPricing.py +118 -0
  155. flowtask/components/QS.py +261 -0
  156. flowtask/components/QSBase.py +201 -0
  157. flowtask/components/QueryIterator.py +273 -0
  158. flowtask/components/QueryToInsert.py +327 -0
  159. flowtask/components/QueryToPandas.py +432 -0
  160. flowtask/components/RESTClient.py +195 -0
  161. flowtask/components/RethinkDBQuery.py +189 -0
  162. flowtask/components/Rsync.py +74 -0
  163. flowtask/components/RunSSH.py +59 -0
  164. flowtask/components/RunShell.py +71 -0
  165. flowtask/components/SalesForce.py +20 -0
  166. flowtask/components/SaveImageBank/__init__.py +257 -0
  167. flowtask/components/SchedulingVisits.py +592 -0
  168. flowtask/components/ScrapPage.py +216 -0
  169. flowtask/components/ScrapSearch.py +79 -0
  170. flowtask/components/SendNotify.py +257 -0
  171. flowtask/components/SentimentAnalysis.py +694 -0
  172. flowtask/components/ServiceScrapper/__init__.py +5 -0
  173. flowtask/components/ServiceScrapper/parsers/__init__.py +1 -0
  174. flowtask/components/ServiceScrapper/parsers/base.py +94 -0
  175. flowtask/components/ServiceScrapper/parsers/costco.py +93 -0
  176. flowtask/components/ServiceScrapper/scrapper.py +199 -0
  177. flowtask/components/SetVariables.py +156 -0
  178. flowtask/components/SubTask.py +182 -0
  179. flowtask/components/SuiteCRM.py +48 -0
  180. flowtask/components/Switch.py +175 -0
  181. flowtask/components/TableBase.py +148 -0
  182. flowtask/components/TableDelete.py +312 -0
  183. flowtask/components/TableInput.py +143 -0
  184. flowtask/components/TableOutput/TableOutput.py +384 -0
  185. flowtask/components/TableOutput/__init__.py +3 -0
  186. flowtask/components/TableSchema.py +534 -0
  187. flowtask/components/Target.py +223 -0
  188. flowtask/components/ThumbnailGenerator.py +156 -0
  189. flowtask/components/ToPandas.py +67 -0
  190. flowtask/components/TransformRows/TransformRows.py +507 -0
  191. flowtask/components/TransformRows/__init__.py +9 -0
  192. flowtask/components/TransformRows/functions.py +559 -0
  193. flowtask/components/TransposeRows.py +176 -0
  194. flowtask/components/UPCDatabase.py +86 -0
  195. flowtask/components/UnGzip.py +171 -0
  196. flowtask/components/Uncompress.py +172 -0
  197. flowtask/components/UniqueRows.py +126 -0
  198. flowtask/components/Unzip.py +107 -0
  199. flowtask/components/UpdateOperationalVars.py +147 -0
  200. flowtask/components/UploadTo.py +299 -0
  201. flowtask/components/UploadToS3.py +136 -0
  202. flowtask/components/UploadToSFTP.py +160 -0
  203. flowtask/components/UploadToSharepoint.py +205 -0
  204. flowtask/components/UserFunc.py +122 -0
  205. flowtask/components/VivaTracker.py +140 -0
  206. flowtask/components/WSDLClient.py +123 -0
  207. flowtask/components/Wait.py +18 -0
  208. flowtask/components/Walmart.py +199 -0
  209. flowtask/components/Workplace.py +134 -0
  210. flowtask/components/XMLToPandas.py +267 -0
  211. flowtask/components/Zammad/__init__.py +41 -0
  212. flowtask/components/Zammad/models.py +0 -0
  213. flowtask/components/ZoomInfoScraper.py +409 -0
  214. flowtask/components/__init__.py +104 -0
  215. flowtask/components/abstract.py +18 -0
  216. flowtask/components/flow.py +530 -0
  217. flowtask/components/google.py +335 -0
  218. flowtask/components/group.py +221 -0
  219. flowtask/components/py.typed +0 -0
  220. flowtask/components/reviewscrap.py +132 -0
  221. flowtask/components/tAutoincrement.py +117 -0
  222. flowtask/components/tConcat.py +109 -0
  223. flowtask/components/tExplode.py +119 -0
  224. flowtask/components/tFilter.py +184 -0
  225. flowtask/components/tGroup.py +236 -0
  226. flowtask/components/tJoin.py +270 -0
  227. flowtask/components/tMap/__init__.py +9 -0
  228. flowtask/components/tMap/functions.py +54 -0
  229. flowtask/components/tMap/tMap.py +450 -0
  230. flowtask/components/tMelt.py +112 -0
  231. flowtask/components/tMerge.py +114 -0
  232. flowtask/components/tOrder.py +93 -0
  233. flowtask/components/tPandas.py +94 -0
  234. flowtask/components/tPivot.py +71 -0
  235. flowtask/components/tPluckCols.py +76 -0
  236. flowtask/components/tUnnest.py +82 -0
  237. flowtask/components/user.py +401 -0
  238. flowtask/conf.py +457 -0
  239. flowtask/download.py +102 -0
  240. flowtask/events/__init__.py +11 -0
  241. flowtask/events/events/__init__.py +20 -0
  242. flowtask/events/events/abstract.py +95 -0
  243. flowtask/events/events/alerts/__init__.py +362 -0
  244. flowtask/events/events/alerts/colfunctions.py +131 -0
  245. flowtask/events/events/alerts/functions.py +158 -0
  246. flowtask/events/events/dummy.py +12 -0
  247. flowtask/events/events/exec.py +124 -0
  248. flowtask/events/events/file/__init__.py +7 -0
  249. flowtask/events/events/file/base.py +51 -0
  250. flowtask/events/events/file/copy.py +23 -0
  251. flowtask/events/events/file/delete.py +16 -0
  252. flowtask/events/events/interfaces/__init__.py +9 -0
  253. flowtask/events/events/interfaces/client.py +67 -0
  254. flowtask/events/events/interfaces/credentials.py +28 -0
  255. flowtask/events/events/interfaces/notifications.py +58 -0
  256. flowtask/events/events/jira.py +122 -0
  257. flowtask/events/events/log.py +26 -0
  258. flowtask/events/events/logerr.py +52 -0
  259. flowtask/events/events/notify.py +59 -0
  260. flowtask/events/events/notify_event.py +160 -0
  261. flowtask/events/events/publish.py +54 -0
  262. flowtask/events/events/sendfile.py +104 -0
  263. flowtask/events/events/task.py +97 -0
  264. flowtask/events/events/teams.py +98 -0
  265. flowtask/events/events/webhook.py +58 -0
  266. flowtask/events/manager.py +287 -0
  267. flowtask/exceptions.c +39393 -0
  268. flowtask/exceptions.cpython-312-x86_64-linux-gnu.so +0 -0
  269. flowtask/extensions/__init__.py +3 -0
  270. flowtask/extensions/abstract.py +82 -0
  271. flowtask/extensions/logging/__init__.py +65 -0
  272. flowtask/hooks/__init__.py +9 -0
  273. flowtask/hooks/actions/__init__.py +22 -0
  274. flowtask/hooks/actions/abstract.py +66 -0
  275. flowtask/hooks/actions/dummy.py +23 -0
  276. flowtask/hooks/actions/jira.py +74 -0
  277. flowtask/hooks/actions/rest.py +320 -0
  278. flowtask/hooks/actions/sampledata.py +37 -0
  279. flowtask/hooks/actions/sensor.py +23 -0
  280. flowtask/hooks/actions/task.py +9 -0
  281. flowtask/hooks/actions/ticket.py +37 -0
  282. flowtask/hooks/actions/zammad.py +55 -0
  283. flowtask/hooks/hook.py +62 -0
  284. flowtask/hooks/models.py +17 -0
  285. flowtask/hooks/service.py +187 -0
  286. flowtask/hooks/step.py +91 -0
  287. flowtask/hooks/types/__init__.py +23 -0
  288. flowtask/hooks/types/base.py +129 -0
  289. flowtask/hooks/types/brokers/__init__.py +11 -0
  290. flowtask/hooks/types/brokers/base.py +54 -0
  291. flowtask/hooks/types/brokers/mqtt.py +35 -0
  292. flowtask/hooks/types/brokers/rabbitmq.py +82 -0
  293. flowtask/hooks/types/brokers/redis.py +83 -0
  294. flowtask/hooks/types/brokers/sqs.py +44 -0
  295. flowtask/hooks/types/fs.py +232 -0
  296. flowtask/hooks/types/http.py +49 -0
  297. flowtask/hooks/types/imap.py +200 -0
  298. flowtask/hooks/types/jira.py +279 -0
  299. flowtask/hooks/types/mail.py +205 -0
  300. flowtask/hooks/types/postgres.py +98 -0
  301. flowtask/hooks/types/responses/__init__.py +8 -0
  302. flowtask/hooks/types/responses/base.py +5 -0
  303. flowtask/hooks/types/sharepoint.py +288 -0
  304. flowtask/hooks/types/ssh.py +141 -0
  305. flowtask/hooks/types/tagged.py +59 -0
  306. flowtask/hooks/types/upload.py +85 -0
  307. flowtask/hooks/types/watch.py +71 -0
  308. flowtask/hooks/types/web.py +36 -0
  309. flowtask/interfaces/AzureClient.py +137 -0
  310. flowtask/interfaces/AzureGraph.py +839 -0
  311. flowtask/interfaces/Boto3Client.py +326 -0
  312. flowtask/interfaces/DropboxClient.py +173 -0
  313. flowtask/interfaces/ExcelHandler.py +94 -0
  314. flowtask/interfaces/FTPClient.py +131 -0
  315. flowtask/interfaces/GoogleCalendar.py +201 -0
  316. flowtask/interfaces/GoogleClient.py +133 -0
  317. flowtask/interfaces/GoogleDrive.py +127 -0
  318. flowtask/interfaces/GoogleGCS.py +89 -0
  319. flowtask/interfaces/GoogleGeocoding.py +93 -0
  320. flowtask/interfaces/GoogleLang.py +114 -0
  321. flowtask/interfaces/GooglePub.py +61 -0
  322. flowtask/interfaces/GoogleSheet.py +68 -0
  323. flowtask/interfaces/IMAPClient.py +137 -0
  324. flowtask/interfaces/O365Calendar.py +113 -0
  325. flowtask/interfaces/O365Client.py +220 -0
  326. flowtask/interfaces/OneDrive.py +284 -0
  327. flowtask/interfaces/Outlook.py +155 -0
  328. flowtask/interfaces/ParrotBot.py +130 -0
  329. flowtask/interfaces/SSHClient.py +378 -0
  330. flowtask/interfaces/Sharepoint.py +496 -0
  331. flowtask/interfaces/__init__.py +36 -0
  332. flowtask/interfaces/azureauth.py +119 -0
  333. flowtask/interfaces/cache.py +201 -0
  334. flowtask/interfaces/client.py +82 -0
  335. flowtask/interfaces/compress.py +525 -0
  336. flowtask/interfaces/credentials.py +124 -0
  337. flowtask/interfaces/d2l.py +239 -0
  338. flowtask/interfaces/databases/__init__.py +5 -0
  339. flowtask/interfaces/databases/db.py +223 -0
  340. flowtask/interfaces/databases/documentdb.py +55 -0
  341. flowtask/interfaces/databases/rethink.py +39 -0
  342. flowtask/interfaces/dataframes/__init__.py +11 -0
  343. flowtask/interfaces/dataframes/abstract.py +21 -0
  344. flowtask/interfaces/dataframes/arrow.py +71 -0
  345. flowtask/interfaces/dataframes/dt.py +69 -0
  346. flowtask/interfaces/dataframes/pandas.py +167 -0
  347. flowtask/interfaces/dataframes/polars.py +60 -0
  348. flowtask/interfaces/db.py +263 -0
  349. flowtask/interfaces/env.py +46 -0
  350. flowtask/interfaces/func.py +137 -0
  351. flowtask/interfaces/http.py +1780 -0
  352. flowtask/interfaces/locale.py +40 -0
  353. flowtask/interfaces/log.py +75 -0
  354. flowtask/interfaces/mask.py +143 -0
  355. flowtask/interfaces/notification.py +154 -0
  356. flowtask/interfaces/playwright.py +339 -0
  357. flowtask/interfaces/powerpoint.py +368 -0
  358. flowtask/interfaces/py.typed +0 -0
  359. flowtask/interfaces/qs.py +376 -0
  360. flowtask/interfaces/result.py +87 -0
  361. flowtask/interfaces/selenium_service.py +779 -0
  362. flowtask/interfaces/smartsheet.py +154 -0
  363. flowtask/interfaces/stat.py +39 -0
  364. flowtask/interfaces/task.py +96 -0
  365. flowtask/interfaces/template.py +118 -0
  366. flowtask/interfaces/vectorstores/__init__.py +1 -0
  367. flowtask/interfaces/vectorstores/abstract.py +133 -0
  368. flowtask/interfaces/vectorstores/milvus.py +669 -0
  369. flowtask/interfaces/zammad.py +107 -0
  370. flowtask/models.py +193 -0
  371. flowtask/parsers/__init__.py +15 -0
  372. flowtask/parsers/_yaml.c +11978 -0
  373. flowtask/parsers/_yaml.cpython-312-x86_64-linux-gnu.so +0 -0
  374. flowtask/parsers/argparser.py +235 -0
  375. flowtask/parsers/base.c +15155 -0
  376. flowtask/parsers/base.cpython-312-x86_64-linux-gnu.so +0 -0
  377. flowtask/parsers/json.c +11968 -0
  378. flowtask/parsers/json.cpython-312-x86_64-linux-gnu.so +0 -0
  379. flowtask/parsers/maps.py +49 -0
  380. flowtask/parsers/toml.c +11968 -0
  381. flowtask/parsers/toml.cpython-312-x86_64-linux-gnu.so +0 -0
  382. flowtask/plugins/__init__.py +16 -0
  383. flowtask/plugins/components/__init__.py +0 -0
  384. flowtask/plugins/handler/__init__.py +45 -0
  385. flowtask/plugins/importer.py +31 -0
  386. flowtask/plugins/sources/__init__.py +0 -0
  387. flowtask/runner.py +283 -0
  388. flowtask/scheduler/__init__.py +9 -0
  389. flowtask/scheduler/functions.py +493 -0
  390. flowtask/scheduler/handlers/__init__.py +8 -0
  391. flowtask/scheduler/handlers/manager.py +504 -0
  392. flowtask/scheduler/handlers/models.py +58 -0
  393. flowtask/scheduler/handlers/service.py +72 -0
  394. flowtask/scheduler/notifications.py +65 -0
  395. flowtask/scheduler/scheduler.py +993 -0
  396. flowtask/services/__init__.py +0 -0
  397. flowtask/services/bots/__init__.py +0 -0
  398. flowtask/services/bots/telegram.py +264 -0
  399. flowtask/services/files/__init__.py +11 -0
  400. flowtask/services/files/manager.py +522 -0
  401. flowtask/services/files/model.py +37 -0
  402. flowtask/services/files/service.py +767 -0
  403. flowtask/services/jira/__init__.py +3 -0
  404. flowtask/services/jira/jira_actions.py +191 -0
  405. flowtask/services/tasks/__init__.py +13 -0
  406. flowtask/services/tasks/launcher.py +213 -0
  407. flowtask/services/tasks/manager.py +323 -0
  408. flowtask/services/tasks/service.py +275 -0
  409. flowtask/services/tasks/task_manager.py +376 -0
  410. flowtask/services/tasks/tasks.py +155 -0
  411. flowtask/storages/__init__.py +16 -0
  412. flowtask/storages/exceptions.py +12 -0
  413. flowtask/storages/files/__init__.py +8 -0
  414. flowtask/storages/files/abstract.py +29 -0
  415. flowtask/storages/files/filesystem.py +66 -0
  416. flowtask/storages/tasks/__init__.py +19 -0
  417. flowtask/storages/tasks/abstract.py +26 -0
  418. flowtask/storages/tasks/database.py +33 -0
  419. flowtask/storages/tasks/filesystem.py +108 -0
  420. flowtask/storages/tasks/github.py +119 -0
  421. flowtask/storages/tasks/memory.py +45 -0
  422. flowtask/storages/tasks/row.py +25 -0
  423. flowtask/tasks/__init__.py +0 -0
  424. flowtask/tasks/abstract.py +526 -0
  425. flowtask/tasks/command.py +118 -0
  426. flowtask/tasks/pile.py +486 -0
  427. flowtask/tasks/py.typed +0 -0
  428. flowtask/tasks/task.py +778 -0
  429. flowtask/template/__init__.py +161 -0
  430. flowtask/tests.py +257 -0
  431. flowtask/types/__init__.py +8 -0
  432. flowtask/types/typedefs.c +11347 -0
  433. flowtask/types/typedefs.cpython-312-x86_64-linux-gnu.so +0 -0
  434. flowtask/utils/__init__.py +24 -0
  435. flowtask/utils/constants.py +117 -0
  436. flowtask/utils/encoders.py +21 -0
  437. flowtask/utils/executor.py +112 -0
  438. flowtask/utils/functions.cpp +14280 -0
  439. flowtask/utils/functions.cpython-312-x86_64-linux-gnu.so +0 -0
  440. flowtask/utils/json.cpp +13349 -0
  441. flowtask/utils/json.cpython-312-x86_64-linux-gnu.so +0 -0
  442. flowtask/utils/mail.py +63 -0
  443. flowtask/utils/parseqs.c +13324 -0
  444. flowtask/utils/parserqs.cpython-312-x86_64-linux-gnu.so +0 -0
  445. flowtask/utils/stats.py +308 -0
  446. flowtask/utils/transformations.py +74 -0
  447. flowtask/utils/uv.py +12 -0
  448. flowtask/utils/validators.py +97 -0
  449. flowtask/version.py +11 -0
  450. flowtask-5.8.4.dist-info/LICENSE +201 -0
  451. flowtask-5.8.4.dist-info/METADATA +209 -0
  452. flowtask-5.8.4.dist-info/RECORD +470 -0
  453. flowtask-5.8.4.dist-info/WHEEL +6 -0
  454. flowtask-5.8.4.dist-info/entry_points.txt +3 -0
  455. flowtask-5.8.4.dist-info/top_level.txt +2 -0
  456. plugins/components/CreateQR.py +39 -0
  457. plugins/components/TestComponent.py +28 -0
  458. plugins/components/Use1.py +13 -0
  459. plugins/components/Workplace.py +117 -0
  460. plugins/components/__init__.py +3 -0
  461. plugins/sources/__init__.py +0 -0
  462. plugins/sources/get_populartimes.py +78 -0
  463. plugins/sources/google.py +150 -0
  464. plugins/sources/hubspot.py +679 -0
  465. plugins/sources/icims.py +679 -0
  466. plugins/sources/mobileinsight.py +501 -0
  467. plugins/sources/newrelic.py +262 -0
  468. plugins/sources/uap.py +268 -0
  469. plugins/sources/venu.py +244 -0
  470. plugins/sources/vocinity.py +314 -0
@@ -0,0 +1,522 @@
1
+ """
2
+ FileManager.
3
+
4
+ Works with files, download, upload and delete files over FS using an API.
5
+
6
+ TODO: Send a data-preview (first 10 rows) of uploaded file
7
+ TODO: html-template for Uploader preview with "back" button.
8
+ """
9
+ import os
10
+ import hashlib
11
+ from pathlib import Path
12
+ import aiofiles
13
+ import magic
14
+ from aiohttp import web
15
+ from aiohttp.web import StreamResponse, FileResponse
16
+ from navigator.views import BaseView
17
+ from navigator.responses import Response
18
+ from ...utils.json import json_encoder
19
+ from ...exceptions import (
20
+ FileError
21
+ )
22
+ from ...conf import FILES_PATH
23
+
24
+
25
+ class FileManagerFactory:
26
+ def __new__(cls, path: Path, subpath: str = 'files') -> bool:
27
+ class CustomFileManager(FileManager):
28
+ pass
29
+
30
+ CustomFileManager.define_filepath(path, subpath)
31
+ return CustomFileManager
32
+
33
+ class FileManager(BaseView):
34
+ """API View for managing Files.
35
+ """
36
+ _path: Path = None
37
+ _subpath: str = None
38
+
39
+ @classmethod
40
+ def define_filepath(cls, path: Path, subpath: str = 'files'):
41
+ if isinstance(path, str):
42
+ path = Path(path).resolve()
43
+ cls._path = path
44
+ cls._subpath = subpath
45
+
46
+ def __init__(self, request, *args, **kwargs):
47
+ BaseView.__init__(self, request, *args, **kwargs)
48
+ self.mime = magic.Magic(mime=True)
49
+
50
+ def file_exists(self, program, filename):
51
+ fpath = self._path.joinpath(program, self._subpath, filename)
52
+ if fpath.exists():
53
+ return fpath
54
+ else:
55
+ return None
56
+
57
+ def delete_file(self, filename):
58
+ if filename.exists():
59
+ try:
60
+ filename.unlink()
61
+ except Exception as err:
62
+ raise FileError(
63
+ f"Error deleting file: {err}"
64
+ ) from err
65
+
66
+ async def read_file(self, filename):
67
+ content = None
68
+ try:
69
+ async with aiofiles.open(filename, 'rb') as afp:
70
+ content = await afp.read()
71
+ return content
72
+ except Exception as err:
73
+ raise FileError(
74
+ f"Error reading file: {err}"
75
+ ) from err
76
+
77
+ async def get_response(self, headers) -> web.Response:
78
+ """Returns a valid Web.Response"""
79
+ response = StreamResponse(
80
+ status=200,
81
+ reason='OK',
82
+ headers={
83
+ 'Pragma': "public", # required,
84
+ 'Expires': '0',
85
+ 'Connection': 'keep-alive',
86
+ 'Cache-Control': 'must-revalidate, post-check=0, pre-check=0',
87
+ **headers
88
+ }
89
+ )
90
+ response.enable_compression()
91
+ return response
92
+
93
+ async def return_file(self, filename, **kwargs) -> web.Response:
94
+ """Returns a File based on a Stream Response
95
+ """
96
+ # HTTP headers for forcing file download
97
+ # TODO: try to discover the content type
98
+ content_type = "application/octet-stream"
99
+ # content_type = "application/vnd.ms-excel"
100
+ content = await self.read_file(filename)
101
+ file = filename.name
102
+ headers = {
103
+ 'Content-Type': content_type,
104
+ 'Content-Transfer-Encoding': 'binary',
105
+ 'Content-Disposition': f'attachment; filename="{file}"'
106
+ }
107
+ if 'headers' in kwargs:
108
+ headers = {**headers, **kwargs['headers']}
109
+ try:
110
+ response = await self.get_response(headers)
111
+ response.headers['X-Content-SHA1'] = hashlib.sha1(file.encode('utf-8')).hexdigest()
112
+ response.content_type = content_type
113
+ # push the content
114
+ response.content_length = len(content)
115
+ await response.prepare(self.request)
116
+ if self.request.transport.is_closing():
117
+ return Response(
118
+ text=json_encoder({"Closed Output"}), status=404,
119
+ content_type='application/json'
120
+ )
121
+ await response.write(content)
122
+ await response.write_eof()
123
+ # await resp.drain()
124
+ return response
125
+ except Exception as err:
126
+ raise FileError(
127
+ f"Error reading file {filename} for download: {err}"
128
+ ) from err
129
+
130
+ async def save_file(self, filename, content):
131
+ try:
132
+ async with aiofiles.open(filename, 'wb') as out:
133
+ content.seek(0)
134
+ await out.write(content.read())
135
+ await out.flush()
136
+ return True
137
+ except Exception as err:
138
+ raise FileError(
139
+ f"Error Saving File: {err}"
140
+ ) from err
141
+
142
+ def list_dir(self, program, filepath):
143
+ fpath = self._path.joinpath(program, self._subpath, filepath)
144
+ file_list = []
145
+ if fpath.exists():
146
+ for f in fpath.iterdir():
147
+ if f.is_file():
148
+ try:
149
+ mime = self.mime.from_file(f)
150
+ except TypeError:
151
+ mime = None
152
+ file_stats = os.stat(f)
153
+ file = {
154
+ "path": str(f),
155
+ "filename": f.name,
156
+ "size": f"{file_stats.st_size / (1024):.2f} Kb",
157
+ "mimetype": mime
158
+ }
159
+ file_list.append(file)
160
+ else:
161
+ file_list.append(str(f)) # is a directory
162
+ return file_list
163
+
164
+ async def get(self):
165
+ """
166
+ GET Method.
167
+ ---
168
+ description: Managing Files.
169
+ tags:
170
+ - File Manager
171
+ consumes:
172
+ - application/json
173
+ produces:
174
+ - application/json
175
+ """
176
+ arguments = self.get_arguments()
177
+ # {'program': 'walmart', 'filepath': ''}
178
+ program = arguments['program']
179
+ try:
180
+ filepath = arguments['filepath']
181
+ except KeyError:
182
+ filepath = None
183
+ try:
184
+ meta = arguments['meta']
185
+ except KeyError:
186
+ meta = None
187
+ if not filepath:
188
+ # return a list of files on root directory
189
+ result = self.list_dir(program, '')
190
+ headers = {
191
+ 'X-STATUS': 'OK',
192
+ 'X-MESSAGE': 'Root Directory listing'
193
+ }
194
+ return self.json_response(
195
+ response=result,
196
+ headers=headers,
197
+ status=202
198
+ )
199
+ else:
200
+ root, ext = os.path.splitext(filepath)
201
+ if not ext:
202
+ # is a directory, need to list the files in that directory
203
+ result = self.list_dir(program, filepath)
204
+ headers = {
205
+ 'X-STATUS': 'OK',
206
+ 'X-MESSAGE': 'Directory listing'
207
+ }
208
+ return self.json_response(
209
+ response=result,
210
+ headers=headers,
211
+ status=202
212
+ )
213
+ else:
214
+ # get file metadata or download a file
215
+ try:
216
+ if not meta:
217
+ if filename := self.file_exists(program, filepath):
218
+ # getting this file from server using a Stream API
219
+ headers = {
220
+ 'X-STATUS': 'OK',
221
+ 'X-MESSAGE': 'File Exists',
222
+ 'X-FILENAME': str(filename),
223
+ "X-DIRECTORY": str(filename.parent),
224
+ 'X-FILESIZE': f"{filename.stat().st_size}"
225
+ }
226
+ # return await self.return_file(filename, headers=headers)
227
+ return FileResponse(filename, headers=headers, status=200)
228
+ else:
229
+ # file doesn't exists
230
+ headers = {
231
+ 'X-STATUS': 'EMPTY',
232
+ 'X-MESSAGE': 'File not Found',
233
+ 'X-FILENAME': ''
234
+ }
235
+ return self.no_content(headers=headers)
236
+ else:
237
+ ### returning only the File Stats:
238
+ filename = self.file_exists(program, filepath)
239
+ headers = {
240
+ 'X-STATUS': 'OK',
241
+ 'X-MESSAGE': 'File Exists',
242
+ 'X-FILENAME': str(filename),
243
+ 'X-FILESIZE': f"{filename.stat().st_size}"
244
+ }
245
+ try:
246
+ mime = self.mime.from_file(filename)
247
+ except TypeError:
248
+ mime = "application/octet-stream"
249
+ fileinfo = {
250
+ "filename": str(filename),
251
+ "name": str(filename.name),
252
+ "directory": str(filename.parent),
253
+ "mimetype": mime,
254
+ "size": f"{filename.stat().st_size / (1024):.2f}"
255
+ }
256
+ return self.json_response(
257
+ response=fileinfo,
258
+ headers=headers,
259
+ status=200
260
+ )
261
+ except Exception as err:
262
+ return self.critical(
263
+ exception=err
264
+ )
265
+
266
+ async def head(self):
267
+ """
268
+ HEAD Method.
269
+ description: Sent response about file exists or not.
270
+ tags:
271
+ - files
272
+ - File Manager
273
+ - filesystem
274
+ - file
275
+ consumes:
276
+ - application/json
277
+ produces:
278
+ - application/json
279
+ """
280
+ arguments = self.get_arguments()
281
+ # {'program': 'walmart', 'filepath': 'seasonality.xslx'}
282
+ try:
283
+ if filename := self.file_exists(arguments['program'], arguments['filepath']):
284
+ headers = {
285
+ 'X-STATUS': 'OK',
286
+ 'X-MESSAGE': 'File Exists',
287
+ 'X-FILENAME': str(filename),
288
+ 'X-DIRECTORY': str(filename.parent),
289
+ 'X-FILESIZE': f"{filename.stat().st_size}",
290
+ "X-SIZE": f"{filename.stat().st_size / (1024):.2f} Kb"
291
+ }
292
+ print(headers)
293
+ else:
294
+ # file doesn't exists
295
+ headers = {
296
+ 'X-STATUS': 'EMPTY',
297
+ 'X-MESSAGE': 'File not Found',
298
+ 'X-FILENAME': ''
299
+ }
300
+ return self.no_content(headers=headers)
301
+ except Exception as err:
302
+ return self.critical(
303
+ exception=err
304
+ )
305
+
306
+ async def delete(self):
307
+ """
308
+ DELETe Method.
309
+ description: Deletes a File (if exists) on Directory
310
+ tags:
311
+ - files
312
+ - File Manager
313
+ - filesystem
314
+ - file
315
+ consumes:
316
+ - application/json
317
+ produces:
318
+ - application/json
319
+ """
320
+ arguments = self.get_arguments()
321
+ try:
322
+ if filename := self.file_exists(arguments['program'], arguments['filepath']):
323
+ # trying to delete the file:
324
+ try:
325
+ self.delete_file(filename)
326
+ # deletes sucessful
327
+ headers = {
328
+ 'X-STATUS': 'OK',
329
+ 'X-MESSAGE': 'File Deleted',
330
+ 'X-FILENAME': str(filename)
331
+ }
332
+ msg = {
333
+ "response": f'File {filename!s} was deleted successfully'
334
+ }
335
+ state = 202
336
+ except Exception as err:
337
+ headers = {
338
+ 'X-STATUS': 'FAIL',
339
+ 'X-MESSAGE': 'Error Deleting File',
340
+ 'X-ERROR': str(err),
341
+ 'X-FILENAME': str(filename)
342
+ }
343
+ msg = {
344
+ "response": f'Failed deleting file {filename!s}'
345
+ }
346
+ state = 401
347
+ return self.json_response(
348
+ response=msg,
349
+ headers=headers,
350
+ status=state
351
+ )
352
+ else:
353
+ # file doesn't exists
354
+ headers = {
355
+ 'X-STATUS': 'EMPTY',
356
+ 'X-MESSAGE': 'File not Found',
357
+ 'X-FILENAME': ''
358
+ }
359
+ return self.no_content(headers=headers)
360
+ except Exception as err:
361
+ return self.critical(
362
+ exception=err
363
+ )
364
+
365
+ async def post(self):
366
+ """
367
+ POST Method.
368
+ description: upload a file onto repository directory.
369
+ tags:
370
+ - files
371
+ - File Manager
372
+ - filesystem
373
+ - file
374
+ consumes:
375
+ - application/json
376
+ produces:
377
+ - application/json
378
+ """
379
+ arguments = self.get_arguments()
380
+ program = arguments['program']
381
+ try:
382
+ filepath = arguments['filepath']
383
+ except KeyError:
384
+ filepath = ''
385
+
386
+ # post-data
387
+ frm = await self.request.post()
388
+ try:
389
+ file = frm.get('file_name')
390
+ except (ValueError, KeyError) as err:
391
+ return self.error(
392
+ exception=err,
393
+ status=406
394
+ )
395
+ # get the filename for save:
396
+ if filepath != '':
397
+ root, ext = os.path.splitext(filepath)
398
+ if not ext:
399
+ # is a directory, firstly, check if root exists over FS
400
+ print('ROOT ', root)
401
+ filepath = self._path.joinpath(program, 'files', root)
402
+ if not filepath.exists():
403
+ filepath.mkdir()
404
+ # create the new filename:
405
+ filename = file.filename
406
+ fpath = filepath.joinpath(filename)
407
+ else:
408
+ # is a filename, with (or without) subfolder
409
+ filename = arguments['filepath']
410
+ filepath = self._path.joinpath(program, self._subpath, filename)
411
+ if not filepath.parent.exists():
412
+ filepath.parent.mkdir()
413
+ # at the end, the new name of the file:
414
+ fpath = filepath
415
+ else:
416
+ # preserving original name
417
+ filename = file.filename
418
+ fpath = self._path.joinpath(program, self._subpath, filename)
419
+ # get file handler
420
+ iofile = file.file
421
+ mimetype = file.content_type
422
+ # fpath = self._path.joinpath(program, 'files', filename)
423
+ # TODO: saving file using a thread executor:
424
+ try:
425
+ if fpath.exists():
426
+ # unlink the previous file
427
+ fpath.unlink()
428
+ if await self.save_file(fpath, iofile):
429
+ headers = {
430
+ 'X-STATUS': 'OK',
431
+ 'X-MESSAGE': 'File Uploaded',
432
+ 'X-FILENAME': str(fpath)
433
+ }
434
+ return self.json_response(
435
+ response=f"File uploaded successfully: {filename}",
436
+ headers=headers,
437
+ status=202
438
+ )
439
+ else:
440
+ headers = {
441
+ 'X-STATUS': 'ERROR',
442
+ 'X-MESSAGE': 'Not Uploaded',
443
+ 'X-FILENAME': str(fpath)
444
+ }
445
+ return self.error(
446
+ response=f'Cannot upload the file {filename!s}',
447
+ status=403
448
+ )
449
+ except Exception as err:
450
+ return self.error(
451
+ response=f'Cannot upload file {filename!s}',
452
+ exception=err,
453
+ status=406
454
+ )
455
+
456
+ async def put(self):
457
+ """
458
+ PUT Method.
459
+ description: Create a new directory.
460
+ tags:
461
+ - files
462
+ - File Manager
463
+ - filesystem
464
+ - file
465
+ consumes:
466
+ - application/json
467
+ produces:
468
+ - application/json
469
+ """
470
+ arguments = self.get_arguments()
471
+ program = arguments['program']
472
+ try:
473
+ filepath = arguments['filepath']
474
+ except KeyError:
475
+ filepath = ''
476
+
477
+ if filepath != '':
478
+ root, ext = os.path.splitext(filepath)
479
+ else:
480
+ root = ''
481
+ ext = None
482
+ try:
483
+ if not ext:
484
+ filepath = self._path.joinpath(program, self._subpath, root)
485
+ if not filepath.exists():
486
+ filepath.mkdir()
487
+ headers = {
488
+ 'X-STATUS': 'OK',
489
+ 'X-MESSAGE': 'File Uploaded',
490
+ 'X-FOLDER': str(filepath)
491
+ }
492
+ return self.json_response(
493
+ response="Folder Created successfully",
494
+ headers=headers,
495
+ status=202
496
+ )
497
+ else:
498
+ headers = {
499
+ 'X-STATUS': 'ERROR',
500
+ 'X-MESSAGE': 'Path exists',
501
+ 'X-FOLDER': str(filepath)
502
+ }
503
+ return self.json_response(
504
+ response='Path exists',
505
+ headers=headers,
506
+ status=403
507
+ )
508
+ else:
509
+ headers = {
510
+ 'X-STATUS': 'ERROR',
511
+ 'X-MESSAGE': 'Path not directory',
512
+ 'X-FOLDER': str(filepath)
513
+ }
514
+ return self.json_response(
515
+ response='Path not directory',
516
+ headers=headers,
517
+ status=403
518
+ )
519
+ except Exception as err:
520
+ raise FileError(
521
+ f"Error Creating Folder: {err}"
522
+ ) from err
@@ -0,0 +1,37 @@
1
+ """FileService DB Model.
2
+
3
+ Database Object Model for FileServices.
4
+ """
5
+ from datetime import datetime
6
+ import uuid
7
+ from asyncdb.models import Column, Model
8
+
9
+ def auto_now_add(*args, **kwargs):
10
+ return uuid.uuid4()
11
+
12
+
13
+ class FileModel(Model):
14
+ file_id: int = Column(required=False, primary_key=True, db_default='auto')
15
+ file_uid: uuid.UUID = Column(default=auto_now_add, required=True, primary_key=True, db_default='uuid_generate_v4()')
16
+ file_slug: str = Column(required=True)
17
+ program_id: int = Column(required=True, default=6)
18
+ program_slug: str = Column(required=True, default='troc')
19
+ mimetype: str = Column(required=True, default='text/csv')
20
+ description: str = Column(required=False)
21
+ filename: dict = Column(required=False, default_factory=lambda: {"name": "", "pattern": ""})
22
+ attributes: dict = Column(
23
+ required=False,
24
+ default_factory=lambda: {"overwrite": True, "create_dir": True, "show_preview": True}
25
+ )
26
+ params: dict = Column(required=False, default_factory=dict)
27
+ fields: list = Column(required=False, default_factory=lambda: [])
28
+ task_enabled: bool = Column(required=True, default=False)
29
+ active: bool = Column(required=True, default=False)
30
+ uploaded_at: datetime = Column(required=False, default=datetime.now())
31
+ created_at: datetime = Column(required=False)
32
+
33
+ class Meta:
34
+ name = 'files'
35
+ schema = 'troc'
36
+ strict = False
37
+ frozen = False