flowtask 5.8.4__cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (470) hide show
  1. flowtask/__init__.py +93 -0
  2. flowtask/__main__.py +38 -0
  3. flowtask/bots/__init__.py +6 -0
  4. flowtask/bots/check.py +93 -0
  5. flowtask/bots/codebot.py +51 -0
  6. flowtask/components/ASPX.py +148 -0
  7. flowtask/components/AddDataset.py +352 -0
  8. flowtask/components/Amazon.py +523 -0
  9. flowtask/components/AutoTask.py +314 -0
  10. flowtask/components/Azure.py +80 -0
  11. flowtask/components/AzureUsers.py +106 -0
  12. flowtask/components/BaseAction.py +91 -0
  13. flowtask/components/BaseLoop.py +198 -0
  14. flowtask/components/BestBuy.py +800 -0
  15. flowtask/components/CSVToGCS.py +120 -0
  16. flowtask/components/CompanyScraper/__init__.py +1 -0
  17. flowtask/components/CompanyScraper/parsers/__init__.py +6 -0
  18. flowtask/components/CompanyScraper/parsers/base.py +102 -0
  19. flowtask/components/CompanyScraper/parsers/explorium.py +192 -0
  20. flowtask/components/CompanyScraper/parsers/leadiq.py +206 -0
  21. flowtask/components/CompanyScraper/parsers/rocket.py +133 -0
  22. flowtask/components/CompanyScraper/parsers/siccode.py +109 -0
  23. flowtask/components/CompanyScraper/parsers/visualvisitor.py +130 -0
  24. flowtask/components/CompanyScraper/parsers/zoominfo.py +118 -0
  25. flowtask/components/CompanyScraper/scrapper.py +1054 -0
  26. flowtask/components/CopyTo.py +177 -0
  27. flowtask/components/CopyToBigQuery.py +243 -0
  28. flowtask/components/CopyToMongoDB.py +291 -0
  29. flowtask/components/CopyToPg.py +609 -0
  30. flowtask/components/CopyToRethink.py +207 -0
  31. flowtask/components/CreateGCSBucket.py +102 -0
  32. flowtask/components/CreateReport/CreateReport.py +228 -0
  33. flowtask/components/CreateReport/__init__.py +9 -0
  34. flowtask/components/CreateReport/charts/__init__.py +15 -0
  35. flowtask/components/CreateReport/charts/bar.py +51 -0
  36. flowtask/components/CreateReport/charts/base.py +66 -0
  37. flowtask/components/CreateReport/charts/pie.py +64 -0
  38. flowtask/components/CreateReport/utils.py +9 -0
  39. flowtask/components/CustomerSatisfaction.py +196 -0
  40. flowtask/components/DataInput.py +200 -0
  41. flowtask/components/DateList.py +255 -0
  42. flowtask/components/DbClient.py +163 -0
  43. flowtask/components/DialPad.py +146 -0
  44. flowtask/components/DocumentDBQuery.py +200 -0
  45. flowtask/components/DownloadFrom.py +371 -0
  46. flowtask/components/DownloadFromD2L.py +113 -0
  47. flowtask/components/DownloadFromFTP.py +181 -0
  48. flowtask/components/DownloadFromIMAP.py +315 -0
  49. flowtask/components/DownloadFromS3.py +198 -0
  50. flowtask/components/DownloadFromSFTP.py +265 -0
  51. flowtask/components/DownloadFromSharepoint.py +110 -0
  52. flowtask/components/DownloadFromSmartSheet.py +114 -0
  53. flowtask/components/DownloadS3File.py +229 -0
  54. flowtask/components/Dummy.py +59 -0
  55. flowtask/components/DuplicatePhoto.py +411 -0
  56. flowtask/components/EmployeeEvaluation.py +237 -0
  57. flowtask/components/ExecuteSQL.py +323 -0
  58. flowtask/components/ExtractHTML.py +178 -0
  59. flowtask/components/FileBase.py +178 -0
  60. flowtask/components/FileCopy.py +181 -0
  61. flowtask/components/FileDelete.py +82 -0
  62. flowtask/components/FileExists.py +146 -0
  63. flowtask/components/FileIteratorDelete.py +112 -0
  64. flowtask/components/FileList.py +194 -0
  65. flowtask/components/FileOpen.py +75 -0
  66. flowtask/components/FileRead.py +120 -0
  67. flowtask/components/FileRename.py +106 -0
  68. flowtask/components/FilterIf.py +284 -0
  69. flowtask/components/FilterRows/FilterRows.py +200 -0
  70. flowtask/components/FilterRows/__init__.py +10 -0
  71. flowtask/components/FilterRows/functions.py +4 -0
  72. flowtask/components/GCSToBigQuery.py +103 -0
  73. flowtask/components/GoogleA4.py +150 -0
  74. flowtask/components/GoogleGeoCoding.py +344 -0
  75. flowtask/components/GooglePlaces.py +315 -0
  76. flowtask/components/GoogleSearch.py +539 -0
  77. flowtask/components/HTTPClient.py +268 -0
  78. flowtask/components/ICIMS.py +146 -0
  79. flowtask/components/IF.py +179 -0
  80. flowtask/components/IcimsFolderCopy.py +173 -0
  81. flowtask/components/ImageFeatures/__init__.py +5 -0
  82. flowtask/components/ImageFeatures/process.py +233 -0
  83. flowtask/components/IteratorBase.py +251 -0
  84. flowtask/components/LangchainLoader/__init__.py +5 -0
  85. flowtask/components/LangchainLoader/loader.py +194 -0
  86. flowtask/components/LangchainLoader/loaders/__init__.py +22 -0
  87. flowtask/components/LangchainLoader/loaders/abstract.py +362 -0
  88. flowtask/components/LangchainLoader/loaders/basepdf.py +50 -0
  89. flowtask/components/LangchainLoader/loaders/docx.py +91 -0
  90. flowtask/components/LangchainLoader/loaders/html.py +119 -0
  91. flowtask/components/LangchainLoader/loaders/pdfblocks.py +146 -0
  92. flowtask/components/LangchainLoader/loaders/pdfmark.py +79 -0
  93. flowtask/components/LangchainLoader/loaders/pdftables.py +135 -0
  94. flowtask/components/LangchainLoader/loaders/qa.py +67 -0
  95. flowtask/components/LangchainLoader/loaders/txt.py +55 -0
  96. flowtask/components/LeadIQ.py +650 -0
  97. flowtask/components/Loop.py +253 -0
  98. flowtask/components/Lowes.py +334 -0
  99. flowtask/components/MS365Usage.py +156 -0
  100. flowtask/components/MSTeamsMessages.py +320 -0
  101. flowtask/components/MarketClustering.py +1051 -0
  102. flowtask/components/MergeFiles.py +362 -0
  103. flowtask/components/MilvusOutput.py +87 -0
  104. flowtask/components/NearByStores.py +175 -0
  105. flowtask/components/NetworkNinja/__init__.py +6 -0
  106. flowtask/components/NetworkNinja/models/__init__.py +52 -0
  107. flowtask/components/NetworkNinja/models/abstract.py +177 -0
  108. flowtask/components/NetworkNinja/models/account.py +39 -0
  109. flowtask/components/NetworkNinja/models/client.py +19 -0
  110. flowtask/components/NetworkNinja/models/district.py +14 -0
  111. flowtask/components/NetworkNinja/models/events.py +101 -0
  112. flowtask/components/NetworkNinja/models/forms.py +499 -0
  113. flowtask/components/NetworkNinja/models/market.py +16 -0
  114. flowtask/components/NetworkNinja/models/organization.py +34 -0
  115. flowtask/components/NetworkNinja/models/photos.py +125 -0
  116. flowtask/components/NetworkNinja/models/project.py +44 -0
  117. flowtask/components/NetworkNinja/models/region.py +28 -0
  118. flowtask/components/NetworkNinja/models/store.py +203 -0
  119. flowtask/components/NetworkNinja/models/user.py +151 -0
  120. flowtask/components/NetworkNinja/router.py +854 -0
  121. flowtask/components/Odoo.py +175 -0
  122. flowtask/components/OdooInjector.py +192 -0
  123. flowtask/components/OpenFromXML.py +126 -0
  124. flowtask/components/OpenWeather.py +41 -0
  125. flowtask/components/OpenWithBase.py +616 -0
  126. flowtask/components/OpenWithPandas.py +715 -0
  127. flowtask/components/PGPDecrypt.py +199 -0
  128. flowtask/components/PandasIterator.py +187 -0
  129. flowtask/components/PandasToFile.py +189 -0
  130. flowtask/components/Paradox.py +339 -0
  131. flowtask/components/ParamIterator.py +117 -0
  132. flowtask/components/ParseHTML.py +84 -0
  133. flowtask/components/PlacerStores.py +249 -0
  134. flowtask/components/Pokemon.py +507 -0
  135. flowtask/components/PositiveBot.py +62 -0
  136. flowtask/components/PowerPointSlide.py +400 -0
  137. flowtask/components/PrintMessage.py +127 -0
  138. flowtask/components/ProductCompetitors/__init__.py +5 -0
  139. flowtask/components/ProductCompetitors/parsers/__init__.py +7 -0
  140. flowtask/components/ProductCompetitors/parsers/base.py +72 -0
  141. flowtask/components/ProductCompetitors/parsers/bestbuy.py +86 -0
  142. flowtask/components/ProductCompetitors/parsers/lowes.py +103 -0
  143. flowtask/components/ProductCompetitors/scrapper.py +155 -0
  144. flowtask/components/ProductCompliant.py +169 -0
  145. flowtask/components/ProductInfo/__init__.py +1 -0
  146. flowtask/components/ProductInfo/parsers/__init__.py +5 -0
  147. flowtask/components/ProductInfo/parsers/base.py +83 -0
  148. flowtask/components/ProductInfo/parsers/brother.py +97 -0
  149. flowtask/components/ProductInfo/parsers/canon.py +167 -0
  150. flowtask/components/ProductInfo/parsers/epson.py +118 -0
  151. flowtask/components/ProductInfo/parsers/hp.py +131 -0
  152. flowtask/components/ProductInfo/parsers/samsung.py +97 -0
  153. flowtask/components/ProductInfo/scraper.py +319 -0
  154. flowtask/components/ProductPricing.py +118 -0
  155. flowtask/components/QS.py +261 -0
  156. flowtask/components/QSBase.py +201 -0
  157. flowtask/components/QueryIterator.py +273 -0
  158. flowtask/components/QueryToInsert.py +327 -0
  159. flowtask/components/QueryToPandas.py +432 -0
  160. flowtask/components/RESTClient.py +195 -0
  161. flowtask/components/RethinkDBQuery.py +189 -0
  162. flowtask/components/Rsync.py +74 -0
  163. flowtask/components/RunSSH.py +59 -0
  164. flowtask/components/RunShell.py +71 -0
  165. flowtask/components/SalesForce.py +20 -0
  166. flowtask/components/SaveImageBank/__init__.py +257 -0
  167. flowtask/components/SchedulingVisits.py +592 -0
  168. flowtask/components/ScrapPage.py +216 -0
  169. flowtask/components/ScrapSearch.py +79 -0
  170. flowtask/components/SendNotify.py +257 -0
  171. flowtask/components/SentimentAnalysis.py +694 -0
  172. flowtask/components/ServiceScrapper/__init__.py +5 -0
  173. flowtask/components/ServiceScrapper/parsers/__init__.py +1 -0
  174. flowtask/components/ServiceScrapper/parsers/base.py +94 -0
  175. flowtask/components/ServiceScrapper/parsers/costco.py +93 -0
  176. flowtask/components/ServiceScrapper/scrapper.py +199 -0
  177. flowtask/components/SetVariables.py +156 -0
  178. flowtask/components/SubTask.py +182 -0
  179. flowtask/components/SuiteCRM.py +48 -0
  180. flowtask/components/Switch.py +175 -0
  181. flowtask/components/TableBase.py +148 -0
  182. flowtask/components/TableDelete.py +312 -0
  183. flowtask/components/TableInput.py +143 -0
  184. flowtask/components/TableOutput/TableOutput.py +384 -0
  185. flowtask/components/TableOutput/__init__.py +3 -0
  186. flowtask/components/TableSchema.py +534 -0
  187. flowtask/components/Target.py +223 -0
  188. flowtask/components/ThumbnailGenerator.py +156 -0
  189. flowtask/components/ToPandas.py +67 -0
  190. flowtask/components/TransformRows/TransformRows.py +507 -0
  191. flowtask/components/TransformRows/__init__.py +9 -0
  192. flowtask/components/TransformRows/functions.py +559 -0
  193. flowtask/components/TransposeRows.py +176 -0
  194. flowtask/components/UPCDatabase.py +86 -0
  195. flowtask/components/UnGzip.py +171 -0
  196. flowtask/components/Uncompress.py +172 -0
  197. flowtask/components/UniqueRows.py +126 -0
  198. flowtask/components/Unzip.py +107 -0
  199. flowtask/components/UpdateOperationalVars.py +147 -0
  200. flowtask/components/UploadTo.py +299 -0
  201. flowtask/components/UploadToS3.py +136 -0
  202. flowtask/components/UploadToSFTP.py +160 -0
  203. flowtask/components/UploadToSharepoint.py +205 -0
  204. flowtask/components/UserFunc.py +122 -0
  205. flowtask/components/VivaTracker.py +140 -0
  206. flowtask/components/WSDLClient.py +123 -0
  207. flowtask/components/Wait.py +18 -0
  208. flowtask/components/Walmart.py +199 -0
  209. flowtask/components/Workplace.py +134 -0
  210. flowtask/components/XMLToPandas.py +267 -0
  211. flowtask/components/Zammad/__init__.py +41 -0
  212. flowtask/components/Zammad/models.py +0 -0
  213. flowtask/components/ZoomInfoScraper.py +409 -0
  214. flowtask/components/__init__.py +104 -0
  215. flowtask/components/abstract.py +18 -0
  216. flowtask/components/flow.py +530 -0
  217. flowtask/components/google.py +335 -0
  218. flowtask/components/group.py +221 -0
  219. flowtask/components/py.typed +0 -0
  220. flowtask/components/reviewscrap.py +132 -0
  221. flowtask/components/tAutoincrement.py +117 -0
  222. flowtask/components/tConcat.py +109 -0
  223. flowtask/components/tExplode.py +119 -0
  224. flowtask/components/tFilter.py +184 -0
  225. flowtask/components/tGroup.py +236 -0
  226. flowtask/components/tJoin.py +270 -0
  227. flowtask/components/tMap/__init__.py +9 -0
  228. flowtask/components/tMap/functions.py +54 -0
  229. flowtask/components/tMap/tMap.py +450 -0
  230. flowtask/components/tMelt.py +112 -0
  231. flowtask/components/tMerge.py +114 -0
  232. flowtask/components/tOrder.py +93 -0
  233. flowtask/components/tPandas.py +94 -0
  234. flowtask/components/tPivot.py +71 -0
  235. flowtask/components/tPluckCols.py +76 -0
  236. flowtask/components/tUnnest.py +82 -0
  237. flowtask/components/user.py +401 -0
  238. flowtask/conf.py +457 -0
  239. flowtask/download.py +102 -0
  240. flowtask/events/__init__.py +11 -0
  241. flowtask/events/events/__init__.py +20 -0
  242. flowtask/events/events/abstract.py +95 -0
  243. flowtask/events/events/alerts/__init__.py +362 -0
  244. flowtask/events/events/alerts/colfunctions.py +131 -0
  245. flowtask/events/events/alerts/functions.py +158 -0
  246. flowtask/events/events/dummy.py +12 -0
  247. flowtask/events/events/exec.py +124 -0
  248. flowtask/events/events/file/__init__.py +7 -0
  249. flowtask/events/events/file/base.py +51 -0
  250. flowtask/events/events/file/copy.py +23 -0
  251. flowtask/events/events/file/delete.py +16 -0
  252. flowtask/events/events/interfaces/__init__.py +9 -0
  253. flowtask/events/events/interfaces/client.py +67 -0
  254. flowtask/events/events/interfaces/credentials.py +28 -0
  255. flowtask/events/events/interfaces/notifications.py +58 -0
  256. flowtask/events/events/jira.py +122 -0
  257. flowtask/events/events/log.py +26 -0
  258. flowtask/events/events/logerr.py +52 -0
  259. flowtask/events/events/notify.py +59 -0
  260. flowtask/events/events/notify_event.py +160 -0
  261. flowtask/events/events/publish.py +54 -0
  262. flowtask/events/events/sendfile.py +104 -0
  263. flowtask/events/events/task.py +97 -0
  264. flowtask/events/events/teams.py +98 -0
  265. flowtask/events/events/webhook.py +58 -0
  266. flowtask/events/manager.py +287 -0
  267. flowtask/exceptions.c +39393 -0
  268. flowtask/exceptions.cpython-310-x86_64-linux-gnu.so +0 -0
  269. flowtask/extensions/__init__.py +3 -0
  270. flowtask/extensions/abstract.py +82 -0
  271. flowtask/extensions/logging/__init__.py +65 -0
  272. flowtask/hooks/__init__.py +9 -0
  273. flowtask/hooks/actions/__init__.py +22 -0
  274. flowtask/hooks/actions/abstract.py +66 -0
  275. flowtask/hooks/actions/dummy.py +23 -0
  276. flowtask/hooks/actions/jira.py +74 -0
  277. flowtask/hooks/actions/rest.py +320 -0
  278. flowtask/hooks/actions/sampledata.py +37 -0
  279. flowtask/hooks/actions/sensor.py +23 -0
  280. flowtask/hooks/actions/task.py +9 -0
  281. flowtask/hooks/actions/ticket.py +37 -0
  282. flowtask/hooks/actions/zammad.py +55 -0
  283. flowtask/hooks/hook.py +62 -0
  284. flowtask/hooks/models.py +17 -0
  285. flowtask/hooks/service.py +187 -0
  286. flowtask/hooks/step.py +91 -0
  287. flowtask/hooks/types/__init__.py +23 -0
  288. flowtask/hooks/types/base.py +129 -0
  289. flowtask/hooks/types/brokers/__init__.py +11 -0
  290. flowtask/hooks/types/brokers/base.py +54 -0
  291. flowtask/hooks/types/brokers/mqtt.py +35 -0
  292. flowtask/hooks/types/brokers/rabbitmq.py +82 -0
  293. flowtask/hooks/types/brokers/redis.py +83 -0
  294. flowtask/hooks/types/brokers/sqs.py +44 -0
  295. flowtask/hooks/types/fs.py +232 -0
  296. flowtask/hooks/types/http.py +49 -0
  297. flowtask/hooks/types/imap.py +200 -0
  298. flowtask/hooks/types/jira.py +279 -0
  299. flowtask/hooks/types/mail.py +205 -0
  300. flowtask/hooks/types/postgres.py +98 -0
  301. flowtask/hooks/types/responses/__init__.py +8 -0
  302. flowtask/hooks/types/responses/base.py +5 -0
  303. flowtask/hooks/types/sharepoint.py +288 -0
  304. flowtask/hooks/types/ssh.py +141 -0
  305. flowtask/hooks/types/tagged.py +59 -0
  306. flowtask/hooks/types/upload.py +85 -0
  307. flowtask/hooks/types/watch.py +71 -0
  308. flowtask/hooks/types/web.py +36 -0
  309. flowtask/interfaces/AzureClient.py +137 -0
  310. flowtask/interfaces/AzureGraph.py +839 -0
  311. flowtask/interfaces/Boto3Client.py +326 -0
  312. flowtask/interfaces/DropboxClient.py +173 -0
  313. flowtask/interfaces/ExcelHandler.py +94 -0
  314. flowtask/interfaces/FTPClient.py +131 -0
  315. flowtask/interfaces/GoogleCalendar.py +201 -0
  316. flowtask/interfaces/GoogleClient.py +133 -0
  317. flowtask/interfaces/GoogleDrive.py +127 -0
  318. flowtask/interfaces/GoogleGCS.py +89 -0
  319. flowtask/interfaces/GoogleGeocoding.py +93 -0
  320. flowtask/interfaces/GoogleLang.py +114 -0
  321. flowtask/interfaces/GooglePub.py +61 -0
  322. flowtask/interfaces/GoogleSheet.py +68 -0
  323. flowtask/interfaces/IMAPClient.py +137 -0
  324. flowtask/interfaces/O365Calendar.py +113 -0
  325. flowtask/interfaces/O365Client.py +220 -0
  326. flowtask/interfaces/OneDrive.py +284 -0
  327. flowtask/interfaces/Outlook.py +155 -0
  328. flowtask/interfaces/ParrotBot.py +130 -0
  329. flowtask/interfaces/SSHClient.py +378 -0
  330. flowtask/interfaces/Sharepoint.py +496 -0
  331. flowtask/interfaces/__init__.py +36 -0
  332. flowtask/interfaces/azureauth.py +119 -0
  333. flowtask/interfaces/cache.py +201 -0
  334. flowtask/interfaces/client.py +82 -0
  335. flowtask/interfaces/compress.py +525 -0
  336. flowtask/interfaces/credentials.py +124 -0
  337. flowtask/interfaces/d2l.py +239 -0
  338. flowtask/interfaces/databases/__init__.py +5 -0
  339. flowtask/interfaces/databases/db.py +223 -0
  340. flowtask/interfaces/databases/documentdb.py +55 -0
  341. flowtask/interfaces/databases/rethink.py +39 -0
  342. flowtask/interfaces/dataframes/__init__.py +11 -0
  343. flowtask/interfaces/dataframes/abstract.py +21 -0
  344. flowtask/interfaces/dataframes/arrow.py +71 -0
  345. flowtask/interfaces/dataframes/dt.py +69 -0
  346. flowtask/interfaces/dataframes/pandas.py +167 -0
  347. flowtask/interfaces/dataframes/polars.py +60 -0
  348. flowtask/interfaces/db.py +263 -0
  349. flowtask/interfaces/env.py +46 -0
  350. flowtask/interfaces/func.py +137 -0
  351. flowtask/interfaces/http.py +1780 -0
  352. flowtask/interfaces/locale.py +40 -0
  353. flowtask/interfaces/log.py +75 -0
  354. flowtask/interfaces/mask.py +143 -0
  355. flowtask/interfaces/notification.py +154 -0
  356. flowtask/interfaces/playwright.py +339 -0
  357. flowtask/interfaces/powerpoint.py +368 -0
  358. flowtask/interfaces/py.typed +0 -0
  359. flowtask/interfaces/qs.py +376 -0
  360. flowtask/interfaces/result.py +87 -0
  361. flowtask/interfaces/selenium_service.py +779 -0
  362. flowtask/interfaces/smartsheet.py +154 -0
  363. flowtask/interfaces/stat.py +39 -0
  364. flowtask/interfaces/task.py +96 -0
  365. flowtask/interfaces/template.py +118 -0
  366. flowtask/interfaces/vectorstores/__init__.py +1 -0
  367. flowtask/interfaces/vectorstores/abstract.py +133 -0
  368. flowtask/interfaces/vectorstores/milvus.py +669 -0
  369. flowtask/interfaces/zammad.py +107 -0
  370. flowtask/models.py +193 -0
  371. flowtask/parsers/__init__.py +15 -0
  372. flowtask/parsers/_yaml.c +11978 -0
  373. flowtask/parsers/_yaml.cpython-310-x86_64-linux-gnu.so +0 -0
  374. flowtask/parsers/argparser.py +235 -0
  375. flowtask/parsers/base.c +15155 -0
  376. flowtask/parsers/base.cpython-310-x86_64-linux-gnu.so +0 -0
  377. flowtask/parsers/json.c +11968 -0
  378. flowtask/parsers/json.cpython-310-x86_64-linux-gnu.so +0 -0
  379. flowtask/parsers/maps.py +49 -0
  380. flowtask/parsers/toml.c +11968 -0
  381. flowtask/parsers/toml.cpython-310-x86_64-linux-gnu.so +0 -0
  382. flowtask/plugins/__init__.py +16 -0
  383. flowtask/plugins/components/__init__.py +0 -0
  384. flowtask/plugins/handler/__init__.py +45 -0
  385. flowtask/plugins/importer.py +31 -0
  386. flowtask/plugins/sources/__init__.py +0 -0
  387. flowtask/runner.py +283 -0
  388. flowtask/scheduler/__init__.py +9 -0
  389. flowtask/scheduler/functions.py +493 -0
  390. flowtask/scheduler/handlers/__init__.py +8 -0
  391. flowtask/scheduler/handlers/manager.py +504 -0
  392. flowtask/scheduler/handlers/models.py +58 -0
  393. flowtask/scheduler/handlers/service.py +72 -0
  394. flowtask/scheduler/notifications.py +65 -0
  395. flowtask/scheduler/scheduler.py +993 -0
  396. flowtask/services/__init__.py +0 -0
  397. flowtask/services/bots/__init__.py +0 -0
  398. flowtask/services/bots/telegram.py +264 -0
  399. flowtask/services/files/__init__.py +11 -0
  400. flowtask/services/files/manager.py +522 -0
  401. flowtask/services/files/model.py +37 -0
  402. flowtask/services/files/service.py +767 -0
  403. flowtask/services/jira/__init__.py +3 -0
  404. flowtask/services/jira/jira_actions.py +191 -0
  405. flowtask/services/tasks/__init__.py +13 -0
  406. flowtask/services/tasks/launcher.py +213 -0
  407. flowtask/services/tasks/manager.py +323 -0
  408. flowtask/services/tasks/service.py +275 -0
  409. flowtask/services/tasks/task_manager.py +376 -0
  410. flowtask/services/tasks/tasks.py +155 -0
  411. flowtask/storages/__init__.py +16 -0
  412. flowtask/storages/exceptions.py +12 -0
  413. flowtask/storages/files/__init__.py +8 -0
  414. flowtask/storages/files/abstract.py +29 -0
  415. flowtask/storages/files/filesystem.py +66 -0
  416. flowtask/storages/tasks/__init__.py +19 -0
  417. flowtask/storages/tasks/abstract.py +26 -0
  418. flowtask/storages/tasks/database.py +33 -0
  419. flowtask/storages/tasks/filesystem.py +108 -0
  420. flowtask/storages/tasks/github.py +119 -0
  421. flowtask/storages/tasks/memory.py +45 -0
  422. flowtask/storages/tasks/row.py +25 -0
  423. flowtask/tasks/__init__.py +0 -0
  424. flowtask/tasks/abstract.py +526 -0
  425. flowtask/tasks/command.py +118 -0
  426. flowtask/tasks/pile.py +486 -0
  427. flowtask/tasks/py.typed +0 -0
  428. flowtask/tasks/task.py +778 -0
  429. flowtask/template/__init__.py +161 -0
  430. flowtask/tests.py +257 -0
  431. flowtask/types/__init__.py +8 -0
  432. flowtask/types/typedefs.c +11347 -0
  433. flowtask/types/typedefs.cpython-310-x86_64-linux-gnu.so +0 -0
  434. flowtask/utils/__init__.py +24 -0
  435. flowtask/utils/constants.py +117 -0
  436. flowtask/utils/encoders.py +21 -0
  437. flowtask/utils/executor.py +112 -0
  438. flowtask/utils/functions.cpp +14280 -0
  439. flowtask/utils/functions.cpython-310-x86_64-linux-gnu.so +0 -0
  440. flowtask/utils/json.cpp +13349 -0
  441. flowtask/utils/json.cpython-310-x86_64-linux-gnu.so +0 -0
  442. flowtask/utils/mail.py +63 -0
  443. flowtask/utils/parseqs.c +13324 -0
  444. flowtask/utils/parserqs.cpython-310-x86_64-linux-gnu.so +0 -0
  445. flowtask/utils/stats.py +308 -0
  446. flowtask/utils/transformations.py +74 -0
  447. flowtask/utils/uv.py +12 -0
  448. flowtask/utils/validators.py +97 -0
  449. flowtask/version.py +11 -0
  450. flowtask-5.8.4.dist-info/LICENSE +201 -0
  451. flowtask-5.8.4.dist-info/METADATA +209 -0
  452. flowtask-5.8.4.dist-info/RECORD +470 -0
  453. flowtask-5.8.4.dist-info/WHEEL +6 -0
  454. flowtask-5.8.4.dist-info/entry_points.txt +3 -0
  455. flowtask-5.8.4.dist-info/top_level.txt +2 -0
  456. plugins/components/CreateQR.py +39 -0
  457. plugins/components/TestComponent.py +28 -0
  458. plugins/components/Use1.py +13 -0
  459. plugins/components/Workplace.py +117 -0
  460. plugins/components/__init__.py +3 -0
  461. plugins/sources/__init__.py +0 -0
  462. plugins/sources/get_populartimes.py +78 -0
  463. plugins/sources/google.py +150 -0
  464. plugins/sources/hubspot.py +679 -0
  465. plugins/sources/icims.py +679 -0
  466. plugins/sources/mobileinsight.py +501 -0
  467. plugins/sources/newrelic.py +262 -0
  468. plugins/sources/uap.py +268 -0
  469. plugins/sources/venu.py +244 -0
  470. plugins/sources/vocinity.py +314 -0
@@ -0,0 +1,253 @@
1
+ from collections.abc import Callable, Awaitable
2
+ import asyncio
3
+ from typing import Any
4
+ from pandas import DataFrame
5
+ from asyncdb.exceptions import NoDataFound, ProviderError, DriverError
6
+ from .flow import FlowComponent
7
+ from ..exceptions import (
8
+ ComponentError,
9
+ DataNotFound,
10
+ NotSupported,
11
+ FileNotFound
12
+ )
13
+ from ..utils.stats import StepMonitor
14
+ from ..interfaces.log import SkipErrors
15
+
16
+
17
+ class Loop(FlowComponent):
18
+ """Loop.
19
+
20
+ Overview:
21
+ The Loop class is a FlowComponent that is used to iterate over the next Component and execute them in a
22
+ sequential order.
23
+ It extends the FlowComponent class and provides methods for starting tasks, retrieving steps,
24
+ and executing jobs asynchronously.
25
+
26
+ """
27
+ def __init__(
28
+ self,
29
+ loop: asyncio.AbstractEventLoop = None,
30
+ job: Callable = None,
31
+ stat: Callable = None,
32
+ **kwargs,
33
+ ):
34
+ self._conditions: dict = {}
35
+ self._generator = kwargs.get("generator", None) # Predefined generator
36
+ self._iterate: bool = kwargs.get('iterate', False)
37
+ self._iterable = kwargs.get("iterable", None) # Custom iterable
38
+ self._done: bool = False # Flag to indicate if iteration is complete
39
+ # Component to be executed when finished.
40
+ self._ondone: str = kwargs.get("onDone", None)
41
+ super(Loop, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
42
+
43
+ async def start(self, **kwargs):
44
+ """
45
+ start.
46
+
47
+ Initialize (if needed) a task
48
+ """
49
+ if self.previous:
50
+ self.data = self.input
51
+
52
+ # check if previous data is an iterable:
53
+ if isinstance(self.data, DataFrame):
54
+ self._iterable = self.data.iterrows()
55
+ elif self._iterate is True or hasattr(self.data, '__iter__'):
56
+ self._iterable = self.data
57
+ elif self._generator:
58
+ self._iterable = self._resolve_generator(self._generator)
59
+ elif self._iterable and not hasattr(self._iterable, "__iter__"):
60
+ raise ComponentError(
61
+ "'iterable' must be an iterable object."
62
+ )
63
+
64
+ self._iterator = iter(self._iterable)
65
+ return True
66
+
67
+ def _resolve_generator(self, generator_name):
68
+ """
69
+ Resolve predefined generators like 'days_of_week' or 'days_of_month'.
70
+ """
71
+ # Define predefined generators here.
72
+ # Each generator should return a list of values.
73
+ # For example, 'days_of_week' could return a list of weekdays,
74
+ # and 'days_of_month' could return a list of days of the month.
75
+ predefined_generators = {
76
+ "days_of_week": lambda: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
77
+ "days_of_month": lambda: [f"Day {i}" for i in range(1, 32)],
78
+ }
79
+ if generator_name not in predefined_generators:
80
+ raise ComponentError(
81
+ f"Unknown generator: {generator_name}"
82
+ )
83
+ return predefined_generators[generator_name]()
84
+
85
+ async def close(self):
86
+ pass
87
+
88
+ def get_component(self, step, idx):
89
+ params = None
90
+ try:
91
+ if not self._TaskPile:
92
+ raise ComponentError(
93
+ "No Components in TaskPile"
94
+ )
95
+ params = step.params()
96
+ try:
97
+ if params["conditions"]:
98
+ self._conditions[step.name] = params["conditions"]
99
+ except KeyError:
100
+ pass
101
+ params["ENV"] = self._environment
102
+ # params
103
+ params["params"] = self._params
104
+ # parameters
105
+ params["parameters"] = self._parameters
106
+ # useful to change variables in set var components
107
+ params["_vars"] = self._vars
108
+ # variables dictionary
109
+ params["variables"] = self._variables
110
+ params["_args"] = self._args
111
+ # argument list for components (or tasks) that need argument lists
112
+ params["arguments"] = self._arguments
113
+ # for components with conditions, we can add more conditions
114
+ conditions = params.get("conditions", {})
115
+ step_conds = self._conditions.get(step.name, {})
116
+ if self.conditions is not None:
117
+ step_conds = {**self.conditions, **step_conds}
118
+ params["conditions"] = {**conditions, **step_conds}
119
+ # attributes only usable component-only
120
+ params["attributes"] = self._attributes
121
+ # the current Pile of components
122
+ params["TaskPile"] = self._TaskPile
123
+ # params['TaskName'] = step_name
124
+ params["debug"] = self._debug
125
+ params["argparser"] = self._argparser
126
+ # the current in-memory connector
127
+ params["memory"] = self._memory
128
+ target = step.component
129
+ # remove this element from tasks, doesn't need to run again
130
+ self._TaskPile.delStep(idx)
131
+ # return target and params
132
+ return [target, params]
133
+ finally:
134
+ pass
135
+
136
+ def create_component(self, target, value: Any = None, **params):
137
+ """get_component.
138
+
139
+ Create a new component instance.
140
+ """
141
+ try:
142
+ return target(
143
+ job=self,
144
+ loop=self._loop,
145
+ stat=self.stat,
146
+ input_result=value,
147
+ **params
148
+ )
149
+ except Exception as err:
150
+ raise ComponentError(
151
+ f"Component Error on {target}: {err}"
152
+ ) from err
153
+
154
+ async def exec_component(self, job, step_name):
155
+ start = getattr(job, "start", None)
156
+ if callable(start):
157
+ try:
158
+ if asyncio.iscoroutinefunction(start):
159
+ st = await job.start()
160
+ else:
161
+ st = job.start()
162
+ self._logger.debug(f"STARTED: {st}")
163
+ except (NoDataFound, DataNotFound) as err:
164
+ raise DataNotFound(f"{err!s}") from err
165
+ except (ProviderError, ComponentError, NotSupported) as err:
166
+ raise ComponentError(
167
+ f"Error running Start Function on {step_name}, error: {err}"
168
+ ) from err
169
+ else:
170
+ raise ComponentError(
171
+ f"Error running Function on {step_name}"
172
+ )
173
+ try:
174
+ run = getattr(job, "run", None)
175
+ if asyncio.iscoroutinefunction(run):
176
+ result = await job.run()
177
+ else:
178
+ result = job.run()
179
+ self._result = result
180
+ return self._result
181
+ except (NoDataFound, DataNotFound, FileNotFound) as err:
182
+ try:
183
+ if job.skipError == SkipErrors.SKIP:
184
+ self._logger.warning(
185
+ f"Component {job!s} was Skipped, error: {err}"
186
+ )
187
+ self._result = self.data
188
+ return self._result
189
+ elif job.skipError == SkipErrors.ENFORCE:
190
+ # Enforcing to Raise Error:
191
+ raise DataNotFound(f"{err!s}") from err
192
+ else:
193
+ # Log Only
194
+ self._logger.error(
195
+ f"Component {job!s} was Skipped, error: {err}"
196
+ )
197
+ except AttributeError:
198
+ raise DataNotFound(f"{err!s}") from err
199
+ except (ProviderError, ComponentError, NotSupported) as err:
200
+ raise NotSupported(
201
+ f"Error running Component {step_name}, error: {err}"
202
+ ) from err
203
+ except Exception as err:
204
+ self._logger.exception(err, exc_info=True)
205
+ raise ComponentError(
206
+ f"Iterator Error on {step_name}, error: {err}"
207
+ ) from err
208
+ finally:
209
+ try:
210
+ close = getattr(job, "close", None)
211
+ if asyncio.iscoroutinefunction(close):
212
+ await job.close()
213
+ else:
214
+ job.close()
215
+ except Exception:
216
+ pass
217
+
218
+ async def run(self):
219
+ """Async Run Method."""
220
+ # iterate over next Component
221
+ step, idx = self._TaskPile.nextStep(self.StepName)
222
+ target, params = self.get_component(step, idx)
223
+ step_name = step.name
224
+ i = 0
225
+ results = []
226
+ while True:
227
+ try:
228
+ # Get the next item from the iterator
229
+ item = next(self._iterator)
230
+ self.setTaskVar('value', item)
231
+ cp = self.create_component(target, item, **params)
232
+ try:
233
+ result = await self.exec_component(cp, step_name)
234
+ results.append(result)
235
+ i += 1
236
+ except (NoDataFound, DataNotFound) as err:
237
+ # its a data component a no data was found
238
+ self._logger.notice(
239
+ f"Data not Found over {step_name} at {i} iteration, got: {err}"
240
+ )
241
+ i += 1
242
+ continue
243
+ except StopIteration:
244
+ self._done = True
245
+ break # Exit loop when iteration is complete
246
+ # when iteration is finished, return the results collected:
247
+ if self.stat:
248
+ parent_stat = self.stat.parent()
249
+ stat = StepMonitor(name=step_name, parent=parent_stat)
250
+ parent_stat.add_step(stat)
251
+ stat.add_metric('ITERATIONS', i)
252
+ self._result = results
253
+ return self._result
@@ -0,0 +1,334 @@
1
+ """
2
+ Scrapping a Web Page Using Selenium + ChromeDriver + BeautifulSoup.
3
+
4
+
5
+ Example:
6
+
7
+ ```yaml
8
+ Lowes:
9
+ type: reviews
10
+ use_proxies: true
11
+ paid_proxy: true
12
+ api_token: xxx
13
+ ```
14
+
15
+ """
16
+ import asyncio
17
+ from collections.abc import Callable
18
+ import random
19
+ import httpx
20
+ import pandas as pd
21
+ import backoff
22
+ # Internals
23
+ from ..exceptions import (
24
+ ComponentError,
25
+ ConfigError,
26
+ NotSupported
27
+ )
28
+ from ..interfaces.http import ua
29
+ from .reviewscrap import ReviewScrapper, bad_gateway_exception
30
+
31
+
32
+ class Lowes(ReviewScrapper):
33
+ """Lowes.
34
+
35
+ Combining API Key and Web Scrapping, this component will be able to extract
36
+ Lowes Information (reviews, etc).
37
+ """
38
+ def __init__(
39
+ self,
40
+ loop: asyncio.AbstractEventLoop = None,
41
+ job: Callable = None,
42
+ stat: Callable = None,
43
+ **kwargs,
44
+ ):
45
+ super(Lowes, self).__init__(
46
+ loop=loop,
47
+ job=job,
48
+ stat=stat,
49
+ **kwargs
50
+ )
51
+ # Always use proxies:
52
+ self.use_proxy: bool = True
53
+ self._free_proxy: bool = False
54
+ self.cookies = {
55
+ "dbidv2": "956aa8ea-87f3-4068-96a8-3e2bdf4e84ec",
56
+ "al_sess": "FuA4EWsuT07UWryyq/3foLUcOGRVVGi7yYKO2imCjWnuWxkaJXwqJRDEw8CjJaWJ",
57
+ # Add other necessary cookies here
58
+ # Ensure tokens are valid and not expired
59
+ }
60
+ self.headers: dict = {
61
+ "Accept": "application/json",
62
+ "Accept-Encoding": "gzip, deflate, br, zstd",
63
+ "Accept-Language": "es-US,es;q=0.9,en-US;q=0.8,en;q=0.7,es-419;q=0.6",
64
+ "Cache-Control": "no-cache",
65
+ "Connection": "keep-alive",
66
+ "Content-Type": "application/json",
67
+ "Host": "www.lowes.com",
68
+ "Pragma": "no-cache",
69
+ "Origin": "https://www.lowes.com",
70
+ "Referer": "https://www.lowes.com/pd/",
71
+ "Sec-CH-UA": '"Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132"',
72
+ "Sec-CH-UA-Mobile": "?0",
73
+ "Sec-CH-UA-Platform": '"Linux"',
74
+ 'sec-fetch-site': 'none',
75
+ 'sec-fetch-mode': 'navigate',
76
+ 'sec-fetch-dest': 'document',
77
+ "Sec-Fetch-Site": "same-origin",
78
+ "User-Agent": random.choice(ua)
79
+ }
80
+ self.semaphore = asyncio.Semaphore(10)
81
+
82
+ async def close(self, **kwargs) -> bool:
83
+ self.close_driver()
84
+ return True
85
+
86
+ async def start(self, **kwargs) -> bool:
87
+ await super(Lowes, self).start(**kwargs)
88
+ if self.previous:
89
+ self.data = self.input
90
+ if not isinstance(self.data, pd.DataFrame):
91
+ raise ComponentError(
92
+ "Incompatible Pandas Dataframe"
93
+ )
94
+ self.api_token = self.get_env_value(self.api_token) if hasattr(self, 'api_token') else self.get_env_value('TARGET_API_KEY') # noqa
95
+ if not hasattr(self, self._fn):
96
+ raise ConfigError(
97
+ f"BestBuy: Unable to found Function {self._fn} in Target Component."
98
+ )
99
+
100
+ @backoff.on_exception(
101
+ backoff.expo,
102
+ (httpx.ConnectTimeout, httpx.HTTPStatusError),
103
+ max_tries=2,
104
+ giveup=lambda e: not bad_gateway_exception(e) and not isinstance(e, httpx.ConnectTimeout)
105
+ )
106
+ async def _product_reviews(self, idx, row, cookies):
107
+ async with self.semaphore:
108
+ # Prepare payload for the API request
109
+ sku = row['sku']
110
+ page_size = 10 # fixed size
111
+ current_offset = 0
112
+ max_pages = 20 # Maximum number of pages to fetch
113
+ all_reviews = []
114
+ total_reviews = 0
115
+ try:
116
+ while current_offset < max_pages * page_size:
117
+ if current_offset == 0:
118
+ payload = {
119
+ "sortBy": "newestFirst"
120
+ }
121
+ else:
122
+ payload = {
123
+ "sortBy": "newestFirst",
124
+ "offset": current_offset
125
+ }
126
+ url = f"https://www.lowes.com/rnr/r/get-by-product/{sku}"
127
+ result = await self.api_get(
128
+ url=url,
129
+ cookies=cookies,
130
+ params=payload,
131
+ headers=self.headers
132
+ )
133
+ if not result:
134
+ self._logger.warning(
135
+ f"No Product Reviews found for {sku}."
136
+ )
137
+ break
138
+ # Extract the reviews data from the API response
139
+ reviews_section = result.get('results', [])
140
+ total_reviews = result.get('totalResults', 0)
141
+ if not reviews_section:
142
+ self._logger.info(f"No more reviews found for SKU {sku} at offset {current_offset}.")
143
+ break
144
+ if len(reviews_section) == 0:
145
+ break
146
+ all_reviews.extend(reviews_section)
147
+ # Update total_reviews
148
+
149
+ # Check if we've fetched all reviews
150
+ if len(all_reviews) >= total_reviews:
151
+ self._logger.info(f"Fetched all reviews for SKU {sku}.")
152
+ break
153
+ current_offset += page_size # Move to the next page
154
+ except (httpx.TimeoutException, httpx.HTTPError) as ex:
155
+ self._logger.warning(f"Request failed: {ex}")
156
+ return []
157
+ except Exception as ex:
158
+ self._logger.error(f"An error occurred: {ex}")
159
+ return []
160
+
161
+ # Extract the reviews data from the API response
162
+ reviews = []
163
+ for item in all_reviews:
164
+ # Exclude certain keys
165
+ # Extract relevant fields
166
+ # Combine with original row data
167
+ review_data = row.to_dict()
168
+ review = {
169
+ **review_data,
170
+ "id": item.get("id"),
171
+ "legacyId": item.get("legacyId"),
172
+ "title": item.get("title"),
173
+ "review": item.get("reviewText"),
174
+ "rating": item.get("rating"),
175
+ "isRecommended": item.get("isRecommended"),
176
+ "userNickname": item.get("userNickname"),
177
+ "submissionTime": item.get("submissionTime"),
178
+ "verifiedPurchaser": item.get("verifiedPurchaser"),
179
+ "helpfulVoteCount": item.get("helpfulVoteCount"),
180
+ "notHelpfulVoteCount": item.get("notHelpfulVoteCount"),
181
+ "clientResponses": item.get("clientResponses"),
182
+ "relevancyScore": item.get("relevancyScore"),
183
+ "productId": item.get("productId"),
184
+ }
185
+ review['total_reviews'] = total_reviews
186
+ # Optionally, handle client responses
187
+ if review["clientResponses"]:
188
+ # For simplicity, concatenate all responses into a single string
189
+ responses = []
190
+ for response in review["clientResponses"]:
191
+ response_text = response.get("response", "")
192
+ responses.append(response_text.strip())
193
+ review["clientResponses"] = " | ".join(responses)
194
+ reviews.append(review)
195
+ self._logger.info(
196
+ f"Fetched {len(reviews)} reviews for SKU {sku}."
197
+ )
198
+ return reviews
199
+
200
+ async def reviews(self):
201
+ """reviews.
202
+
203
+ Target Product Reviews.
204
+ """
205
+ httpx_cookies = httpx.Cookies()
206
+ for key, value in self.cookies.items():
207
+ httpx_cookies.set(
208
+ key, value,
209
+ domain='.lowes.com',
210
+ path='/'
211
+ )
212
+
213
+ # Iterate over each row in the DataFrame
214
+ print('starting ...')
215
+
216
+ tasks = [
217
+ self._product_reviews(
218
+ idx,
219
+ row,
220
+ httpx_cookies
221
+ ) for idx, row in self.data.iterrows()
222
+ ]
223
+ # Gather results concurrently
224
+ all_reviews_nested = await self._processing_tasks(tasks)
225
+
226
+ # Flatten the list of lists
227
+ all_reviews = [review for reviews in all_reviews_nested for review in reviews]
228
+
229
+ # Convert to DataFrame
230
+ reviews_df = pd.DataFrame(all_reviews)
231
+
232
+ # at the end, adding a column for origin of reviews:
233
+ reviews_df['origin'] = 'lowes'
234
+
235
+ # show the num of rows in final dataframe:
236
+ self._logger.notice(
237
+ f"Ending Product Reviews: {len(reviews_df)}"
238
+ )
239
+
240
+ # Override previous dataframe:
241
+ self.data = reviews_df
242
+
243
+ # return existing data
244
+ return self.data
245
+
246
+ @backoff.on_exception(
247
+ backoff.expo,
248
+ (httpx.ConnectTimeout, httpx.HTTPStatusError),
249
+ max_tries=2,
250
+ giveup=lambda e: not bad_gateway_exception(e) and not isinstance(e, httpx.ConnectTimeout)
251
+ )
252
+ async def _product_details(self, idx, row, cookies):
253
+ async with self.semaphore:
254
+ # Prepare payload for the API request
255
+ sku = row['sku']
256
+ storeid = row['store_id']
257
+ zipcode = row['zipcode'],
258
+ state_code = row['state_code']
259
+ payload = {
260
+ "nearByStore": storeid,
261
+ "zipState": state_code,
262
+ "quantity": 1
263
+ }
264
+ try:
265
+ # url = "https://www.lowes.com/lowes-proxy/wpd/1000379005/productdetail/1845/Guest/60639?nearByStore=1845&zipState=IL&quantity=1"
266
+ # url = f"https://www.lowes.com/wpd/{sku}/productdetail/{storeid}/Guest/{zipcode}"
267
+ url = f"https://www.lowes.com/lowes-proxy/wpd/{sku}/productdetail/{storeid}/Guest/{zipcode}"
268
+ result = await self.api_get(
269
+ url=url,
270
+ # cookies=cookies,
271
+ # params=payload,
272
+ headers=self.headers
273
+ )
274
+ if not result:
275
+ self._logger.warning(
276
+ f"No Product Details found for {sku}."
277
+ )
278
+ return []
279
+ # Extract the product details data from the API response
280
+ print('RESULT > ', result)
281
+ except (httpx.TimeoutException, httpx.HTTPError) as ex:
282
+ self._logger.warning(f"Request failed: {ex}")
283
+ return []
284
+ except Exception as ex:
285
+ print(ex)
286
+ self._logger.error(f"An error occurred: {ex}")
287
+ return []
288
+
289
+ async def product_details(self):
290
+ """product_details.
291
+
292
+ Get Product Details from Lowes URL.
293
+ """
294
+ self.cookies = {}
295
+ httpx_cookies = httpx.Cookies()
296
+ for key, value in self.cookies.items():
297
+ httpx_cookies.set(
298
+ key, value,
299
+ domain='.lowes.com',
300
+ path='/'
301
+ )
302
+
303
+ # Iterate over each row in the DataFrame
304
+ print('starting ...')
305
+
306
+ tasks = [
307
+ self._product_details(
308
+ idx,
309
+ row,
310
+ httpx_cookies
311
+ ) for idx, row in self.data.iterrows()
312
+ ]
313
+ # Gather results concurrently
314
+ all_products_nested = await self._processing_tasks(tasks)
315
+
316
+ # Flatten the list of lists
317
+ all_products = [product for products in all_products_nested for product in products]
318
+
319
+ # Convert to DataFrame
320
+ _df = pd.DataFrame(all_products)
321
+
322
+ # at the end, adding a column for origin of reviews:
323
+ _df['origin'] = 'lowes'
324
+
325
+ # show the num of rows in final dataframe:
326
+ self._logger.notice(
327
+ f"Ending Product Details: {len(_df)}"
328
+ )
329
+
330
+ # Override previous dataframe:
331
+ self.data = _df
332
+
333
+ # return existing data
334
+ return self.data