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,534 @@
1
+ import asyncio
2
+ from typing import Dict, Any
3
+ from collections.abc import Callable
4
+ from pathlib import PosixPath, Path
5
+ import re
6
+ from decimal import Decimal
7
+ import datetime
8
+ import numpy as np
9
+ import pandas as pd
10
+ import dask.dataframe as dd
11
+ from asyncdb.models import Model
12
+ import dateparser
13
+ from navconfig.logging import logging
14
+ from ..exceptions import FileError, ComponentError, DataNotFound
15
+ from .flow import FlowComponent
16
+ from ..interfaces.qs import QSSupport
17
+ from ..utils.transformations import (
18
+ is_camelcase,
19
+ is_snakecase,
20
+ remove_illegal_chars,
21
+ camelcase_split
22
+ )
23
+ from ..utils.constants import excel_based
24
+
25
+
26
+ logging.getLogger("fsspec").setLevel(logging.CRITICAL)
27
+
28
+
29
+ dtypes = {
30
+ "varchar": str,
31
+ "character varying": str,
32
+ "string": str,
33
+ "object": str,
34
+ "int": int,
35
+ "int4": int,
36
+ "integer": int,
37
+ "bigint": np.int64,
38
+ "int64": np.int64,
39
+ "uint64": np.int64,
40
+ "Int8": int,
41
+ "float64": Decimal,
42
+ "float": Decimal,
43
+ "bool": bool,
44
+ "datetime64[ns]": datetime.datetime,
45
+ "date": datetime.date,
46
+ }
47
+
48
+
49
+ # adding support for primary keys on raw tables
50
+ pk_sentence = """ALTER TABLE {schema}.{table}
51
+ ADD CONSTRAINT {schema}_{table}_pkey PRIMARY KEY({fields});
52
+
53
+ Example:
54
+
55
+ ```yaml
56
+ TableSchema:
57
+ normalize_names: true
58
+ tablename: photos_raw
59
+ schema: banco_chile
60
+ pk:
61
+ - photo_id
62
+ replace_names:
63
+ url: url_thumbnail
64
+ full_size_url: photo_path
65
+ categories: categories_names
66
+ form_visit_id: form_id
67
+ inserted: inserted_at
68
+ ```
69
+
70
+ """
71
+
72
+
73
+ def datetime_to_name(value: datetime.datetime, mask: str):
74
+ return value.strftime(mask)
75
+
76
+
77
+ # Lista de palabras reservadas comunes en SQL
78
+ SQL_RESERVED_WORDS = [
79
+ "all", "analyse", "analyze", "and", "any", "array", "as", "asc",
80
+ "asymmetric", "authorization", "binary", "both", "case", "cast",
81
+ "check", "collate", "collation", "column", "constraint", "create",
82
+ "cross", "current_catalog", "current_date", "current_role",
83
+ "current_time", "current_timestamp", "current_user", "default",
84
+ "deferrable", "desc", "distinct", "do", "else", "end", "except",
85
+ "false", "fetch", "for", "foreign", "freeze", "from", "full",
86
+ "grant", "group", "having", "ilike", "in", "initially", "inner",
87
+ "intersect", "into", "is", "isnull", "join", "lateral", "leading",
88
+ "left", "like", "limit", "localtime", "localtimestamp", "natural",
89
+ "not", "notnull", "null", "offset", "on", "only", "or", "order",
90
+ "outer", "overlaps", "placing", "primary", "references", "returning",
91
+ "right", "select", "session_user", "similar", "some", "symmetric",
92
+ "table", "tablesample", "then", "to", "trailing", "true", "union",
93
+ "unique", "user", "using", "variadic", "verbose", "when", "where",
94
+ "window", "with"
95
+ ]
96
+
97
+
98
+ class TableSchema(QSSupport, FlowComponent):
99
+ """
100
+ TableSchema
101
+
102
+ Overview
103
+
104
+ The TableSchema class is a component for reading a CSV file or DataFrame and creating a table schema based
105
+ on data models. It supports various formatting and normalization options for column names, datatype inference,
106
+ and automatic handling of primary keys. This component also supports normalization settings for column names,
107
+ such as camelCase to snake_case conversion, illegal character removal, and customizable name replacements.
108
+
109
+ .. table:: Properties
110
+ :widths: auto
111
+
112
+ +-------------------+----------+-----------+------------------------------------------------------------------+
113
+ | Name | Required | Summary |
114
+ +-------------------+----------+-----------+------------------------------------------------------------------+
115
+ | filename | Yes | The CSV file or DataFrame input to read and infer schema from. |
116
+ +-------------------+----------+-----------+------------------------------------------------------------------+
117
+ | schema | No | The database schema for the table. |
118
+ +-------------------+----------+-----------+------------------------------------------------------------------+
119
+ | tablename | Yes | The name of the table to be created based on the data model. |
120
+ +-------------------+----------+-----------+------------------------------------------------------------------+
121
+ | drop | No | Boolean specifying if an existing table with the same name should be dropped.|
122
+ +-------------------+----------+-----------+------------------------------------------------------------------+
123
+ | normalize_names | No | Dictionary with options for column name normalization. |
124
+ +-------------------+----------+-----------+------------------------------------------------------------------+
125
+ | pk | No | List of columns to define as primary keys. |
126
+ +-------------------+----------+-----------+------------------------------------------------------------------+
127
+ | replace_names | No | Dictionary of column name replacements for renaming specific columns. |
128
+ +-------------------+----------+-----------+------------------------------------------------------------------+
129
+
130
+ Returns
131
+
132
+ This component returns the input data after creating a database table schema based on the data's inferred or
133
+ specified structure. If the input is a file, it reads and processes the file; if a DataFrame, it directly
134
+ processes the DataFrame. The component provides detailed metrics on column structure and row counts, as well as
135
+ logging for SQL execution status and any schema creation errors.
136
+ """ # noqa
137
+
138
+ def __init__(
139
+ self,
140
+ loop: asyncio.AbstractEventLoop = None,
141
+ job: Callable = None,
142
+ stat: Callable = None,
143
+ **kwargs,
144
+ ) -> None:
145
+ """Init Method."""
146
+ self.separator: str = ","
147
+ self.params: Dict = {}
148
+ self.fields: Dict = {}
149
+ self.replace_names: Dict = {}
150
+ self.drop: bool = False
151
+ self.data: Any = None
152
+ self.filename: str = None
153
+ # info about table:
154
+ self.tablename: str = None
155
+ self.schema: str = None
156
+ self.credentials = kwargs.pop('credentials', None)
157
+ self._driver: str = kwargs.pop('driver', 'pg')
158
+ super(TableSchema, self).__init__(
159
+ loop=loop,
160
+ job=job,
161
+ stat=stat,
162
+ **kwargs
163
+ )
164
+
165
+ async def start(self, **kwargs):
166
+ if self.previous:
167
+ if isinstance(self.input, PosixPath):
168
+ self.filename = self.input
169
+ elif isinstance(self.input, list):
170
+ self.filename = PosixPath(self.input[0])
171
+ elif isinstance(self.input, str):
172
+ self.filename = PosixPath(self.input)
173
+ elif isinstance(self.input, dict):
174
+ filenames = list(self.input.keys())
175
+ if filenames:
176
+ try:
177
+ self.filename = PosixPath(filenames[0])
178
+ except IndexError as err:
179
+ raise FileError(f"File doesnt exists: {filenames}") from err
180
+ elif isinstance(self.input, dd.DataFrame) or isinstance(
181
+ self.input, pd.DataFrame
182
+ ):
183
+ self.filename = None
184
+ self.data = self.input
185
+ else:
186
+ raise FileError(f"File doesnt exists: {self.input}")
187
+ elif hasattr(self, "filename"):
188
+ self.filename = Path(self.filename)
189
+ else:
190
+ raise ComponentError(
191
+ "TableSchema: This Component requires a File or Dataframe from input."
192
+ )
193
+ if hasattr(self, "replace_names") and self.replace_names:
194
+ for col, replace in self.replace_names.items():
195
+ if not isinstance(replace, (str, dict)):
196
+ self._logger.warning(
197
+ f"Invalid replace_names value for '{col}': expected string or dict, got {type(replace).__name__}"
198
+ )
199
+ elif isinstance(replace, dict) and "type" in replace and replace["type"] not in dtypes:
200
+ self._logger.warning(
201
+ f"Type '{replace['type']}' in replace_names for column '{col}' is not valid. Valid types: {list(dtypes.keys())}"
202
+ )
203
+
204
+ await super().start(**kwargs)
205
+ self.processing_credentials()
206
+
207
+ async def close(self):
208
+ pass
209
+
210
+ def rename_repeated_col(self, col, cols):
211
+ renamed = False
212
+ count = 1
213
+ for c, t in cols:
214
+ if c == col:
215
+ if not renamed:
216
+ col = f"{col}_{count}"
217
+ count += 1
218
+ renamed = True
219
+ else:
220
+ col = col.split("_", 1)[0]
221
+ col = f"{col}_{count}"
222
+ count += 1
223
+ return col
224
+
225
+ def handle_sql_reserved_word(self, column_name):
226
+ """
227
+ Verify if the column name is a SQL reserved word
228
+ and raise an error if it is.
229
+
230
+ Args:
231
+ column_name (str): Column name to verify
232
+
233
+ Returns:
234
+ str: The same column name if it is not a reserved word
235
+
236
+ Raises:
237
+ ComponentError: If the column name is a SQL reserved word
238
+ """
239
+ if column_name.lower() in SQL_RESERVED_WORDS:
240
+ error_msg = (f"Column name '{column_name}' is a SQL reserved word. "
241
+ f"Please use 'replace_names' to change this column name.")
242
+ self._logger.error(error_msg)
243
+ raise ComponentError(error_msg)
244
+ return column_name
245
+
246
+ async def run(self):
247
+ self.result = None
248
+ if not hasattr(self, "mime"):
249
+ self.mime = "text/csv"
250
+ if self.filename:
251
+ if self.mime in excel_based:
252
+ if (
253
+ self.mime == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
254
+ ):
255
+ # xlsx or any openxml based document
256
+ file_engine = self.params.get("file_engine", "openpyxl")
257
+ elif (
258
+ self.mime == "application/vnd.ms-excel.sheet.binary.macroEnabled.12"
259
+ ):
260
+ file_engine = self.params.get("file_engine", "pyxlsb")
261
+ else:
262
+ try:
263
+ ext = self.filename.suffix
264
+ except (AttributeError, ValueError):
265
+ ext = ".xls"
266
+ if ext == ".xls":
267
+ file_engine = self.params.get("file_engine", "xlrd")
268
+ else:
269
+ file_engine = self.params.get("file_engine", "openpyxl")
270
+ # passed arguments to Pandas directly
271
+ arguments = {**self.params}
272
+ if hasattr(self, "pd_args") and isinstance(self.pd_args, dict):
273
+ arguments = {**self.params, **self.pd_args}
274
+ df = pd.read_excel(
275
+ self.filename,
276
+ engine=file_engine,
277
+ keep_default_na=True,
278
+ na_filter=False,
279
+ **arguments,
280
+ )
281
+ else:
282
+ self.params = {"infer_datetime_format": True}
283
+ arguments = {**self.params}
284
+ if hasattr(self, "pd_args") and isinstance(self.pd_args, dict):
285
+ arguments = {**self.params, **self.pd_args}
286
+ try:
287
+ # can we use pyarrow.
288
+ engine = arguments["engine"]
289
+ del arguments["engine"]
290
+ except KeyError:
291
+ engine = "c"
292
+ tp = pd.read_csv(
293
+ self.filename,
294
+ sep=self.separator,
295
+ decimal=",",
296
+ engine=engine,
297
+ keep_default_na=False,
298
+ na_values=["TBD", "NULL", "null"],
299
+ na_filter=True,
300
+ skipinitialspace=True,
301
+ iterator=True,
302
+ chunksize=1000,
303
+ **arguments,
304
+ )
305
+ df = pd.concat(tp, ignore_index=True)
306
+ # read filename from self.filename
307
+ self._result = self.filename
308
+ elif self.data is not None:
309
+ # is already a dataframe:
310
+ df = self.data
311
+ self._result = self.data
312
+ else:
313
+ return False
314
+ if df is None or df.empty:
315
+ raise DataNotFound(f"Empty File or Data: {self.filename}")
316
+ # adding stat from dataframe:
317
+ pd.set_option("display.float_format", lambda x: "%.3f" % x)
318
+ self.add_metric("COLUMNS", df.columns)
319
+ self.add_metric("ROWS", len(df.index))
320
+ # removing empty cols
321
+ if hasattr(self, "drop_empty"):
322
+ df.dropna(axis="columns", how="all", inplace=True)
323
+ df = df.loc[:, ~df.columns.str.contains("^Unnamed")]
324
+ if hasattr(self, "dropna"):
325
+ df.dropna(subset=self.dropna, how="all", inplace=True)
326
+ if hasattr(self, "trim"):
327
+ cols = list(df.columns)
328
+ for col in cols:
329
+ df[col] = df[col].astype(str).str.strip()
330
+ if self._debug:
331
+ print(df)
332
+ # print('COLS: >> ', df.columns)
333
+ columns = df.columns
334
+ cols = []
335
+ replaced_columns = list(self.replace_names.keys())
336
+ if hasattr(self, "pre_rename"):
337
+ ### can rename columns PREVIOUS TO normalize
338
+ for col in columns:
339
+ datatype = df.dtypes[col]
340
+ try:
341
+ t = dtypes[datatype]
342
+ except KeyError:
343
+ t = str
344
+ if col in self.pre_rename:
345
+ col = self.pre_rename[col]
346
+ col = self.rename_repeated_col(col, cols)
347
+ col = self.handle_sql_reserved_word(col)
348
+ f = (col, t)
349
+ cols.append(f)
350
+ elif hasattr(self, "normalize_names"):
351
+ for col in columns:
352
+ datatypes = str(df.dtypes[col])
353
+ t = str
354
+ tmp_col = col
355
+ try:
356
+ t = dtypes[datatypes]
357
+ data = df[col].iloc[0]
358
+ if datatypes == "object":
359
+ # try to infer datatype:
360
+ if isinstance(data, str) and data != np.nan:
361
+ if data.isalpha():
362
+ t = str
363
+ else:
364
+ try:
365
+ dt = dateparser.parse(
366
+ str(data), settings={"TIMEZONE": "UTC"}
367
+ )
368
+ if isinstance(dt, datetime.datetime):
369
+ t = datetime.datetime
370
+ except (ValueError, TypeError):
371
+ pass
372
+ except KeyError:
373
+ t = str
374
+
375
+ if isinstance(col, (datetime.datetime, datetime.date)):
376
+ mask = getattr(self, "mask_datetime", "%b_%d_%Y")
377
+ new_name = datetime_to_name(col, mask)
378
+ elif is_snakecase(col):
379
+ new_name = col.strip().lower()
380
+ elif is_camelcase(col):
381
+ new_name = "_".join(
382
+ [x.lower().strip() for x in camelcase_split(col)]
383
+ )
384
+ else:
385
+ new_name = re.sub(r"[^a-zA-Z0-9_]", "", col).strip()
386
+ if hasattr(self, "normalize"):
387
+ ## making some changes on col_name:
388
+ if (
389
+ "remove_prefix" in self.normalize and self.normalize["remove_prefix"]
390
+ ):
391
+ prefix = self.normalize["remove_prefix"]
392
+ new_name = new_name.removeprefix(prefix)
393
+ if "trim" in self.normalize and self.normalize["trim"] is True:
394
+ new_name = new_name.strip()
395
+ ### remove any illegal character
396
+ new_name = remove_illegal_chars(new_name)
397
+ # re-covert again from camelCase:
398
+ if (
399
+ "camelcase" in self.normalize and self.normalize["camelcase"] is True
400
+ ):
401
+ new_name = new_name.replace(" ", "").translate(
402
+ str.maketrans("", "", "/:.")
403
+ )
404
+ new_name = re.sub(r"\([^)]*\)", "", new_name)
405
+ else:
406
+ new_name = "_".join(
407
+ [x.lower().strip() for x in camelcase_split(new_name)]
408
+ )
409
+
410
+ # Log names after basic normalization but before replace_names
411
+ if self._debug:
412
+ # Store initial normalizations for later display
413
+ if not hasattr(self, '_initial_normalizations'):
414
+ self._initial_normalizations = []
415
+
416
+ # Get type as string
417
+ type_str = getattr(t, "__name__", str(t))
418
+
419
+ # Get a sample value from the original column
420
+ sample_value = "N/A"
421
+ try:
422
+ if len(df) > 0 and col in df.columns:
423
+ sample_value = df[col].iloc[0]
424
+ except:
425
+ pass
426
+
427
+ # Store information for later display
428
+ self._initial_normalizations.append((new_name, type_str, sample_value))
429
+
430
+ # RENAMING THE COLUMN WITH A NEW NAME:
431
+ if new_name in replaced_columns:
432
+ replace = self.replace_names[new_name]
433
+ if isinstance(replace, str):
434
+ new_name = self.replace_names[new_name]
435
+ elif isinstance(replace, dict):
436
+ if "name" in replace:
437
+ new_name = replace["name"]
438
+ if "type" in replace:
439
+ try:
440
+ t = dtypes[replace["type"]]
441
+ except KeyError:
442
+ self._logger.warning(
443
+ f"Type '{replace['type']}' not found in dtypes for column '{new_name}', using default type."
444
+ )
445
+ else:
446
+ self._logger.warning(
447
+ f"Invalid replace_names value for '{new_name}': expected string or dict, got {type(replace).__name__}"
448
+ )
449
+ if new_name in self.fields:
450
+ t = dtypes[self.fields[new_name]]
451
+ new_name = self.rename_repeated_col(new_name, cols)
452
+ f = (new_name, t)
453
+ cols.append(f)
454
+ if tmp_col == new_name:
455
+ self._logger.warning(
456
+ f"The Column '{new_name}' has not normalized"
457
+ )
458
+ else:
459
+ self._logger.debug(
460
+ f" - Normalized Name: {new_name}"
461
+ )
462
+ else:
463
+ for col in columns:
464
+ datatype = df.dtypes[col]
465
+ try:
466
+ t = dtypes[datatype]
467
+ except KeyError:
468
+ t = str
469
+ col = self.rename_repeated_col(col, cols)
470
+ f = (col, t)
471
+ cols.append(f)
472
+ try:
473
+ cls = Model.make_model(
474
+ name=self.tablename,
475
+ schema=self.schema,
476
+ fields=cols
477
+ )
478
+ # Show all collected information in clean format
479
+ if hasattr(self, '_debug') and self._debug and hasattr(self, '_initial_normalizations'):
480
+ print("\n::: First Normalization columns === ")
481
+ for name, type_str, value in self._initial_normalizations:
482
+ print(f"{name} -> {type_str} -> {value}")
483
+ print("=== End :::\n")
484
+ except Exception as err:
485
+ print("ERROR:", err)
486
+ raise ComponentError(str(err)) from err
487
+ if cls:
488
+ mdl = cls() # empty model, I only need the schema
489
+ # TODO: open the metadata table and compare with model
490
+ if sql := mdl.model(dialect="sql"):
491
+ print("SQL IS ", sql)
492
+
493
+ try:
494
+ connection = await self.create_connection(driver=self._driver)
495
+
496
+ async with await connection.connection() as conn:
497
+
498
+ if self.drop is True:
499
+ self._logger.info(f"Dropping table {self.schema}.{self.tablename}")
500
+ result, error = await conn.execute(
501
+ sentence=f"DROP TABLE IF EXISTS {self.schema}.{self.tablename};"
502
+ )
503
+
504
+ self._logger.info(f"Creating table {self.schema}.{self.tablename}")
505
+ result, error = await conn.execute(sentence=sql)
506
+ if error:
507
+ self._logger.error(f"Error creating table: {error}")
508
+ raise ComponentError(f"Error on Table creation: {error}")
509
+ else:
510
+ self.add_metric("Table", result)
511
+ self._logger.info(f"Table {self.schema}.{self.tablename} created successfully")
512
+ if self._debug is True:
513
+ logging.debug(f"TableSchema: {result!s}")
514
+
515
+ # add Primary Key to table:
516
+ if hasattr(self, "pk"):
517
+ pk = pk_sentence.format(
518
+ schema=self.schema,
519
+ table=self.tablename,
520
+ fields=",".join(self.pk),
521
+ )
522
+ self._logger.info(f"Adding primary key on columns: {self.pk}")
523
+ _primary, error = await conn.execute(sentence=pk)
524
+ if error:
525
+ self._logger.warning(f"Error adding primary key: {error}")
526
+ else:
527
+ self._logger.info("Primary key added successfully")
528
+ logging.debug(f"TableSchema: PK creation: {_primary}, {error}")
529
+ except Exception as err:
530
+ self._logger.error(f"Error connecting to database: {err}")
531
+ raise ComponentError(f"Error on database connection: {err}") from err
532
+ # passthrough the previous component value:
533
+ self._result = self.input
534
+ return self.input