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,239 @@
1
+ """
2
+ D2L.
3
+
4
+ Making operations over D2L.
5
+
6
+ """
7
+ import re
8
+ from datetime import datetime, timezone
9
+ from ..exceptions import (
10
+ ComponentError
11
+ )
12
+ import random
13
+ from .http import HTTPService, ua
14
+ from .cache import CacheSupport
15
+
16
+ class D2LClient(CacheSupport, HTTPService):
17
+ '''
18
+ Manage Connection to D2L
19
+ '''
20
+ def __init__(self, *args, **kwargs):
21
+ self.token_type: str = "Bearer"
22
+ self.auth_type: str = "apikey"
23
+ self.domain: str = kwargs.pop('domain', None)
24
+ self.domain = self.get_env_value(self.domain, self.domain)
25
+ self.url_login: str = f'https://{self.domain}/d2l/lp/auth/login/login.d2l'
26
+ self.url_token: str = f'https://{self.domain}/d2l/lp/auth/oauth2/token'
27
+ self.file_format: str = 'application/zip'
28
+ self.create_destination: bool = True # by default
29
+ self.dataset: str = kwargs.pop('dataset', None)
30
+ self.plugin: str = kwargs.pop('plugin', None)
31
+ self.d2l_session_val: str = None
32
+ self.d2l_secure_session_val: str = None
33
+ self.csrf_token: str = None
34
+ self.auth: dict = {'apikey': None}
35
+ super().__init__(*args, **kwargs)
36
+ self.processing_credentials()
37
+ self.username: str = self.credentials.get('username', None)
38
+ self.password: str = self.credentials.get('password', None)
39
+ self.headers = {
40
+ "Accept-Encoding": "gzip, deflate",
41
+ "DNT": "1",
42
+ "Connection": "keep-alive",
43
+ "Upgrade-Insecure-Requests": "1",
44
+ "User-Agent": random.choice(ua)
45
+ }
46
+
47
+ async def get_bearer_token(self):
48
+ # Try to get API Key from REDIS
49
+ with await self.open() as redis:
50
+ api_key = redis.get('D2L_API_KEY')
51
+ d2l_session_val = redis.get('D2L_SESSION_VAL')
52
+ d2l_secure_session_val = redis.get('D2L_SECURE_SESSION_VAL')
53
+ if api_key:
54
+ self.auth['apikey'] = api_key
55
+ self.cookies = {
56
+ "d2lSessionVal": d2l_session_val,
57
+ "d2lSecureSessionVal": d2l_secure_session_val
58
+ }
59
+ self.headers["Authorization"] = f"Bearer {self.auth.get('apikey')}"
60
+ return api_key
61
+ # Get cookies values
62
+ login_headers = {
63
+ "Content-Type": "application/x-www-form-urlencoded",
64
+ "Origin": f"https://{self.domain}",
65
+ "Referer": f"https://{self.domain}/d2l/login",
66
+ "User-Agent": random.choice(ua)
67
+ }
68
+ login_data = {
69
+ "d2l_referrer": f"https://{self.domain}/d2l/login",
70
+ "loginPath": "/d2l/login",
71
+ "userName": self.username,
72
+ "password": self.password,
73
+ }
74
+ try:
75
+ response = await self._post(
76
+ url=self.url_login,
77
+ cookies=None,
78
+ headers=login_headers,
79
+ data=login_data,
80
+ follow_redirects=False,
81
+ raise_for_status=False,
82
+ use_proxy= False
83
+ )
84
+ d2l_session_val = response.cookies.get("d2lSessionVal", "")
85
+ d2l_secure_session_val = response.cookies.get("d2lSecureSessionVal", "")
86
+ self.cookies = {
87
+ "d2lSessionVal": d2l_session_val,
88
+ "d2lSecureSessionVal": d2l_secure_session_val
89
+ }
90
+ response = await self._post(
91
+ url=self.url_login,
92
+ cookies=self.cookies,
93
+ headers=login_headers,
94
+ data=login_data,
95
+ follow_redirects=True,
96
+ raise_for_status=True,
97
+ use_proxy= False
98
+ )
99
+ csrf_token_match = re.search(r"localStorage\.setItem\('XSRF\.Token','(.*?)'\)", response.text)
100
+ csrf_token = csrf_token_match.group(1) if csrf_token_match else ""
101
+ except Exception as err:
102
+ raise ComponentError(
103
+ f"D2L: Error getting data from URL {err}"
104
+ )
105
+ # Get Bearer Token
106
+ token_headers = {
107
+ "Content-Type": "application/x-www-form-urlencoded",
108
+ "Origin": f"https://{self.domain}",
109
+ "Referer": f"https://{self.domain}/d2l/home",
110
+ "x-csrf-token": csrf_token,
111
+ "User-Agent": random.choice(ua)
112
+ }
113
+ token_data = {"scope": "*:*:*"}
114
+ try:
115
+ response = await self._post(
116
+ url=self.url_token,
117
+ cookies=self.cookies,
118
+ headers=token_headers,
119
+ data=token_data,
120
+ use_proxy= False
121
+ )
122
+ json = response.json()
123
+ with await self.open() as redis:
124
+ current_timestamp = int(datetime.now(timezone.utc).timestamp())
125
+ expires_at = json.get('expires_at', (current_timestamp - 600))
126
+ timeout = expires_at - current_timestamp
127
+ self.setexp('D2L_API_KEY', json.get("access_token", None), f'{timeout}s')
128
+ self.setexp('D2L_SESSION_VAL', d2l_session_val, f'{timeout}s')
129
+ self.setexp('D2L_SECURE_SESSION_VAL', d2l_secure_session_val, f'{timeout}s')
130
+ self.auth['apikey'] = json.get("access_token", None)
131
+ self.headers["Authorization"] = f"Bearer {self.auth.get('apikey')}"
132
+ return self.auth['apikey']
133
+ except Exception as err:
134
+ raise ComponentError(
135
+ f"D2L: Error getting data from URL {err}"
136
+ )
137
+
138
+ async def download_file(self):
139
+ # Get Download URL
140
+ url = f'https://{self.domain}/d2l/api/lp/1.45/datasets/bds/{self.schema}/extracts'
141
+ response = await self.api_get(
142
+ url=url,
143
+ headers=self.headers,
144
+ use_proxy=False
145
+ )
146
+ download_link = ''
147
+ if hasattr(self, "masks") and hasattr(self, 'date'):
148
+ self.date = self.mask_replacement(self.date)
149
+ for obj in response.get('Objects', []):
150
+ if hasattr(self, "date") and self.date:
151
+ target_date = datetime.strptime(self.date, "%Y-%m-%d").date()
152
+ if obj.get("BdsType") == "Differential":
153
+ created_date = datetime.strptime(obj.get("CreatedDate", ""), "%Y-%m-%dT%H:%M:%S.%fZ").date()
154
+ if created_date == target_date:
155
+ download_link = obj.get("DownloadLink")
156
+ break
157
+ else:
158
+ if obj.get('BdsType', '') == 'Full':
159
+ download_link = obj.get('DownloadLink', '')
160
+ break
161
+ # Download ZIP File
162
+ self.download = True
163
+ await self.async_request(
164
+ url=download_link
165
+ )
166
+ return True
167
+
168
+ async def request_iterate(self, endpoint, api=True, **kwargs):
169
+ has_more_items = True
170
+ resultset = []
171
+ bookmark = 0
172
+ if api == True:
173
+ while has_more_items == True:
174
+ url = f'https://{self.domain}/d2l/api{endpoint}/?bookmark={bookmark}'
175
+ response = await self.api_get(
176
+ url=url,
177
+ headers=self.headers,
178
+ use_proxy= False
179
+ )
180
+ if not response['Items']:
181
+ break
182
+ else:
183
+ bookmark = response['PagingInfo']['Bookmark']
184
+ has_more_items = response['PagingInfo']['HasMoreItems']
185
+ resultset = [*resultset, *response['Items']]
186
+ #break
187
+ return resultset
188
+ else:
189
+ item = kwargs.get('item', '')
190
+ while has_more_items == True:
191
+ url = f'https://{self.domain}/d2l{endpoint}/?limit=100&offset={bookmark}'
192
+ try:
193
+ response = await self.api_get(
194
+ url=url,
195
+ headers=self.headers,
196
+ cookies=self.cookies,
197
+ use_proxy= False
198
+ )
199
+ if not response[item]:
200
+ break
201
+ else:
202
+ bookmark += 100
203
+ has_more_items = response['Metadata']['HasMore']
204
+ resultset = [*resultset, *response[item]]
205
+ #break
206
+ except Exception:
207
+ break
208
+ return resultset
209
+
210
+ async def awards(self, org_units=None):
211
+ result = []
212
+
213
+ if org_units is None:
214
+ org_units = await self.request_iterate('/lp/1.49/orgstructure', True)
215
+ org_units = [item["Identifier"] for item in org_units["Items"]]
216
+
217
+ for org_unit_id in org_units:
218
+ users = await self.request_iterate(f'/awards/v1/{org_unit_id}/classlist', False, item='Users')
219
+ for user in users:
220
+ user_id = user['UserId']
221
+ org_unit_id = user['OrgUnitId']
222
+
223
+ if user['Paging'].get('HasMore', False) == True:
224
+ awards = await self.request_iterate(f'/awards/v1/{org_unit_id}/myAwards/{user_id}', False, item='Awards')
225
+ else:
226
+ awards = user['Awards']
227
+
228
+ for award in awards:
229
+ result.append({
230
+ 'award_id': award['AwardId'],
231
+ 'user_id': user_id,
232
+ 'org_unit_id': org_unit_id,
233
+ 'certificate_id': award['CertificateId'],
234
+ 'achievement_id': award['AchievementId'],
235
+ 'achievement': award['Achievement'].get('Title ', None),
236
+ 'awarded_by': award['AwardedBy'],
237
+ 'issue_date': award['IssueDate'][14:-1]
238
+ })
239
+ return result
@@ -0,0 +1,5 @@
1
+ from .db import DBSupport
2
+
3
+ __all__ = (
4
+ "DBSupport",
5
+ )
@@ -0,0 +1,223 @@
1
+ from typing import Optional
2
+ import asyncio
3
+ import pandas
4
+ from asyncdb import AsyncDB
5
+ from navconfig.logging import logging
6
+ from querysource.conf import asyncpg_url, default_dsn
7
+ from ..credentials import CredentialsInterface
8
+ from ...utils.functions import is_empty, as_boolean
9
+ from ...exceptions import DataNotFound
10
+
11
+
12
+ class DBSupport(CredentialsInterface):
13
+ """DBSupport.
14
+
15
+ Interface for adding AsyncbDB-based Database Support to Components.
16
+ """
17
+ _service_name: str = 'Flowtask'
18
+ _credentials = {
19
+ "user": str,
20
+ "password": str,
21
+ "host": str,
22
+ "port": int,
23
+ "database": str,
24
+ }
25
+
26
+ def __init__(
27
+ self,
28
+ *args,
29
+ **kwargs
30
+ ):
31
+ self.as_dataframe: bool = as_boolean(kwargs.get("as_dataframe", False))
32
+ # using "string" instead objects in pandas
33
+ self.as_string: bool = as_boolean(kwargs.get("as_string", False))
34
+ # Infer types:
35
+ self.infer_types: bool = as_boolean(kwargs.get("infer_types", False))
36
+ if not hasattr(self, '_logger'):
37
+ self._logger = logging.getLogger(
38
+ 'Flowtask.DBSupport'
39
+ )
40
+ super().__init__(*args, **kwargs)
41
+
42
+ def event_loop(
43
+ self, evt: Optional[asyncio.AbstractEventLoop] = None
44
+ ) -> asyncio.AbstractEventLoop:
45
+ if evt is not None:
46
+ asyncio.set_event_loop(evt)
47
+ return evt
48
+ else:
49
+ try:
50
+ return asyncio.get_event_loop()
51
+ except RuntimeError as exc:
52
+ try:
53
+ evt = asyncio.new_event_loop()
54
+ asyncio.set_event_loop(evt)
55
+ return evt
56
+ except RuntimeError as exc:
57
+ raise RuntimeError(
58
+ f"There is no Event Loop: {exc}"
59
+ ) from exc
60
+
61
+ def get_connection(
62
+ self,
63
+ driver: str = "pg",
64
+ dsn: Optional[str] = None,
65
+ params: Optional[dict] = None,
66
+ event_loop: Optional[asyncio.AbstractEventLoop] = None,
67
+ **kwargs,
68
+ ):
69
+ # TODO: datasources and credentials
70
+ if not kwargs and driver == "pg":
71
+ kwargs = {
72
+ "server_settings": {
73
+ "application_name": f"{self._service_name}.DB",
74
+ "client_min_messages": "notice",
75
+ "max_parallel_workers": "512",
76
+ "jit": "on",
77
+ }
78
+ }
79
+ if not event_loop:
80
+ event_loop = self.event_loop()
81
+ args = {
82
+ "loop": event_loop,
83
+ **kwargs
84
+ }
85
+ if dsn is not None:
86
+ args["dsn"] = dsn
87
+ if params:
88
+ args["params"] = params
89
+ return AsyncDB(
90
+ driver, **args
91
+ )
92
+
93
+ def db_connection(
94
+ self,
95
+ driver: str = "pg",
96
+ credentials: Optional[dict] = None,
97
+ event_loop: Optional[asyncio.AbstractEventLoop] = None,
98
+ ):
99
+ if not credentials:
100
+ credentials = {"dsn": default_dsn}
101
+ else:
102
+ credentials = {"params": credentials}
103
+ kwargs = {}
104
+ if driver == "pg":
105
+ kwargs = {
106
+ "server_settings": {
107
+ "application_name": f"{self._service_name}.DB",
108
+ "client_min_messages": "notice",
109
+ "max_parallel_workers": "512",
110
+ "jit": "on",
111
+ }
112
+ }
113
+ if not event_loop:
114
+ event_loop = self.event_loop()
115
+ return AsyncDB(
116
+ driver,
117
+ loop=event_loop,
118
+ **credentials,
119
+ **kwargs
120
+ )
121
+
122
+ def pg_connection(
123
+ self,
124
+ dsn: Optional[str] = None,
125
+ credentials: Optional[dict] = None,
126
+ event_loop: Optional[asyncio.AbstractEventLoop] = None,
127
+ ):
128
+ if not credentials:
129
+ if dsn is not None:
130
+ credentials = {"dsn": dsn}
131
+ else:
132
+ credentials = {"dsn": asyncpg_url}
133
+ else:
134
+ credentials = {"params": credentials}
135
+ kwargs: dict = {
136
+ "min_size": 2,
137
+ "server_settings": {
138
+ "application_name": f"{self._service_name}.DB",
139
+ "client_min_messages": "notice",
140
+ "max_parallel_workers": "512",
141
+ "jit": "on",
142
+ },
143
+ }
144
+ if not event_loop:
145
+ event_loop = self.event_loop()
146
+ return AsyncDB(
147
+ "pg",
148
+ loop=event_loop, **credentials, **kwargs
149
+ )
150
+
151
+ def get_default_driver(self, driver: str):
152
+ """get_default_driver.
153
+
154
+ Getting a default connection based on driver's name.
155
+ """
156
+ driver_path = f"querysource.datasources.drivers.{driver}"
157
+ drv = f"{driver}_default"
158
+ try:
159
+ driver_module = __import__(driver_path, fromlist=[driver])
160
+ drv_obj = getattr(driver_module, drv)
161
+ return drv_obj
162
+ except ImportError as err:
163
+ raise ImportError(
164
+ f"Error importing driver: {err!s}"
165
+ ) from err
166
+ except AttributeError as err:
167
+ raise AttributeError(
168
+ f"Error getting driver: {err!s}"
169
+ ) from err
170
+ except Exception as err:
171
+ raise Exception(
172
+ f"Error getting default connection: {err!s}"
173
+ ) from err
174
+
175
+ def default_connection(self, driver: str):
176
+ """default_connection.
177
+
178
+ Default Connection to Database.
179
+ """
180
+ credentials = {}
181
+ try:
182
+ driver = self.get_default_driver(driver)
183
+ credentials = driver.params()
184
+ if driver.driver == 'pg' and credentials.get('username', None) is not None:
185
+ credentials['user'] = credentials.pop('username')
186
+ except ImportError as err:
187
+ raise ImportError(
188
+ f"Error importing Default driver: {err!s}"
189
+ ) from err
190
+ try:
191
+ return self.get_connection(
192
+ driver=driver.driver,
193
+ params=credentials
194
+ )
195
+ except Exception as err:
196
+ raise Exception(
197
+ f"Error getting Default Connection: {err!s}"
198
+ ) from err
199
+
200
+ async def get_dataframe(self, result):
201
+ try:
202
+ df = pandas.DataFrame(result)
203
+ except Exception as err: # pylint: disable=W0703
204
+ logging.exception(err, stack_info=True)
205
+ # Attempt to infer better dtypes for object columns.
206
+ if is_empty(df):
207
+ raise DataNotFound("DbClient: Data not Found")
208
+ df.infer_objects()
209
+ if self.infer_types is True:
210
+ df = df.convert_dtypes(convert_string=self.as_string)
211
+ if self._debug is True:
212
+ print(df.dtypes)
213
+ if hasattr(self, "drop_empty"):
214
+ df.dropna(axis=1, how="all", inplace=True)
215
+ df.dropna(axis=0, how="all", inplace=True)
216
+ if hasattr(self, "dropna"):
217
+ df.dropna(subset=self.dropna, how="all", inplace=True)
218
+ if (
219
+ hasattr(self, "clean_strings") and getattr(self, "clean_strings", False) is True
220
+ ):
221
+ u = df.select_dtypes(include=["object", "string"])
222
+ df[u.columns] = u.fillna("")
223
+ return df
@@ -0,0 +1,55 @@
1
+ from typing import Optional
2
+ from querysource.conf import (
3
+ DOCUMENTDB_HOSTNAME,
4
+ DOCUMENTDB_PORT,
5
+ DOCUMENTDB_DATABASE,
6
+ DOCUMENTDB_USERNAME,
7
+ DOCUMENTDB_PASSWORD,
8
+ DOCUMENTDB_TLSFILE,
9
+ )
10
+ from .db import DBSupport
11
+
12
+
13
+ class DocumentDBSupport(DBSupport):
14
+ """DocumentDBSupport.
15
+
16
+ Interface for adding AWS DocumentDB Database Support to Components.
17
+ """
18
+ _service_name: str = 'Flowtask'
19
+ driver: str = 'mongo'
20
+ _credentials = {
21
+ "host": str,
22
+ "port": int,
23
+ "username": str,
24
+ "password": str,
25
+ "database": str,
26
+ "dbtype": "documentdb",
27
+ "ssl": True,
28
+ "tlsCAFile": str,
29
+ }
30
+
31
+ def default_connection(self, driver: str = 'mongo', credentials: Optional[dict] = None):
32
+ """default_connection.
33
+
34
+ Default Connection to RethinkDB.
35
+ """
36
+ if not credentials:
37
+ credentials = {
38
+ "host": DOCUMENTDB_HOSTNAME,
39
+ "port": DOCUMENTDB_PORT,
40
+ "username": DOCUMENTDB_USERNAME,
41
+ "password": DOCUMENTDB_PASSWORD,
42
+ "database": DOCUMENTDB_DATABASE,
43
+ "dbtype": "documentdb",
44
+ "ssl": True,
45
+ "tlsCAFile": DOCUMENTDB_TLSFILE,
46
+ }
47
+ try:
48
+ return self.get_connection(
49
+ driver=driver,
50
+ params=credentials
51
+ )
52
+ except Exception as err:
53
+ raise Exception(
54
+ f"Error getting Default DocumentDB Connection: {err!s}"
55
+ ) from err
@@ -0,0 +1,39 @@
1
+ from .db import DBSupport
2
+
3
+
4
+ class RethinkDBSupport(DBSupport):
5
+ """RethinkDBSupport.
6
+
7
+ Interface for adding RethinkDB-based Database Support to Components.
8
+ """
9
+ _service_name: str = 'Flowtask'
10
+ _credentials = {
11
+ "user": str,
12
+ "password": str,
13
+ "host": str,
14
+ "port": int,
15
+ "database": str,
16
+ }
17
+
18
+ def default_connection(self, driver: str = 'rethink'):
19
+ """default_connection.
20
+
21
+ Default Connection to RethinkDB.
22
+ """
23
+ credentials = {}
24
+ try:
25
+ driver = self.get_default_driver(driver)
26
+ credentials = driver.params()
27
+ except ImportError as err:
28
+ raise ImportError(
29
+ f"Error importing RethinkDB driver: {err!s}"
30
+ ) from err
31
+ try:
32
+ return self.get_connection(
33
+ driver=driver.driver,
34
+ params=credentials
35
+ )
36
+ except Exception as err:
37
+ raise Exception(
38
+ f"Error getting Default Rethink Connection: {err!s}"
39
+ ) from err
@@ -0,0 +1,11 @@
1
+ from .pandas import PandasDataframe
2
+ from .polars import PolarsDataframe
3
+ from .arrow import ArrowDataframe
4
+ from .dt import DtDataframe
5
+
6
+ __all__ = (
7
+ "PandasDataframe",
8
+ "PolarsDataframe",
9
+ "ArrowDataframe",
10
+ "DtDataframe",
11
+ )
@@ -0,0 +1,21 @@
1
+ from typing import Any, Union, ParamSpec
2
+ from abc import ABC, abstractmethod
3
+ from navconfig.logging import logging
4
+
5
+
6
+ P = ParamSpec("P")
7
+
8
+
9
+ class BaseDataframe(ABC):
10
+
11
+ @abstractmethod
12
+ async def create_dataframe(
13
+ self, result: Union[dict, bytes, Any], *args: P.args, **kwargs: P.kwargs
14
+ ) -> Any:
15
+ """
16
+ Converts any result into a DataFrame.
17
+
18
+ :param result: The result data to be converted into a DataFrame.
19
+ :return: A DataFrame containing the result data.
20
+ """
21
+ pass
@@ -0,0 +1,71 @@
1
+ from typing import Union, Any, ParamSpec
2
+ import pandas as pd
3
+ import orjson
4
+ import pyarrow as pa
5
+ import pyarrow.csv as pc
6
+ import pyarrow.parquet as pq
7
+ from io import BytesIO
8
+ from .abstract import BaseDataframe
9
+ from ...exceptions import ComponentError, DataNotFound
10
+
11
+
12
+ P = ParamSpec("P")
13
+
14
+
15
+ def is_empty(obj):
16
+ """check_empty.
17
+ Check if a basic object, a Apache Arrow Table is empty or not.
18
+ """
19
+ if isinstance(obj, pa.Table):
20
+ return obj.num_rows == 0
21
+ else:
22
+ return bool(not obj)
23
+
24
+
25
+ class ArrowDataframe(BaseDataframe):
26
+ """ArrowDataframe.
27
+
28
+ Converts any result into a Arrow DataFrame.
29
+ """
30
+
31
+ async def create_dataframe(
32
+ self, result: Union[dict, bytes, Any], *args: P.args, **kwargs: P.kwargs
33
+ ) -> Any:
34
+ """
35
+ Converts any result into a Arrow DataFrame.
36
+
37
+ :param result: The result data to be converted into a Arrow DataFrame.
38
+ :return: A DataFrame containing the result data.
39
+ """
40
+ if is_empty(result):
41
+ raise DataNotFound("DataFrame: No Data was Found.")
42
+ try:
43
+ if isinstance(result, str):
44
+ try:
45
+ result = orjson.loads(result)
46
+ except Exception:
47
+ pass
48
+ if isinstance(result, list):
49
+ names = list(result[0].keys())
50
+ df = pa.Table.from_arrays(result, names=names, **kwargs)
51
+ elif isinstance(result, bytes) or isinstance(result, BytesIO):
52
+ try:
53
+ # Reset the pointer to the start of the stream
54
+ result.seek(0)
55
+ df = pc.read_csv(result, **kwargs)
56
+ except pa.lib.ArrowInvalid as e:
57
+ # Use pyarrow.parquet.read_table to read Parquet data
58
+ df = pq.read_table(result)
59
+ else:
60
+ df = pa.Table.from_pandas(pd.DataFrame(result, **kwargs))
61
+ numrows = df.num_rows
62
+ numcols = df.num_columns
63
+ try:
64
+ self._variables["_numRows_"] = numrows
65
+ self.add_metric("NUM_ROWS", numrows)
66
+ self.add_metric("NUM_COLS", numcols)
67
+ except Exception:
68
+ pass
69
+ return df
70
+ except Exception as err:
71
+ raise ComponentError(f"Error Creating Dataframe: {err!s}")