flowtask 5.8.4__cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (470) hide show
  1. flowtask/__init__.py +93 -0
  2. flowtask/__main__.py +38 -0
  3. flowtask/bots/__init__.py +6 -0
  4. flowtask/bots/check.py +93 -0
  5. flowtask/bots/codebot.py +51 -0
  6. flowtask/components/ASPX.py +148 -0
  7. flowtask/components/AddDataset.py +352 -0
  8. flowtask/components/Amazon.py +523 -0
  9. flowtask/components/AutoTask.py +314 -0
  10. flowtask/components/Azure.py +80 -0
  11. flowtask/components/AzureUsers.py +106 -0
  12. flowtask/components/BaseAction.py +91 -0
  13. flowtask/components/BaseLoop.py +198 -0
  14. flowtask/components/BestBuy.py +800 -0
  15. flowtask/components/CSVToGCS.py +120 -0
  16. flowtask/components/CompanyScraper/__init__.py +1 -0
  17. flowtask/components/CompanyScraper/parsers/__init__.py +6 -0
  18. flowtask/components/CompanyScraper/parsers/base.py +102 -0
  19. flowtask/components/CompanyScraper/parsers/explorium.py +192 -0
  20. flowtask/components/CompanyScraper/parsers/leadiq.py +206 -0
  21. flowtask/components/CompanyScraper/parsers/rocket.py +133 -0
  22. flowtask/components/CompanyScraper/parsers/siccode.py +109 -0
  23. flowtask/components/CompanyScraper/parsers/visualvisitor.py +130 -0
  24. flowtask/components/CompanyScraper/parsers/zoominfo.py +118 -0
  25. flowtask/components/CompanyScraper/scrapper.py +1054 -0
  26. flowtask/components/CopyTo.py +177 -0
  27. flowtask/components/CopyToBigQuery.py +243 -0
  28. flowtask/components/CopyToMongoDB.py +291 -0
  29. flowtask/components/CopyToPg.py +609 -0
  30. flowtask/components/CopyToRethink.py +207 -0
  31. flowtask/components/CreateGCSBucket.py +102 -0
  32. flowtask/components/CreateReport/CreateReport.py +228 -0
  33. flowtask/components/CreateReport/__init__.py +9 -0
  34. flowtask/components/CreateReport/charts/__init__.py +15 -0
  35. flowtask/components/CreateReport/charts/bar.py +51 -0
  36. flowtask/components/CreateReport/charts/base.py +66 -0
  37. flowtask/components/CreateReport/charts/pie.py +64 -0
  38. flowtask/components/CreateReport/utils.py +9 -0
  39. flowtask/components/CustomerSatisfaction.py +196 -0
  40. flowtask/components/DataInput.py +200 -0
  41. flowtask/components/DateList.py +255 -0
  42. flowtask/components/DbClient.py +163 -0
  43. flowtask/components/DialPad.py +146 -0
  44. flowtask/components/DocumentDBQuery.py +200 -0
  45. flowtask/components/DownloadFrom.py +371 -0
  46. flowtask/components/DownloadFromD2L.py +113 -0
  47. flowtask/components/DownloadFromFTP.py +181 -0
  48. flowtask/components/DownloadFromIMAP.py +315 -0
  49. flowtask/components/DownloadFromS3.py +198 -0
  50. flowtask/components/DownloadFromSFTP.py +265 -0
  51. flowtask/components/DownloadFromSharepoint.py +110 -0
  52. flowtask/components/DownloadFromSmartSheet.py +114 -0
  53. flowtask/components/DownloadS3File.py +229 -0
  54. flowtask/components/Dummy.py +59 -0
  55. flowtask/components/DuplicatePhoto.py +411 -0
  56. flowtask/components/EmployeeEvaluation.py +237 -0
  57. flowtask/components/ExecuteSQL.py +323 -0
  58. flowtask/components/ExtractHTML.py +178 -0
  59. flowtask/components/FileBase.py +178 -0
  60. flowtask/components/FileCopy.py +181 -0
  61. flowtask/components/FileDelete.py +82 -0
  62. flowtask/components/FileExists.py +146 -0
  63. flowtask/components/FileIteratorDelete.py +112 -0
  64. flowtask/components/FileList.py +194 -0
  65. flowtask/components/FileOpen.py +75 -0
  66. flowtask/components/FileRead.py +120 -0
  67. flowtask/components/FileRename.py +106 -0
  68. flowtask/components/FilterIf.py +284 -0
  69. flowtask/components/FilterRows/FilterRows.py +200 -0
  70. flowtask/components/FilterRows/__init__.py +10 -0
  71. flowtask/components/FilterRows/functions.py +4 -0
  72. flowtask/components/GCSToBigQuery.py +103 -0
  73. flowtask/components/GoogleA4.py +150 -0
  74. flowtask/components/GoogleGeoCoding.py +344 -0
  75. flowtask/components/GooglePlaces.py +315 -0
  76. flowtask/components/GoogleSearch.py +539 -0
  77. flowtask/components/HTTPClient.py +268 -0
  78. flowtask/components/ICIMS.py +146 -0
  79. flowtask/components/IF.py +179 -0
  80. flowtask/components/IcimsFolderCopy.py +173 -0
  81. flowtask/components/ImageFeatures/__init__.py +5 -0
  82. flowtask/components/ImageFeatures/process.py +233 -0
  83. flowtask/components/IteratorBase.py +251 -0
  84. flowtask/components/LangchainLoader/__init__.py +5 -0
  85. flowtask/components/LangchainLoader/loader.py +194 -0
  86. flowtask/components/LangchainLoader/loaders/__init__.py +22 -0
  87. flowtask/components/LangchainLoader/loaders/abstract.py +362 -0
  88. flowtask/components/LangchainLoader/loaders/basepdf.py +50 -0
  89. flowtask/components/LangchainLoader/loaders/docx.py +91 -0
  90. flowtask/components/LangchainLoader/loaders/html.py +119 -0
  91. flowtask/components/LangchainLoader/loaders/pdfblocks.py +146 -0
  92. flowtask/components/LangchainLoader/loaders/pdfmark.py +79 -0
  93. flowtask/components/LangchainLoader/loaders/pdftables.py +135 -0
  94. flowtask/components/LangchainLoader/loaders/qa.py +67 -0
  95. flowtask/components/LangchainLoader/loaders/txt.py +55 -0
  96. flowtask/components/LeadIQ.py +650 -0
  97. flowtask/components/Loop.py +253 -0
  98. flowtask/components/Lowes.py +334 -0
  99. flowtask/components/MS365Usage.py +156 -0
  100. flowtask/components/MSTeamsMessages.py +320 -0
  101. flowtask/components/MarketClustering.py +1051 -0
  102. flowtask/components/MergeFiles.py +362 -0
  103. flowtask/components/MilvusOutput.py +87 -0
  104. flowtask/components/NearByStores.py +175 -0
  105. flowtask/components/NetworkNinja/__init__.py +6 -0
  106. flowtask/components/NetworkNinja/models/__init__.py +52 -0
  107. flowtask/components/NetworkNinja/models/abstract.py +177 -0
  108. flowtask/components/NetworkNinja/models/account.py +39 -0
  109. flowtask/components/NetworkNinja/models/client.py +19 -0
  110. flowtask/components/NetworkNinja/models/district.py +14 -0
  111. flowtask/components/NetworkNinja/models/events.py +101 -0
  112. flowtask/components/NetworkNinja/models/forms.py +499 -0
  113. flowtask/components/NetworkNinja/models/market.py +16 -0
  114. flowtask/components/NetworkNinja/models/organization.py +34 -0
  115. flowtask/components/NetworkNinja/models/photos.py +125 -0
  116. flowtask/components/NetworkNinja/models/project.py +44 -0
  117. flowtask/components/NetworkNinja/models/region.py +28 -0
  118. flowtask/components/NetworkNinja/models/store.py +203 -0
  119. flowtask/components/NetworkNinja/models/user.py +151 -0
  120. flowtask/components/NetworkNinja/router.py +854 -0
  121. flowtask/components/Odoo.py +175 -0
  122. flowtask/components/OdooInjector.py +192 -0
  123. flowtask/components/OpenFromXML.py +126 -0
  124. flowtask/components/OpenWeather.py +41 -0
  125. flowtask/components/OpenWithBase.py +616 -0
  126. flowtask/components/OpenWithPandas.py +715 -0
  127. flowtask/components/PGPDecrypt.py +199 -0
  128. flowtask/components/PandasIterator.py +187 -0
  129. flowtask/components/PandasToFile.py +189 -0
  130. flowtask/components/Paradox.py +339 -0
  131. flowtask/components/ParamIterator.py +117 -0
  132. flowtask/components/ParseHTML.py +84 -0
  133. flowtask/components/PlacerStores.py +249 -0
  134. flowtask/components/Pokemon.py +507 -0
  135. flowtask/components/PositiveBot.py +62 -0
  136. flowtask/components/PowerPointSlide.py +400 -0
  137. flowtask/components/PrintMessage.py +127 -0
  138. flowtask/components/ProductCompetitors/__init__.py +5 -0
  139. flowtask/components/ProductCompetitors/parsers/__init__.py +7 -0
  140. flowtask/components/ProductCompetitors/parsers/base.py +72 -0
  141. flowtask/components/ProductCompetitors/parsers/bestbuy.py +86 -0
  142. flowtask/components/ProductCompetitors/parsers/lowes.py +103 -0
  143. flowtask/components/ProductCompetitors/scrapper.py +155 -0
  144. flowtask/components/ProductCompliant.py +169 -0
  145. flowtask/components/ProductInfo/__init__.py +1 -0
  146. flowtask/components/ProductInfo/parsers/__init__.py +5 -0
  147. flowtask/components/ProductInfo/parsers/base.py +83 -0
  148. flowtask/components/ProductInfo/parsers/brother.py +97 -0
  149. flowtask/components/ProductInfo/parsers/canon.py +167 -0
  150. flowtask/components/ProductInfo/parsers/epson.py +118 -0
  151. flowtask/components/ProductInfo/parsers/hp.py +131 -0
  152. flowtask/components/ProductInfo/parsers/samsung.py +97 -0
  153. flowtask/components/ProductInfo/scraper.py +319 -0
  154. flowtask/components/ProductPricing.py +118 -0
  155. flowtask/components/QS.py +261 -0
  156. flowtask/components/QSBase.py +201 -0
  157. flowtask/components/QueryIterator.py +273 -0
  158. flowtask/components/QueryToInsert.py +327 -0
  159. flowtask/components/QueryToPandas.py +432 -0
  160. flowtask/components/RESTClient.py +195 -0
  161. flowtask/components/RethinkDBQuery.py +189 -0
  162. flowtask/components/Rsync.py +74 -0
  163. flowtask/components/RunSSH.py +59 -0
  164. flowtask/components/RunShell.py +71 -0
  165. flowtask/components/SalesForce.py +20 -0
  166. flowtask/components/SaveImageBank/__init__.py +257 -0
  167. flowtask/components/SchedulingVisits.py +592 -0
  168. flowtask/components/ScrapPage.py +216 -0
  169. flowtask/components/ScrapSearch.py +79 -0
  170. flowtask/components/SendNotify.py +257 -0
  171. flowtask/components/SentimentAnalysis.py +694 -0
  172. flowtask/components/ServiceScrapper/__init__.py +5 -0
  173. flowtask/components/ServiceScrapper/parsers/__init__.py +1 -0
  174. flowtask/components/ServiceScrapper/parsers/base.py +94 -0
  175. flowtask/components/ServiceScrapper/parsers/costco.py +93 -0
  176. flowtask/components/ServiceScrapper/scrapper.py +199 -0
  177. flowtask/components/SetVariables.py +156 -0
  178. flowtask/components/SubTask.py +182 -0
  179. flowtask/components/SuiteCRM.py +48 -0
  180. flowtask/components/Switch.py +175 -0
  181. flowtask/components/TableBase.py +148 -0
  182. flowtask/components/TableDelete.py +312 -0
  183. flowtask/components/TableInput.py +143 -0
  184. flowtask/components/TableOutput/TableOutput.py +384 -0
  185. flowtask/components/TableOutput/__init__.py +3 -0
  186. flowtask/components/TableSchema.py +534 -0
  187. flowtask/components/Target.py +223 -0
  188. flowtask/components/ThumbnailGenerator.py +156 -0
  189. flowtask/components/ToPandas.py +67 -0
  190. flowtask/components/TransformRows/TransformRows.py +507 -0
  191. flowtask/components/TransformRows/__init__.py +9 -0
  192. flowtask/components/TransformRows/functions.py +559 -0
  193. flowtask/components/TransposeRows.py +176 -0
  194. flowtask/components/UPCDatabase.py +86 -0
  195. flowtask/components/UnGzip.py +171 -0
  196. flowtask/components/Uncompress.py +172 -0
  197. flowtask/components/UniqueRows.py +126 -0
  198. flowtask/components/Unzip.py +107 -0
  199. flowtask/components/UpdateOperationalVars.py +147 -0
  200. flowtask/components/UploadTo.py +299 -0
  201. flowtask/components/UploadToS3.py +136 -0
  202. flowtask/components/UploadToSFTP.py +160 -0
  203. flowtask/components/UploadToSharepoint.py +205 -0
  204. flowtask/components/UserFunc.py +122 -0
  205. flowtask/components/VivaTracker.py +140 -0
  206. flowtask/components/WSDLClient.py +123 -0
  207. flowtask/components/Wait.py +18 -0
  208. flowtask/components/Walmart.py +199 -0
  209. flowtask/components/Workplace.py +134 -0
  210. flowtask/components/XMLToPandas.py +267 -0
  211. flowtask/components/Zammad/__init__.py +41 -0
  212. flowtask/components/Zammad/models.py +0 -0
  213. flowtask/components/ZoomInfoScraper.py +409 -0
  214. flowtask/components/__init__.py +104 -0
  215. flowtask/components/abstract.py +18 -0
  216. flowtask/components/flow.py +530 -0
  217. flowtask/components/google.py +335 -0
  218. flowtask/components/group.py +221 -0
  219. flowtask/components/py.typed +0 -0
  220. flowtask/components/reviewscrap.py +132 -0
  221. flowtask/components/tAutoincrement.py +117 -0
  222. flowtask/components/tConcat.py +109 -0
  223. flowtask/components/tExplode.py +119 -0
  224. flowtask/components/tFilter.py +184 -0
  225. flowtask/components/tGroup.py +236 -0
  226. flowtask/components/tJoin.py +270 -0
  227. flowtask/components/tMap/__init__.py +9 -0
  228. flowtask/components/tMap/functions.py +54 -0
  229. flowtask/components/tMap/tMap.py +450 -0
  230. flowtask/components/tMelt.py +112 -0
  231. flowtask/components/tMerge.py +114 -0
  232. flowtask/components/tOrder.py +93 -0
  233. flowtask/components/tPandas.py +94 -0
  234. flowtask/components/tPivot.py +71 -0
  235. flowtask/components/tPluckCols.py +76 -0
  236. flowtask/components/tUnnest.py +82 -0
  237. flowtask/components/user.py +401 -0
  238. flowtask/conf.py +457 -0
  239. flowtask/download.py +102 -0
  240. flowtask/events/__init__.py +11 -0
  241. flowtask/events/events/__init__.py +20 -0
  242. flowtask/events/events/abstract.py +95 -0
  243. flowtask/events/events/alerts/__init__.py +362 -0
  244. flowtask/events/events/alerts/colfunctions.py +131 -0
  245. flowtask/events/events/alerts/functions.py +158 -0
  246. flowtask/events/events/dummy.py +12 -0
  247. flowtask/events/events/exec.py +124 -0
  248. flowtask/events/events/file/__init__.py +7 -0
  249. flowtask/events/events/file/base.py +51 -0
  250. flowtask/events/events/file/copy.py +23 -0
  251. flowtask/events/events/file/delete.py +16 -0
  252. flowtask/events/events/interfaces/__init__.py +9 -0
  253. flowtask/events/events/interfaces/client.py +67 -0
  254. flowtask/events/events/interfaces/credentials.py +28 -0
  255. flowtask/events/events/interfaces/notifications.py +58 -0
  256. flowtask/events/events/jira.py +122 -0
  257. flowtask/events/events/log.py +26 -0
  258. flowtask/events/events/logerr.py +52 -0
  259. flowtask/events/events/notify.py +59 -0
  260. flowtask/events/events/notify_event.py +160 -0
  261. flowtask/events/events/publish.py +54 -0
  262. flowtask/events/events/sendfile.py +104 -0
  263. flowtask/events/events/task.py +97 -0
  264. flowtask/events/events/teams.py +98 -0
  265. flowtask/events/events/webhook.py +58 -0
  266. flowtask/events/manager.py +287 -0
  267. flowtask/exceptions.c +39393 -0
  268. flowtask/exceptions.cpython-39-x86_64-linux-gnu.so +0 -0
  269. flowtask/extensions/__init__.py +3 -0
  270. flowtask/extensions/abstract.py +82 -0
  271. flowtask/extensions/logging/__init__.py +65 -0
  272. flowtask/hooks/__init__.py +9 -0
  273. flowtask/hooks/actions/__init__.py +22 -0
  274. flowtask/hooks/actions/abstract.py +66 -0
  275. flowtask/hooks/actions/dummy.py +23 -0
  276. flowtask/hooks/actions/jira.py +74 -0
  277. flowtask/hooks/actions/rest.py +320 -0
  278. flowtask/hooks/actions/sampledata.py +37 -0
  279. flowtask/hooks/actions/sensor.py +23 -0
  280. flowtask/hooks/actions/task.py +9 -0
  281. flowtask/hooks/actions/ticket.py +37 -0
  282. flowtask/hooks/actions/zammad.py +55 -0
  283. flowtask/hooks/hook.py +62 -0
  284. flowtask/hooks/models.py +17 -0
  285. flowtask/hooks/service.py +187 -0
  286. flowtask/hooks/step.py +91 -0
  287. flowtask/hooks/types/__init__.py +23 -0
  288. flowtask/hooks/types/base.py +129 -0
  289. flowtask/hooks/types/brokers/__init__.py +11 -0
  290. flowtask/hooks/types/brokers/base.py +54 -0
  291. flowtask/hooks/types/brokers/mqtt.py +35 -0
  292. flowtask/hooks/types/brokers/rabbitmq.py +82 -0
  293. flowtask/hooks/types/brokers/redis.py +83 -0
  294. flowtask/hooks/types/brokers/sqs.py +44 -0
  295. flowtask/hooks/types/fs.py +232 -0
  296. flowtask/hooks/types/http.py +49 -0
  297. flowtask/hooks/types/imap.py +200 -0
  298. flowtask/hooks/types/jira.py +279 -0
  299. flowtask/hooks/types/mail.py +205 -0
  300. flowtask/hooks/types/postgres.py +98 -0
  301. flowtask/hooks/types/responses/__init__.py +8 -0
  302. flowtask/hooks/types/responses/base.py +5 -0
  303. flowtask/hooks/types/sharepoint.py +288 -0
  304. flowtask/hooks/types/ssh.py +141 -0
  305. flowtask/hooks/types/tagged.py +59 -0
  306. flowtask/hooks/types/upload.py +85 -0
  307. flowtask/hooks/types/watch.py +71 -0
  308. flowtask/hooks/types/web.py +36 -0
  309. flowtask/interfaces/AzureClient.py +137 -0
  310. flowtask/interfaces/AzureGraph.py +839 -0
  311. flowtask/interfaces/Boto3Client.py +326 -0
  312. flowtask/interfaces/DropboxClient.py +173 -0
  313. flowtask/interfaces/ExcelHandler.py +94 -0
  314. flowtask/interfaces/FTPClient.py +131 -0
  315. flowtask/interfaces/GoogleCalendar.py +201 -0
  316. flowtask/interfaces/GoogleClient.py +133 -0
  317. flowtask/interfaces/GoogleDrive.py +127 -0
  318. flowtask/interfaces/GoogleGCS.py +89 -0
  319. flowtask/interfaces/GoogleGeocoding.py +93 -0
  320. flowtask/interfaces/GoogleLang.py +114 -0
  321. flowtask/interfaces/GooglePub.py +61 -0
  322. flowtask/interfaces/GoogleSheet.py +68 -0
  323. flowtask/interfaces/IMAPClient.py +137 -0
  324. flowtask/interfaces/O365Calendar.py +113 -0
  325. flowtask/interfaces/O365Client.py +220 -0
  326. flowtask/interfaces/OneDrive.py +284 -0
  327. flowtask/interfaces/Outlook.py +155 -0
  328. flowtask/interfaces/ParrotBot.py +130 -0
  329. flowtask/interfaces/SSHClient.py +378 -0
  330. flowtask/interfaces/Sharepoint.py +496 -0
  331. flowtask/interfaces/__init__.py +36 -0
  332. flowtask/interfaces/azureauth.py +119 -0
  333. flowtask/interfaces/cache.py +201 -0
  334. flowtask/interfaces/client.py +82 -0
  335. flowtask/interfaces/compress.py +525 -0
  336. flowtask/interfaces/credentials.py +124 -0
  337. flowtask/interfaces/d2l.py +239 -0
  338. flowtask/interfaces/databases/__init__.py +5 -0
  339. flowtask/interfaces/databases/db.py +223 -0
  340. flowtask/interfaces/databases/documentdb.py +55 -0
  341. flowtask/interfaces/databases/rethink.py +39 -0
  342. flowtask/interfaces/dataframes/__init__.py +11 -0
  343. flowtask/interfaces/dataframes/abstract.py +21 -0
  344. flowtask/interfaces/dataframes/arrow.py +71 -0
  345. flowtask/interfaces/dataframes/dt.py +69 -0
  346. flowtask/interfaces/dataframes/pandas.py +167 -0
  347. flowtask/interfaces/dataframes/polars.py +60 -0
  348. flowtask/interfaces/db.py +263 -0
  349. flowtask/interfaces/env.py +46 -0
  350. flowtask/interfaces/func.py +137 -0
  351. flowtask/interfaces/http.py +1780 -0
  352. flowtask/interfaces/locale.py +40 -0
  353. flowtask/interfaces/log.py +75 -0
  354. flowtask/interfaces/mask.py +143 -0
  355. flowtask/interfaces/notification.py +154 -0
  356. flowtask/interfaces/playwright.py +339 -0
  357. flowtask/interfaces/powerpoint.py +368 -0
  358. flowtask/interfaces/py.typed +0 -0
  359. flowtask/interfaces/qs.py +376 -0
  360. flowtask/interfaces/result.py +87 -0
  361. flowtask/interfaces/selenium_service.py +779 -0
  362. flowtask/interfaces/smartsheet.py +154 -0
  363. flowtask/interfaces/stat.py +39 -0
  364. flowtask/interfaces/task.py +96 -0
  365. flowtask/interfaces/template.py +118 -0
  366. flowtask/interfaces/vectorstores/__init__.py +1 -0
  367. flowtask/interfaces/vectorstores/abstract.py +133 -0
  368. flowtask/interfaces/vectorstores/milvus.py +669 -0
  369. flowtask/interfaces/zammad.py +107 -0
  370. flowtask/models.py +193 -0
  371. flowtask/parsers/__init__.py +15 -0
  372. flowtask/parsers/_yaml.c +11978 -0
  373. flowtask/parsers/_yaml.cpython-39-x86_64-linux-gnu.so +0 -0
  374. flowtask/parsers/argparser.py +235 -0
  375. flowtask/parsers/base.c +15155 -0
  376. flowtask/parsers/base.cpython-39-x86_64-linux-gnu.so +0 -0
  377. flowtask/parsers/json.c +11968 -0
  378. flowtask/parsers/json.cpython-39-x86_64-linux-gnu.so +0 -0
  379. flowtask/parsers/maps.py +49 -0
  380. flowtask/parsers/toml.c +11968 -0
  381. flowtask/parsers/toml.cpython-39-x86_64-linux-gnu.so +0 -0
  382. flowtask/plugins/__init__.py +16 -0
  383. flowtask/plugins/components/__init__.py +0 -0
  384. flowtask/plugins/handler/__init__.py +45 -0
  385. flowtask/plugins/importer.py +31 -0
  386. flowtask/plugins/sources/__init__.py +0 -0
  387. flowtask/runner.py +283 -0
  388. flowtask/scheduler/__init__.py +9 -0
  389. flowtask/scheduler/functions.py +493 -0
  390. flowtask/scheduler/handlers/__init__.py +8 -0
  391. flowtask/scheduler/handlers/manager.py +504 -0
  392. flowtask/scheduler/handlers/models.py +58 -0
  393. flowtask/scheduler/handlers/service.py +72 -0
  394. flowtask/scheduler/notifications.py +65 -0
  395. flowtask/scheduler/scheduler.py +993 -0
  396. flowtask/services/__init__.py +0 -0
  397. flowtask/services/bots/__init__.py +0 -0
  398. flowtask/services/bots/telegram.py +264 -0
  399. flowtask/services/files/__init__.py +11 -0
  400. flowtask/services/files/manager.py +522 -0
  401. flowtask/services/files/model.py +37 -0
  402. flowtask/services/files/service.py +767 -0
  403. flowtask/services/jira/__init__.py +3 -0
  404. flowtask/services/jira/jira_actions.py +191 -0
  405. flowtask/services/tasks/__init__.py +13 -0
  406. flowtask/services/tasks/launcher.py +213 -0
  407. flowtask/services/tasks/manager.py +323 -0
  408. flowtask/services/tasks/service.py +275 -0
  409. flowtask/services/tasks/task_manager.py +376 -0
  410. flowtask/services/tasks/tasks.py +155 -0
  411. flowtask/storages/__init__.py +16 -0
  412. flowtask/storages/exceptions.py +12 -0
  413. flowtask/storages/files/__init__.py +8 -0
  414. flowtask/storages/files/abstract.py +29 -0
  415. flowtask/storages/files/filesystem.py +66 -0
  416. flowtask/storages/tasks/__init__.py +19 -0
  417. flowtask/storages/tasks/abstract.py +26 -0
  418. flowtask/storages/tasks/database.py +33 -0
  419. flowtask/storages/tasks/filesystem.py +108 -0
  420. flowtask/storages/tasks/github.py +119 -0
  421. flowtask/storages/tasks/memory.py +45 -0
  422. flowtask/storages/tasks/row.py +25 -0
  423. flowtask/tasks/__init__.py +0 -0
  424. flowtask/tasks/abstract.py +526 -0
  425. flowtask/tasks/command.py +118 -0
  426. flowtask/tasks/pile.py +486 -0
  427. flowtask/tasks/py.typed +0 -0
  428. flowtask/tasks/task.py +778 -0
  429. flowtask/template/__init__.py +161 -0
  430. flowtask/tests.py +257 -0
  431. flowtask/types/__init__.py +8 -0
  432. flowtask/types/typedefs.c +11347 -0
  433. flowtask/types/typedefs.cpython-39-x86_64-linux-gnu.so +0 -0
  434. flowtask/utils/__init__.py +24 -0
  435. flowtask/utils/constants.py +117 -0
  436. flowtask/utils/encoders.py +21 -0
  437. flowtask/utils/executor.py +112 -0
  438. flowtask/utils/functions.cpp +14280 -0
  439. flowtask/utils/functions.cpython-39-x86_64-linux-gnu.so +0 -0
  440. flowtask/utils/json.cpp +13349 -0
  441. flowtask/utils/json.cpython-39-x86_64-linux-gnu.so +0 -0
  442. flowtask/utils/mail.py +63 -0
  443. flowtask/utils/parseqs.c +13324 -0
  444. flowtask/utils/parserqs.cpython-39-x86_64-linux-gnu.so +0 -0
  445. flowtask/utils/stats.py +308 -0
  446. flowtask/utils/transformations.py +74 -0
  447. flowtask/utils/uv.py +12 -0
  448. flowtask/utils/validators.py +97 -0
  449. flowtask/version.py +11 -0
  450. flowtask-5.8.4.dist-info/LICENSE +201 -0
  451. flowtask-5.8.4.dist-info/METADATA +209 -0
  452. flowtask-5.8.4.dist-info/RECORD +470 -0
  453. flowtask-5.8.4.dist-info/WHEEL +6 -0
  454. flowtask-5.8.4.dist-info/entry_points.txt +3 -0
  455. flowtask-5.8.4.dist-info/top_level.txt +2 -0
  456. plugins/components/CreateQR.py +39 -0
  457. plugins/components/TestComponent.py +28 -0
  458. plugins/components/Use1.py +13 -0
  459. plugins/components/Workplace.py +117 -0
  460. plugins/components/__init__.py +3 -0
  461. plugins/sources/__init__.py +0 -0
  462. plugins/sources/get_populartimes.py +78 -0
  463. plugins/sources/google.py +150 -0
  464. plugins/sources/hubspot.py +679 -0
  465. plugins/sources/icims.py +679 -0
  466. plugins/sources/mobileinsight.py +501 -0
  467. plugins/sources/newrelic.py +262 -0
  468. plugins/sources/uap.py +268 -0
  469. plugins/sources/venu.py +244 -0
  470. plugins/sources/vocinity.py +314 -0
@@ -0,0 +1,432 @@
1
+ import logging
2
+ import asyncio
3
+ from pathlib import Path, PurePath
4
+ from collections.abc import Callable
5
+ from pprint import pprint
6
+ import aiofiles
7
+ import urllib3
8
+ import pandas as pd
9
+ from asyncdb.exceptions import NoDataFound
10
+ from querysource.types.validators import Entity
11
+ from ..exceptions import (
12
+ ComponentError,
13
+ DataNotFound,
14
+ NotSupported,
15
+ FileError
16
+ )
17
+ from ..interfaces.qs import QSSupport
18
+ from ..utils import cPrint, is_empty, SafeDict
19
+ from ..conf import TASK_PATH
20
+ from .flow import FlowComponent
21
+ from ..interfaces import TemplateSupport
22
+
23
+ urllib3.disable_warnings()
24
+ logging.getLogger("urllib3").setLevel(logging.WARNING)
25
+
26
+
27
+ class QueryToPandas(FlowComponent, TemplateSupport, QSSupport):
28
+ """
29
+ QueryToPandas.
30
+
31
+ Overview
32
+
33
+ This component fetches data using QuerySource and transforms it into a Pandas DataFrame.
34
+
35
+ .. table:: Properties
36
+ :widths: auto
37
+
38
+ +--------------+----------+-----------+-------------------------------------------------------+
39
+ | Name | Required | Summary |
40
+ +--------------+----------+-----------+-------------------------------------------------------+
41
+ | query | Yes | Represents an SQL query |
42
+ +--------------+----------+-----------+-------------------------------------------------------+
43
+ | query_slug | Yes | Named queries that are saved in Navigator (QuerySource) |
44
+ +--------------+----------+-----------+-------------------------------------------------------+
45
+ | as_dict | Yes | True | False. if true, it returns the data in JSON format |
46
+ | | | instead of a dataframe |
47
+ +--------------+----------+-----------+-------------------------------------------------------+
48
+ | raw_result | Yes | Returns the data in the NATIVE FORMAT of the database for |
49
+ | | | example ( pg RECORDSET) |
50
+ +--------------+----------+-----------+-------------------------------------------------------+
51
+ | file_sql | Yes | SQL comes from a sql file |
52
+ +--------------+----------+-----------+-------------------------------------------------------+
53
+ | use_template | Yes | The component is passed to the SQL file through a template |
54
+ | | | replacement system |
55
+ +--------------+----------+-----------+-------------------------------------------------------+
56
+ | infer_types | Yes | Type inference, give the component the power to decide the data |
57
+ | | | types of each column |
58
+ +--------------+----------+-----------+-------------------------------------------------------+
59
+ | drop_empty | Yes | False | True delete (drop) any column that is empty |
60
+ +--------------+----------+-----------+-------------------------------------------------------+
61
+ | dropna | Yes | False | True delete all NA (Not a Number) |
62
+ +--------------+----------+-----------+-------------------------------------------------------+
63
+ | fillna | Yes | False | True fills with an EMPTY SPACE all the NAs of the |
64
+ | | | dataframe |
65
+ +--------------+----------+-----------+-------------------------------------------------------+
66
+ | clean_strings| Yes | Fills with an empty space the NA,but ONLY of the fields of |
67
+ | | | type string |
68
+ +--------------+----------+-----------+-------------------------------------------------------+
69
+ | clean_dates | Yes | Declares NONE any date field that has a NAT (Not a Time) |
70
+ +--------------+----------+-----------+-------------------------------------------------------+
71
+ | conditions | Yes | This attribute allows me to apply conditions to filter the data |
72
+ +--------------+----------+-----------+-------------------------------------------------------+
73
+ | formit | Yes | Form id (i have doubts about this) |
74
+ +--------------+----------+-----------+-------------------------------------------------------+
75
+ | orgid | Yes | Organization id (i have doubts about this) |
76
+ +--------------+----------+-----------+-------------------------------------------------------+
77
+ | refresh | Yes | Refreshes the data in the QueryToPandas |
78
+ +--------------+----------+-----------+-------------------------------------------------------+
79
+ | to_string | No | Whether to convert all data to string type. Default is True. |
80
+ +--------------+----------+-----------+-------------------------------------------------------+
81
+ | as_objects | No | Whether to return the result as objects. Default is True. |
82
+ +--------------+----------+-----------+-------------------------------------------------------+
83
+ | datatypes | No | A dictionary specifying data types for columns. |
84
+ +--------------+----------+-----------+-------------------------------------------------------+
85
+ | datasource | No | The datasource to fetch the data from. Default is "db". |
86
+ +--------------+----------+-----------+-------------------------------------------------------+
87
+ Returns
88
+
89
+ This component returns a Pandas DataFrame if the query is successfully executed and data is fetched,
90
+ otherwise raises a ComponentError.
91
+
92
+
93
+
94
+ Example:
95
+
96
+ ```yaml
97
+ QueryToPandas:
98
+ query: SELECT formid, orgid FROM banco.forms WHERE enabled = true
99
+ ```
100
+
101
+ """ # noqa
102
+ def __init__(
103
+ self,
104
+ loop: asyncio.AbstractEventLoop = None,
105
+ job: Callable = None,
106
+ stat: Callable = None,
107
+ **kwargs,
108
+ ):
109
+ """Init Method."""
110
+ self.data = None
111
+ self.infer_types: bool = True
112
+ self.to_string: bool = True
113
+ self._query: dict = {}
114
+ self.as_dict: bool = False
115
+ self.as_objects: bool = True
116
+ self._dtypes: dict = {}
117
+ self.datatypes: dict = {}
118
+ self.use_template: bool = kwargs.get('use_template', False)
119
+ self._driver = kwargs.get("driver", "pg")
120
+ super().__init__(loop=loop, job=job, stat=stat, **kwargs)
121
+
122
+ async def open_sqlfile(self, file: PurePath, **kwargs) -> str:
123
+ if file.exists() and file.is_file():
124
+ content = None
125
+ # open SQL File:
126
+ async with aiofiles.open(file, "r+") as afp:
127
+ content = await afp.read()
128
+ # check if we need to replace masks
129
+ if hasattr(self, "masks"):
130
+ self._logger.debug(f"QueryToPandas Masks: {self.masks}")
131
+ if "{" in content:
132
+ content = self.mask_replacement(content)
133
+ if self.use_template is True:
134
+ content = self._templateparser.from_string(content, kwargs)
135
+ elif hasattr(self, "conditions"):
136
+ content = self.conditions_replacement(content)
137
+ return content
138
+ else:
139
+ raise FileError(f"{self.__name__}: Missing SQL File: {file}")
140
+
141
+ async def start(self, **kwargs):
142
+ await super(QueryToPandas, self).start(**kwargs)
143
+ # compute conditions:
144
+ self.set_conditions()
145
+ # check if sql comes from a filename:
146
+ if hasattr(self, "file_sql") or hasattr(self, "query_file"):
147
+ # based on a list/dict of queries
148
+ if hasattr(self, "file_sql"):
149
+ query = self.file_sql
150
+ else:
151
+ query = self.query_file
152
+ if isinstance(query, PurePath):
153
+ self._query = []
154
+ if query.exists() and query.is_file():
155
+ sql = await self.open_sqlfile(query)
156
+ self._query.append(sql)
157
+ elif isinstance(query, str):
158
+ self._query = []
159
+ try:
160
+ file_path = Path(TASK_PATH).joinpath(self._program, "sql", query)
161
+ if file_path.exists() and file_path.is_file():
162
+ sql = await self.open_sqlfile(file_path)
163
+ self._query.append(sql)
164
+ except Exception as ex:
165
+ raise FileError(f"File SQL doesn't exists: {query!s}: {ex}") from ex
166
+ elif isinstance(query, list): # list of queries
167
+ self._query = []
168
+ for file_sql in query:
169
+ file_path = Path(TASK_PATH).joinpath(self._program, "sql", file_sql)
170
+ if file_path.exists() and file_path.is_file():
171
+ sql = await self.open_sqlfile(file_path)
172
+ self._query.append(sql)
173
+ elif isinstance(query, dict): # named queries
174
+ self._query = {}
175
+ for key, file_sql in query.items():
176
+ file_path = Path(TASK_PATH).joinpath(self._program, "sql", file_sql)
177
+ if file_path.exists() and file_path.is_file():
178
+ sql = await self.open_sqlfile(file_path)
179
+ self._query[key] = sql
180
+ elif hasattr(self, "query_slug"):
181
+ if isinstance(self.query_slug, str): # pylint: disable=E0203
182
+ if "{" in self.query_slug: # pylint: disable=E0203 # noqa
183
+ self.query_slug = self.mask_replacement(self.query_slug)
184
+ self._query[self.query_slug] = self.query_slug
185
+ elif isinstance(self.query_slug, list):
186
+ for slug in self.query_slug:
187
+ self._query[slug] = slug
188
+ elif isinstance(self.query_slug, dict):
189
+ # iterate over all conditions and search in masks:
190
+ for key, data in self.query_slug.items():
191
+ slug = data["slug"]
192
+ for mask, replace in self._mask.items():
193
+ if mask in data["conditions"]:
194
+ self.query_slug[key]["conditions"][mask] = replace
195
+ self._query[key] = slug
196
+ elif hasattr(self, "query"):
197
+ if isinstance(self.query, str): # pylint: disable=E0203
198
+ self._query = []
199
+ if hasattr(self, "masks"):
200
+ self.query = self.mask_replacement(self.query)
201
+ elif "{" in self.query and hasattr(self, "conditions"):
202
+ try:
203
+ self.query = self.query.format(**self.conditions)
204
+ except Exception as err:
205
+ self._logger.warning(f"Error replacing Vars in Query: {err}")
206
+ try:
207
+ self.query = self.query.format(**self._variables)
208
+ except Exception as err:
209
+ self._logger.warning(f"Error replacing Vars in Query: {err}")
210
+ self._query.append(self.query)
211
+ elif isinstance(self.query, dict): # named queries
212
+ self._query = {}
213
+ for key, query in self.query.items():
214
+ query = self.mask_replacement(query)
215
+ try:
216
+ query = query.format(**self._variables)
217
+ except Exception:
218
+ pass
219
+ self._query[key] = query
220
+ elif isinstance(self.query, list): # need to be concatenated
221
+ self._query = []
222
+ for query in self.query:
223
+ query = self.mask_replacement(query)
224
+ try:
225
+ for val in self._variables:
226
+ if isinstance(self._variables[val], list):
227
+ result = ", ".join(self._variables[val])
228
+ else:
229
+ result = ", ".join(
230
+ "'{}'".format(v) for v in self._variables[val]
231
+ )
232
+ query = query.format(**self._variables)
233
+ except Exception:
234
+ pass
235
+ self._query.append(query)
236
+ if hasattr(self, "conditions"):
237
+ self.set_conditions("conditions")
238
+ cPrint("NEW CONDITIONS ARE> ", level="WARN")
239
+ pprint(self.conditions)
240
+
241
+ # Replace variables
242
+ if isinstance(self._query, list):
243
+ queries = []
244
+ for query in self._query:
245
+ values = {}
246
+ for key, val in self._variables.items():
247
+ if isinstance(val, list):
248
+ value = ", ".join(
249
+ "'{}'".format(Entity.quoteString(v)) for v in val
250
+ )
251
+ else:
252
+ value = val
253
+ query = query.replace("{{{}}}".format(str(key)), str(value))
254
+ values[key] = value
255
+ # using safeDict
256
+ query.format_map(SafeDict(**values))
257
+ queries.append(query)
258
+ self._query = queries
259
+ return True
260
+
261
+ async def close(self):
262
+ """Method."""
263
+
264
+ async def run(self):
265
+ # TODO: support for datasources
266
+ # TODO: using maps to transform data types
267
+ if not self._query:
268
+ raise ComponentError(
269
+ "QueryToPandas: Empty Query/Slug or File"
270
+ )
271
+ if hasattr(self, "query") or hasattr(self, "file_sql"):
272
+ try:
273
+ connection = await self.create_connection()
274
+ except Exception as err:
275
+ self._logger.exception(err, stack_info=True)
276
+ raise
277
+ if isinstance(self._query, list): # list of queries
278
+ results = []
279
+ async with await connection.connection() as conn:
280
+ for query in self._query:
281
+ try:
282
+ res, error = await conn.query(query)
283
+ if error:
284
+ raise DataNotFound(error)
285
+ result = [dict(row) for row in res]
286
+ except NoDataFound:
287
+ result = []
288
+ except Exception as err:
289
+ self._logger.error(err)
290
+ raise
291
+ ln = len(result)
292
+ st = {
293
+ "result": ln
294
+ }
295
+ self.add_metric("Query", st)
296
+ if ln == 1 and self.as_dict is True:
297
+ # saving only one row
298
+ result = dict(result[0])
299
+ results.append(result)
300
+ else:
301
+ results.extend(result)
302
+ if hasattr(self, "raw_result"):
303
+ self._result = results
304
+ self._variables[f"{self.StepName}_NUMROWS"] = len(results)
305
+ else:
306
+ self._result = await self.get_dataframe(
307
+ results, infer_types=self.infer_types
308
+ )
309
+ numrows = len(self._result.index)
310
+ self._variables[f"{self.StepName}_NUMROWS"] = numrows
311
+ elif isinstance(self._query, dict): # Named queries
312
+ self._result = {}
313
+ results = []
314
+ async with await connection.connection() as conn:
315
+ for key, query in self._query.items():
316
+ try:
317
+ res, error = await conn.query(query)
318
+ if error:
319
+ raise DataNotFound(error)
320
+ result = [dict(row) for row in res]
321
+ except NoDataFound:
322
+ result = []
323
+ except Exception as err:
324
+ self._logger.error(err)
325
+ raise
326
+ ln = len(result)
327
+ st = {"query": key, "result": ln}
328
+ self.add_metric("Query", st)
329
+ if ln == 1:
330
+ # saving only one row
331
+ result = dict(result[0])
332
+ if hasattr(self, "raw_result"):
333
+ self._result[key] = result
334
+ self._variables[f"{self.StepName}_{key}_NUMROWS"] = len(
335
+ result
336
+ )
337
+ else:
338
+ df = await self.get_dataframe(
339
+ result, infer_types=self.infer_types
340
+ )
341
+ self._result[key] = df
342
+ self._variables[f"{self.StepName}_{key}_NUMROWS"] = len(
343
+ df.index
344
+ )
345
+ else:
346
+ raise NotSupported(f"{self.__name__}: Incompatible Query Method.")
347
+ elif hasattr(self, "query_slug"):
348
+ # TODO: assign the datasource to QuerySource connection
349
+ self.add_metric("SLUG", self.query_slug)
350
+ if isinstance(self.query_slug, dict):
351
+ # return a list of queries
352
+ self._result = {}
353
+ for key, data in self.query_slug.items():
354
+ slug = data["slug"]
355
+ conditions = data["conditions"]
356
+ try:
357
+ result = await self.get_qs(slug, conditions)
358
+ ln = len(result)
359
+ st = {"query": key, "result": ln}
360
+ if ln == 1 and self.as_dict is True:
361
+ # saving only one row
362
+ result = dict(result[0])
363
+ except (DataNotFound, NoDataFound) as ex:
364
+ raise DataNotFound(str(ex)) from ex
365
+ if hasattr(self, "raw_result"):
366
+ self._result[key] = result
367
+ self._variables[f"{self.StepName}_{key}_NUMROWS"] = len(result)
368
+ self.add_metric("NUMROWS", len(result))
369
+ else:
370
+ df = await self.get_dataframe(
371
+ result, infer_types=self.infer_types
372
+ )
373
+ self._result[key] = df
374
+ self._variables[f"{self.StepName}_{key}_NUMROWS"] = len(
375
+ df.index
376
+ )
377
+ self.add_metric("NUMROWS", len(df.index))
378
+ else:
379
+ results = []
380
+ for key, slug in self._query.items():
381
+ conditions = {}
382
+ if hasattr(self, "conditions"):
383
+ conditions = self.conditions
384
+ try:
385
+ result = await self.get_qs(slug, conditions)
386
+ ln = len(result)
387
+ self._logger.debug(f"QS {key}: length: {ln}")
388
+ st = {"query": key, "result": ln}
389
+ if ln == 1 and self.as_dict is True:
390
+ # saving only one row
391
+ result = dict(result[0])
392
+ except (DataNotFound, NoDataFound):
393
+ result = {}
394
+ except Exception as err:
395
+ self._logger.exception(err, stack_info=False)
396
+ raise
397
+ results.extend(result)
398
+ if hasattr(self, "raw_result"):
399
+ self._result = results
400
+ self._variables[f"{self.StepName}_NUMROWS"] = len(results)
401
+ self.add_metric("NUMROWS", len(result))
402
+ else:
403
+ self._result = await self.get_dataframe(
404
+ results, infer_types=self.infer_types
405
+ )
406
+ numrows = len(self._result.index)
407
+ self._variables[f"{self.StepName}_NUMROWS"] = numrows
408
+ self.add_metric("NUMROWS", numrows)
409
+ else:
410
+ raise NotSupported(f"{self.__name__}: Method not allowed")
411
+ if is_empty(self._result):
412
+ raise DataNotFound(f"{self.__name__}: Data Not Found")
413
+ else:
414
+ ### making traspose of data:
415
+ if hasattr(self, "transpose"):
416
+ # transpose rows to columns:
417
+ # self._result = self._result.transpose()
418
+ self._result = pd.melt(self._result, id_vars=self.transpose["columns"])
419
+ if "variable" in self.transpose:
420
+ # rename variable to a new name:
421
+ self._result.rename(
422
+ columns={"variable": self.transpose["variable"]}, inplace=True
423
+ )
424
+ if "value" in self.transpose:
425
+ self._result.rename(
426
+ columns={"value": self.transpose["value"]}, inplace=True
427
+ )
428
+ if self._debug is True:
429
+ print("== DATA PREVIEW ==")
430
+ print(self._result)
431
+ print()
432
+ return self._result
@@ -0,0 +1,195 @@
1
+ """RESTClient.
2
+
3
+ Basic component for making RESTful queries to URLs.
4
+
5
+
6
+ Example:
7
+
8
+ ```yaml
9
+ RESTClient:
10
+ url: https://api.upcdatabase.org/product/{barcode}
11
+ barcode: '0111222333446'
12
+ credentials:
13
+ apikey: UPC_API_KEY
14
+ as_dataframe: true
15
+ ```
16
+
17
+ """
18
+ import asyncio
19
+ from abc import ABC
20
+ from typing import List, Dict, Union
21
+ from collections.abc import Callable
22
+ from urllib.parse import urlencode
23
+ from navconfig.logging import logging
24
+ from ..exceptions import DataNotFound, ComponentError
25
+ from .HTTPClient import HTTPClient
26
+
27
+
28
+ class RESTClient(HTTPClient):
29
+ """
30
+ RESTClient
31
+
32
+ Overview
33
+
34
+ The RESTClient class is a component for making RESTful queries to URLs. It extends the HTTPClient class and provides
35
+ functionality to send requests and process responses from REST APIs. It supports creating DataFrames from JSON responses
36
+ if specified.
37
+
38
+ .. table:: Properties
39
+ :widths: auto
40
+
41
+ +------------------+----------+-----------+--------------------------------------------------------------------------------------+
42
+ | Name | Required | Description |
43
+ +------------------+----------+-----------+--------------------------------------------------------------------------------------+
44
+ | _result | No | The result of the REST query, can be a list or dictionary. |
45
+ +------------------+----------+-----------+--------------------------------------------------------------------------------------+
46
+ | accept | No | The accepted response type, defaults to "application/json". |
47
+ +------------------+----------+-----------+--------------------------------------------------------------------------------------+
48
+ | url | Yes | The URL to send the REST query to. |
49
+ +------------------+----------+-----------+--------------------------------------------------------------------------------------+
50
+ | method | No | The HTTP method to use for the request, defaults to the method specified in the class. |
51
+ +------------------+----------+-----------+--------------------------------------------------------------------------------------+
52
+
53
+ Return
54
+
55
+ The methods in this class manage the execution of RESTful queries and handle the response. It includes functionality to
56
+ convert JSON responses into DataFrames if specified.
57
+
58
+ """ # noqa
59
+
60
+ def __init__(
61
+ self,
62
+ loop: asyncio.AbstractEventLoop = None,
63
+ job: Callable = None,
64
+ stat: Callable = None,
65
+ **kwargs,
66
+ ) -> None:
67
+ """Init Method."""
68
+ self._result: Union[List, Dict] = None
69
+ self._data: dict = kwargs.pop("data", {})
70
+ super().__init__(loop=loop, job=job, stat=stat, **kwargs)
71
+ self.accept: str = "application/json" # by default
72
+
73
+ async def run(self):
74
+ self.url = self.build_url(
75
+ self.url,
76
+ args=self.arguments,
77
+ queryparams=urlencode(self.parameters)
78
+ )
79
+ try:
80
+ if self.use_async is True:
81
+ result, error = await self.async_request(
82
+ url=self.url,
83
+ method=self.method,
84
+ data=self._data
85
+ )
86
+ else:
87
+ result, error = await self.request(
88
+ url=self.url,
89
+ method=self.method,
90
+ data=self._data
91
+ )
92
+ if not result:
93
+ raise DataNotFound(f"Data was not found on: {self.url}")
94
+ elif error is not None:
95
+ if isinstance(error, BaseException):
96
+ raise error
97
+ else:
98
+ raise ComponentError(f"RESTClient Error: {error}")
99
+ except Exception as err:
100
+ logging.exception(err, stack_info=True)
101
+ raise ComponentError(f"RESTClient Error: {err}") from err
102
+ # at here, processing Result
103
+ if self.as_dataframe is True:
104
+ try:
105
+ result = await self.create_dataframe(result)
106
+ except Exception as err:
107
+ raise ComponentError(f"RESTClient Error: {err}") from err
108
+ self._result = result
109
+ return self._result
110
+
111
+
112
+ class AbstractREST(RESTClient):
113
+ """AbstractREST.
114
+ Abstract Method for RESTful Components.
115
+ """
116
+
117
+ _default_method: str = None
118
+ base_url: str = None
119
+
120
+ def __init__(
121
+ self,
122
+ loop: asyncio.AbstractEventLoop = None,
123
+ job: Callable = None,
124
+ stat: Callable = None,
125
+ **kwargs,
126
+ ) -> None:
127
+ """Init Method."""
128
+ self._result: Union[List, Dict] = None
129
+ self.url: str = None
130
+ self._method: str = kwargs.pop('method', self._default_method)
131
+ super().__init__(loop=loop, job=job, stat=stat, **kwargs)
132
+ self.accept: str = "application/json" # by default
133
+ self._args = self._params
134
+
135
+ async def start(self, **kwargs):
136
+ if not hasattr(self, self._method):
137
+ raise ComponentError(
138
+ f"{self.__name__} Error: has no Method {self._method}"
139
+ )
140
+ await super(AbstractREST, self).start(**kwargs)
141
+
142
+ async def run(self):
143
+ method = getattr(self, self._method)
144
+ try:
145
+ await method()
146
+ except Exception as err:
147
+ logging.exception(err, stack_info=True)
148
+ raise ComponentError(
149
+ f"{self.__name__}: Error calling Method {self._method}: {err}"
150
+ ) from err
151
+ self.url = self.build_url(
152
+ self.url,
153
+ args=self.arguments,
154
+ queryparams=urlencode(self.parameters)
155
+ )
156
+ try:
157
+ if self.use_async is True:
158
+ result, error = await self.async_request(
159
+ url=self.url,
160
+ method=self.method,
161
+ data=self._data
162
+ )
163
+ else:
164
+ result, error = await self.request(
165
+ url=self.url,
166
+ method=self.method,
167
+ data=self._data
168
+ )
169
+ if self._debug:
170
+ print(result)
171
+ if not result:
172
+ raise DataNotFound(
173
+ f"Data was not found on: {self.url}"
174
+ )
175
+ elif error is not None:
176
+ if isinstance(error, BaseException):
177
+ raise error
178
+ else:
179
+ raise ComponentError(f"HTTPClient Error: {error}")
180
+ # at here, processing Result
181
+ if self.as_dataframe is True:
182
+ try:
183
+ result = await self.create_dataframe(result)
184
+ if self._debug is True:
185
+ print(result)
186
+ print("::: Printing Column Information === ")
187
+ for column, t in result.dtypes.items():
188
+ print(column, "->", t, "->", result[column].iloc[0])
189
+ except Exception as err:
190
+ raise ComponentError(f"HTTPClient Error: {err}") from err
191
+ self._result = result
192
+ return self._result
193
+ except Exception as err:
194
+ logging.exception(err, stack_info=True)
195
+ raise ComponentError(f"HTTPClient Error: {err}") from err