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,69 @@
1
+ from typing import Union, Any, ParamSpec
2
+ from io import BytesIO
3
+ import orjson
4
+ import pyarrow as pa
5
+ import datatable as dt
6
+ import pandas as pd
7
+ from .abstract import BaseDataframe
8
+ from ...exceptions import ComponentError, DataNotFound
9
+
10
+
11
+ P = ParamSpec("P")
12
+
13
+
14
+ def is_empty(obj):
15
+ """check_empty.
16
+ Check if a basic object, a Polars DataFrame, an Apache Arrow Table,
17
+ or a Python DataTable Frame is empty or not.
18
+ """
19
+ if isinstance(obj, (pa.Table, dt.Frame)):
20
+ return obj.nrows == 0
21
+ else:
22
+ return bool(not obj)
23
+
24
+
25
+ class DtDataframe(BaseDataframe):
26
+ """DtDataframe.
27
+
28
+ Converts any result into a Datatable 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 Datatable DataFrame.
36
+
37
+ :param result: The result data to be converted into a Datatable DataFrame.
38
+ :return: A DataFrame containing the result data.
39
+ """
40
+ if is_empty(result):
41
+ raise DataNotFound("Frame: 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, dict)):
49
+ df = dt.Frame(result, **kwargs)
50
+ elif isinstance(result, bytes) or isinstance(result, BytesIO):
51
+ # Reset the pointer to the start of the stream
52
+ result.seek(0)
53
+ # Assuming bytes is a CSV format, adjust as needed
54
+ df = dt.Frame(pd.read_csv(result))
55
+ else:
56
+ raise ValueError("Unsupported data type for DataTable Frame creation")
57
+
58
+ columns = list(df.names)
59
+ numrows = df.nrows
60
+ numcols = df.ncols
61
+ try:
62
+ self._variables["_numRows_"] = numrows
63
+ self.add_metric("NUM_ROWS", numrows)
64
+ self.add_metric("NUM_COLS", numcols)
65
+ except Exception:
66
+ pass
67
+ return df
68
+ except Exception as err:
69
+ raise ComponentError(f"Error Creating Frame: {err!s}")
@@ -0,0 +1,167 @@
1
+ from typing import Union, Any, ParamSpec, Callable
2
+ import asyncio
3
+ import orjson
4
+ import pandas as pd
5
+ from .abstract import BaseDataframe
6
+ from ...exceptions import ComponentError, DataNotFound
7
+
8
+ P = ParamSpec("P")
9
+
10
+
11
+ def is_empty(obj):
12
+ """check_empty.
13
+ Check if a basic object is empty or not.
14
+ """
15
+ if isinstance(obj, pd.DataFrame):
16
+ return True if obj.empty else False
17
+ else:
18
+ return bool(not obj)
19
+
20
+
21
+ class PandasDataframe(BaseDataframe):
22
+ """PandasDataframe.
23
+
24
+ Converts any result into a Pandas DataFrame.
25
+ """
26
+ chunk_size: int = 100
27
+ task_parts: int = 10
28
+
29
+ async def create_dataframe(
30
+ self,
31
+ result: Union[dict, bytes, Any],
32
+ *args: P.args,
33
+ **kwargs: P.kwargs
34
+ ) -> Any:
35
+ """
36
+ Converts any result into a Pandas DataFrame.
37
+
38
+ :param result: The result data to be converted into a Pandas DataFrame.
39
+ :return: A DataFrame containing the result data.
40
+ """
41
+ if is_empty(result):
42
+ raise DataNotFound("DataFrame: No Data was Found.")
43
+ try:
44
+ if isinstance(result, str):
45
+ try:
46
+ result = orjson.loads(result)
47
+ except Exception:
48
+ pass
49
+ if isinstance(result, dict):
50
+ result = [result]
51
+ df = pd.DataFrame(result, **kwargs)
52
+ # Attempt to infer better dtypes for object columns.
53
+ df.infer_objects()
54
+ columns = list(df.columns)
55
+ if hasattr(self, "infer_types"):
56
+ df = df.convert_dtypes(convert_string=self.to_string)
57
+ if hasattr(self, "infer_types"):
58
+ df = df.convert_dtypes()
59
+ if hasattr(self, "drop_empty"):
60
+ df.dropna(axis=1, how="all", inplace=True)
61
+ df.dropna(axis=0, how="all", inplace=True)
62
+ if hasattr(self, "dropna"):
63
+ df.dropna(subset=self.dropna, how="all", inplace=True)
64
+ numrows = len(df.index)
65
+ try:
66
+ self._variables["_numRows_"] = numrows
67
+ self.add_metric("NUM_ROWS", numrows)
68
+ self.add_metric("NUM_COLS", len(columns))
69
+ except Exception:
70
+ pass
71
+ return df
72
+ except Exception as err:
73
+ raise ComponentError(
74
+ f"Error Creating Dataframe: {err!s}"
75
+ )
76
+
77
+ async def from_csv(
78
+ self, result: str, *args: P.args, **kwargs: P.kwargs
79
+ ) -> Any:
80
+ """
81
+ Converts a Comma-Separated CSV into a Pandas DataFrame.
82
+
83
+ :param result: The result data to be converted into a Pandas DataFrame.
84
+ :return: A DataFrame containing the result data.
85
+ """
86
+ if is_empty(result):
87
+ raise DataNotFound("DataFrame: No Data was Found.")
88
+ try:
89
+ df = pd.read_csv(result, encoding="utf-8", **kwargs)
90
+ # Attempt to infer better dtypes for object columns.
91
+ df.infer_objects()
92
+ columns = list(df.columns)
93
+ if hasattr(self, "infer_types"):
94
+ df = df.convert_dtypes(convert_string=self.to_string)
95
+ if hasattr(self, "infer_types"):
96
+ df = df.convert_dtypes()
97
+ if hasattr(self, "drop_empty"):
98
+ df.dropna(axis=1, how="all", inplace=True)
99
+ df.dropna(axis=0, how="all", inplace=True)
100
+ if hasattr(self, "dropna"):
101
+ df.dropna(subset=self.dropna, how="all", inplace=True)
102
+ numrows = len(df.index)
103
+ try:
104
+ self._variables["_numRows_"] = numrows
105
+ self.add_metric("NUM_ROWS", numrows)
106
+ self.add_metric("NUM_COLS", len(columns))
107
+ except Exception:
108
+ pass
109
+ return df
110
+ except Exception as err:
111
+ raise ComponentError(f"Error Creating Dataframe: {err!s}")
112
+
113
+ def column_exists(self, column: str):
114
+ """Returns True if the column exists in the DataFrame."""
115
+ if column not in self.data.columns:
116
+ self._logger.warning(
117
+ f"Column {column} does not exist in the dataframe"
118
+ )
119
+ self.data[column] = None
120
+ return False
121
+ return True
122
+
123
+ def _create_tasks(self, dataframe: pd.DataFrame, func: Union[str, Callable], **kwargs) -> list:
124
+ """
125
+ Create tasks for processing the DataFrame.
126
+
127
+ :param dataframe: The DataFrame to process.
128
+ :param
129
+ func: The function to apply to each row.
130
+ :return: A list of tasks.
131
+ """
132
+ if isinstance(func, str):
133
+ func = getattr(self, func)
134
+ if not callable(func):
135
+ raise ValueError(f"Function {func} is not callable.")
136
+ if not isinstance(dataframe, pd.DataFrame):
137
+ raise ValueError(f"Dataframe {dataframe} is not a DataFrame.")
138
+ if dataframe.empty:
139
+ raise ValueError(f"Dataframe {dataframe} is empty.")
140
+ tasks = []
141
+ for idx, row in dataframe.iterrows():
142
+ task = func(row, idx, **kwargs)
143
+ if asyncio.iscoroutinefunction(task):
144
+ tasks.append(task)
145
+ else:
146
+ tasks.append(asyncio.create_task(task))
147
+ return tasks
148
+
149
+ def split_parts(self, task_list, num_parts: int = 5) -> list:
150
+ part_size = len(task_list) // num_parts
151
+ remainder = len(task_list) % num_parts
152
+ parts = []
153
+ start = 0
154
+ for i in range(num_parts):
155
+ # Distribute the remainder across the first `remainder` parts
156
+ end = start + part_size + (1 if i < remainder else 0)
157
+ parts.append(task_list[start:end])
158
+ start = end
159
+ return parts
160
+
161
+ async def _processing_tasks(self, tasks: list) -> pd.DataFrame:
162
+ """Process tasks concurrently."""
163
+ results = []
164
+ for chunk in self.split_parts(tasks, self.task_parts):
165
+ result = await asyncio.gather(*chunk, return_exceptions=False)
166
+ results.extend(result)
167
+ return results
@@ -0,0 +1,60 @@
1
+ from typing import Union, Any, ParamSpec
2
+ import orjson
3
+ import pandas as pd
4
+ import polars as pl
5
+ from .abstract import BaseDataframe
6
+ from ...exceptions import ComponentError, DataNotFound
7
+
8
+
9
+ P = ParamSpec("P")
10
+
11
+
12
+ def is_empty(obj):
13
+ """check_empty.
14
+ Check if a basic object or a DataFrame (Pandas or Polars) is empty or not.
15
+ """
16
+ if isinstance(obj, pd.DataFrame) or isinstance(obj, pl.DataFrame):
17
+ return obj.shape[0] == 0
18
+ else:
19
+ return bool(not obj)
20
+
21
+
22
+ class PolarsDataframe(BaseDataframe):
23
+ """PolarsDataframe.
24
+
25
+ Converts any result into a Polars DataFrame.
26
+ """
27
+
28
+ async def create_dataframe(
29
+ self, result: Union[dict, bytes, Any], *args: P.args, **kwargs: P.kwargs
30
+ ) -> Any:
31
+ """
32
+ Converts any result into a Polars DataFrame.
33
+
34
+ :param result: The result data to be converted into a Polars DataFrame.
35
+ :return: A DataFrame containing the result data.
36
+ """
37
+ if is_empty(result):
38
+ raise DataNotFound("DataFrame: No Data was Found.")
39
+ try:
40
+ if isinstance(result, str):
41
+ try:
42
+ result = orjson.loads(result)
43
+ except Exception:
44
+ pass
45
+ df = pl.DataFrame(result, **kwargs)
46
+ columns = list(df.columns)
47
+ if hasattr(self, "drop_empty"):
48
+ df = df.drop_nulls(how="all", subset=df.columns)
49
+ if hasattr(self, "dropna"):
50
+ df = df.drop_nulls(how="all", subset=self.dropna)
51
+ numrows = df.height
52
+ try:
53
+ self._variables["_numRows_"] = numrows
54
+ self.add_metric("NUM_ROWS", numrows)
55
+ self.add_metric("NUM_COLS", df.width)
56
+ except Exception:
57
+ pass
58
+ return df
59
+ except Exception as err:
60
+ raise ComponentError(f"Error Creating Dataframe: {err!s}")
@@ -0,0 +1,263 @@
1
+ import asyncio
2
+ from typing import Optional
3
+ from collections.abc import Callable
4
+ from navconfig.logging import logging
5
+ from querysource.conf import (
6
+ # postgres main database:
7
+ # postgres read-only
8
+ PG_DRIVER,
9
+ PG_HOST,
10
+ PG_USER,
11
+ PG_PWD,
12
+ PG_DATABASE,
13
+ PG_PORT,
14
+ # rethinkdb
15
+ RT_DRIVER,
16
+ RT_HOST,
17
+ RT_PORT,
18
+ RT_USER,
19
+ RT_PASSWORD,
20
+ RT_DATABASE,
21
+ # SQL Server
22
+ MSSQL_DRIVER,
23
+ MSSQL_HOST,
24
+ MSSQL_PORT,
25
+ MSSQL_USER,
26
+ MSSQL_PWD,
27
+ MSSQL_DATABASE,
28
+ # MySQL Server
29
+ MYSQL_DRIVER,
30
+ MYSQL_HOST,
31
+ MYSQL_PORT,
32
+ MYSQL_USER,
33
+ MYSQL_PWD,
34
+ MYSQL_DATABASE,
35
+ # influxdb
36
+ INFLUX_DRIVER,
37
+ INFLUX_HOST,
38
+ INFLUX_PORT,
39
+ INFLUX_ORG,
40
+ INFLUX_TOKEN,
41
+ # INFLUX_USER,
42
+ # INFLUX_PWD,
43
+ INFLUX_DATABASE,
44
+ # cassandra
45
+ CASSANDRA_DRIVER,
46
+ CASSANDRA_HOST,
47
+ CASSANDRA_PORT,
48
+ CASSANDRA_USER,
49
+ CASSANDRA_PWD,
50
+ CASSANDRA_DATABASE,
51
+ )
52
+ from asyncdb import AsyncDB
53
+ from asyncdb.drivers.base import BaseDriver
54
+ from asyncdb.exceptions import ProviderError
55
+ from ..conf import default_dsn
56
+ from ..exceptions import ComponentError
57
+ from .credentials import CredentialsInterface
58
+
59
+
60
+ class DBInterface(CredentialsInterface):
61
+ """DBInterface.
62
+
63
+ Abstract Interface for Database-based connectors.
64
+ """
65
+ _credentials = {
66
+ "host": str,
67
+ "port": int,
68
+ "user": str,
69
+ "password": str,
70
+ "database": str,
71
+ }
72
+
73
+ def __init__(
74
+ self,
75
+ *args,
76
+ driver: Optional[str] = None,
77
+ **kwargs
78
+ ) -> None:
79
+ self.driver: str = driver
80
+ self.datasource: str = None
81
+ self._connection: Callable = None
82
+ super().__init__(*args, **kwargs)
83
+
84
+ async def connection(
85
+ self,
86
+ driver: str = "pg",
87
+ credentials: Optional[dict] = None,
88
+ event_loop: Optional[asyncio.AbstractEventLoop] = None,
89
+ **kwargs,
90
+ ) -> BaseDriver:
91
+ if not event_loop:
92
+ event_loop = asyncio.get_event_loop()
93
+ if driver == "pg": # default driver:
94
+ args = {
95
+ "server_settings": {
96
+ "client_min_messages": "notice",
97
+ "max_parallel_workers": "24",
98
+ "statement_timeout": "36000000",
99
+ }
100
+ }
101
+ else:
102
+ args = kwargs
103
+ try:
104
+ self._connection = AsyncDB(
105
+ driver, params=credentials, loop=event_loop, **args
106
+ )
107
+ except ProviderError as e:
108
+ raise ComponentError(f"DbClient: Error creating connection: {e}") from e
109
+ except Exception as e:
110
+ raise ComponentError(f"DbClient: unknown DB error: {e}") from e
111
+ if self._connection:
112
+ return self._connection
113
+ else:
114
+ raise ComponentError(f"DbClient: Unable to connect to {driver}")
115
+
116
+ def pg_connection(self, event_loop: asyncio.AbstractEventLoop = None) -> BaseDriver:
117
+ pgargs: dict = {
118
+ "server_settings": {
119
+ "application_name": "Flowtask",
120
+ "client_min_messages": "notice",
121
+ "max_parallel_workers": "48",
122
+ "jit": "off",
123
+ "statement_timeout": "3600000",
124
+ "effective_cache_size": "2147483647",
125
+ },
126
+ }
127
+ if not event_loop:
128
+ try:
129
+ event_loop = asyncio.get_running_loop()
130
+ except RuntimeError:
131
+ event_loop = asyncio.get_event_loop()
132
+ return AsyncDB("pg", dsn=default_dsn, loop=event_loop, **pgargs)
133
+
134
+ async def get_driver(self, driver: str, conn: BaseDriver) -> BaseDriver:
135
+ # TODO: migration to Model
136
+ result = None
137
+ query = (
138
+ "SELECT driver, params, credentials FROM public.datasources where name = '{}'"
139
+ )
140
+ try:
141
+ result, error = await conn.queryrow(query.format(driver))
142
+ if error:
143
+ raise ComponentError(
144
+ f"DbClient: Error on Getting Datasource: {error!s}"
145
+ )
146
+ if result:
147
+ try:
148
+ self.driver = result["driver"]
149
+ except KeyError as ex:
150
+ raise RuntimeError(
151
+ f"DbClient Error: there is no *Driver* column on datasource {driver}"
152
+ ) from ex
153
+ try:
154
+ params = result["params"]
155
+ logging.debug(
156
+ f"DB: connection params: {params}"
157
+ )
158
+ self.credentials = {**dict(params), **dict(result["credentials"])}
159
+ except (TypeError, ValueError, KeyError) as ex:
160
+ raise RuntimeError(
161
+ f"DbClient Error: wrong or missing credentials on Datasource {driver}"
162
+ ) from ex
163
+ except Exception as e:
164
+ logging.exception(f"DB Error: {e}", stack_info=True)
165
+ raise
166
+ if not result:
167
+ # getting the default for any kind of database connection:
168
+ # based on provider (rethink, mssql, etc) get default connection
169
+ if driver == "sqlserver":
170
+ self.driver = MSSQL_DRIVER
171
+ self.credentials = {
172
+ "host": MSSQL_HOST,
173
+ "port": MSSQL_PORT,
174
+ "database": MSSQL_DATABASE,
175
+ "user": MSSQL_USER,
176
+ "password": MSSQL_PWD,
177
+ }
178
+ elif driver == "cassandra":
179
+ self.driver = CASSANDRA_DRIVER
180
+ self.credentials = {
181
+ "host": CASSANDRA_HOST,
182
+ "port": CASSANDRA_PORT,
183
+ "database": CASSANDRA_DATABASE,
184
+ "user": CASSANDRA_USER,
185
+ "password": CASSANDRA_PWD,
186
+ }
187
+ elif driver in ("influx", "influxdb"):
188
+ self.driver = INFLUX_DRIVER
189
+ self.credentials = {
190
+ "host": INFLUX_HOST,
191
+ "port": INFLUX_PORT,
192
+ "database": INFLUX_DATABASE,
193
+ "org": INFLUX_ORG,
194
+ "token": INFLUX_TOKEN,
195
+ }
196
+ elif driver in ("rethink", "rethinkdb"):
197
+ self.driver = RT_DRIVER
198
+ self.credentials = {
199
+ "host": RT_HOST,
200
+ "port": RT_PORT,
201
+ "database": RT_DATABASE,
202
+ "user": RT_USER,
203
+ "password": RT_PASSWORD,
204
+ }
205
+ elif driver in ("postgres", "postgresql"):
206
+ self.driver = PG_DRIVER
207
+ self.credentials = {
208
+ "host": PG_HOST,
209
+ "port": PG_PORT,
210
+ "database": PG_DATABASE,
211
+ "user": PG_USER,
212
+ "password": PG_PWD,
213
+ }
214
+ elif driver == "mysql":
215
+ self.driver = MYSQL_DRIVER
216
+ self.credentials = {
217
+ "host": MYSQL_HOST,
218
+ "port": MYSQL_PORT,
219
+ "database": MYSQL_DATABASE,
220
+ "user": MYSQL_USER,
221
+ "password": MYSQL_PWD,
222
+ }
223
+ else:
224
+ raise ComponentError(f"Unknown Database Driver {driver}")
225
+
226
+ async def get_credentials(self) -> BaseDriver:
227
+ if self.credentials:
228
+ return True # credentials are passed to Component
229
+ if self.datasource is not None:
230
+ driver = self.datasource
231
+ else:
232
+ driver = "pg"
233
+ if driver in ("db", "pg"):
234
+ # default credentials
235
+ self.driver = PG_DRIVER
236
+ self.credentials = {
237
+ "user": PG_USER,
238
+ "password": PG_PWD,
239
+ "host": PG_HOST,
240
+ "port": int(PG_PORT),
241
+ "database": PG_DATABASE,
242
+ }
243
+ return True
244
+ else:
245
+ # getting from "datasources" table:
246
+ db = self.pg_connection()
247
+ try:
248
+ async with await db.connection() as conn:
249
+ await self.get_driver(driver, conn)
250
+ if not self.credentials:
251
+ raise RuntimeError(
252
+ f"DB Error: wrong or missing credentials: {driver}"
253
+ )
254
+ except Exception as e:
255
+ logging.exception(f"DB Error: {e}")
256
+ raise
257
+
258
+ async def start(self, **kwargs):
259
+ # first: getting credential from datasource or creds dictionary.
260
+ # second: processing credentials (extracting value replacements from environment)
261
+ await self.get_credentials()
262
+ self.processing_credentials()
263
+ await super(DBInterface, self).start(**kwargs)
@@ -0,0 +1,46 @@
1
+ from abc import ABC
2
+ import os
3
+ from navconfig import config
4
+
5
+
6
+ class EnvSupport(ABC):
7
+ """EnvSupport.
8
+
9
+ Support for Environment Variables
10
+ """
11
+
12
+ def __init__(self, *args, **kwargs):
13
+ self._environment = config
14
+ # Call super only if there’s a next class in the MRO
15
+ try:
16
+ super().__init__(*args, **kwargs)
17
+ except TypeError:
18
+ super().__init__()
19
+
20
+ def get_env_value(self, key, default: str = None, expected_type: object = None):
21
+ """
22
+ Retrieves a value from the environment variables or the configuration.
23
+
24
+ :param key: The key for the environment variable.
25
+ :param default: The default value to return if the key is not found.
26
+ :param expected_type: the data type to be expected.
27
+ :return: The value of the environment variable or the default value.
28
+ """
29
+ if key is None:
30
+ return default
31
+ if expected_type is not None:
32
+ if expected_type in (int, float):
33
+ return self._environment.getint(key, default)
34
+ elif expected_type == bool:
35
+ return self._environment.getboolean(key, default)
36
+ else:
37
+ return self._environment.get(key, default)
38
+ if val := os.getenv(str(key), default):
39
+ return val
40
+ if val := self._environment.get(key, default):
41
+ return val
42
+ else:
43
+ if hasattr(self, "masks") and hasattr(self, "_mask"):
44
+ if key in self._mask.keys():
45
+ return self._mask[key]
46
+ return key