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,409 @@
1
+ from collections.abc import Callable
2
+ import asyncio
3
+ import logging
4
+ import random
5
+ import backoff
6
+ import httpx
7
+ from typing import Optional, Dict, Any
8
+ import pandas as pd
9
+ from bs4 import BeautifulSoup
10
+ from ..exceptions import ComponentError, ConfigError
11
+ from ..interfaces import HTTPService, SeleniumService
12
+ from ..interfaces.http import ua, bad_gateway_exception
13
+ from .flow import FlowComponent
14
+ import json
15
+
16
+
17
+ class ZoomInfoScraper(FlowComponent, HTTPService, SeleniumService):
18
+ """
19
+ ZoomInfo Scraper Component that can use either HTTP or Selenium for scraping.
20
+
21
+ Overview:
22
+
23
+ This component scrapes company information from ZoomInfo pages using HTTPService.
24
+ It can receive URLs from a previous component (like GoogleSearch) and extract
25
+ specific company information.
26
+
27
+ .. table:: Properties
28
+ :widths: auto
29
+
30
+ +-----------------------+----------+------------------------------------------------------------------------------------------------------+
31
+ | Name | Required | Description |
32
+ +-----------------------+----------+------------------------------------------------------------------------------------------------------+
33
+ | url_column (str) | Yes | Name of the column containing URLs to scrape (default: 'search_url') |
34
+ +-----------------------+----------+------------------------------------------------------------------------------------------------------+
35
+ | wait_for (tuple) | No | Element to wait for before scraping (default: ('class', 'company-overview')) |
36
+ +-----------------------+----------+------------------------------------------------------------------------------------------------------+
37
+
38
+ Return:
39
+
40
+ The component adds new columns to the DataFrame with company information:
41
+ - headquarters
42
+ - phone_number
43
+ - website
44
+ - stock_symbol
45
+ - naics_code
46
+ - employee_count
47
+ """
48
+
49
+ def __init__(self, loop: asyncio.AbstractEventLoop = None, job: Callable = None, stat: Callable = None, **kwargs) -> None:
50
+ super().__init__(loop=loop, job=job, stat=stat, **kwargs)
51
+
52
+ # Flag to determine which service to use
53
+ self.use_selenium = kwargs.get('use_selenium', True)
54
+
55
+ # Configure common attributes
56
+ self.url_column = kwargs.get('url_column', 'search_url')
57
+ self._counter = 0
58
+ self._debug = kwargs.get('debug', False)
59
+ self._semaphore = asyncio.Semaphore(kwargs.get('max_concurrent', 5))
60
+
61
+ # Proxy configuration like BestBuy
62
+ self.use_proxy = True
63
+ self._free_proxy = False
64
+ self.paid_proxy = True
65
+
66
+ # Configure Selenium specific settings if needed
67
+ if self.use_selenium:
68
+ self.accept_cookies = kwargs.get('accept_cookies', ('id', 'onetrust-accept-btn-handler'))
69
+ self.wait_until = kwargs.get('wait_until', ('class', 'company-overview'))
70
+ self.timeout = kwargs.get('timeout', 30)
71
+
72
+ # Configure Selenium proxy if using Selenium
73
+ if self.use_proxy:
74
+ self.seleniumwire_options = {
75
+ 'proxy': {
76
+ 'http': f'http://{OXYLABS_USERNAME}:{OXYLABS_PASSWORD}@{OXYLABS_ENDPOINT}',
77
+ 'https': f'http://{OXYLABS_USERNAME}:{OXYLABS_PASSWORD}@{OXYLABS_ENDPOINT}'
78
+ }
79
+ }
80
+
81
+ # Configure HTTP specific settings
82
+ else:
83
+ self.headers = {
84
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
85
+ "Accept-Language": "en-US,en;q=0.5",
86
+ "Accept-Encoding": "gzip, deflate, br",
87
+ "Connection": "keep-alive",
88
+ "Upgrade-Insecure-Requests": "1",
89
+ "User-Agent": random.choice(ua),
90
+ **kwargs.get('headers', {})
91
+ }
92
+ self.session_cookies = kwargs.get('session_cookies', {})
93
+
94
+ def split_parts(self, task_list, num_parts: int = 5) -> list:
95
+ """Split task list into parts for concurrent processing."""
96
+ part_size = len(task_list) // num_parts
97
+ remainder = len(task_list) % num_parts
98
+ parts = []
99
+ start = 0
100
+ for i in range(num_parts):
101
+ # Distribute the remainder across the first `remainder` parts
102
+ end = start + part_size + (1 if i < remainder else 0)
103
+ parts.append(task_list[start:end])
104
+ start = end
105
+ return parts
106
+
107
+ async def _processing_tasks(self, tasks: list) -> pd.DataFrame:
108
+ """Process tasks concurrently and format the results."""
109
+ results = []
110
+ for chunk in self.split_parts(tasks, self.task_parts):
111
+ result = await asyncio.gather(*chunk, return_exceptions=False)
112
+ results.extend(result)
113
+
114
+ # Filter out None results and separate index and data
115
+ valid_results = [(idx, data) for idx, data in results if data]
116
+
117
+ if not valid_results:
118
+ return pd.DataFrame()
119
+
120
+ # Split into indices and data dictionaries
121
+ indices, data_dicts = zip(*valid_results)
122
+
123
+ # Convert list of dictionaries to DataFrame
124
+ df = pd.DataFrame(data_dicts, index=indices)
125
+
126
+ # Ensure all expected columns exist
127
+ expected_columns = [
128
+ 'company_name',
129
+ 'logo_url',
130
+ 'address',
131
+ 'phone_number',
132
+ 'website',
133
+ 'stock_symbol',
134
+ 'naics_code',
135
+ 'sic_code',
136
+ 'employee_count',
137
+ 'revenue_range',
138
+ 'similar_companies',
139
+ 'search_term',
140
+ 'search_url'
141
+ ]
142
+
143
+ for col in expected_columns:
144
+ if col not in df.columns:
145
+ df[col] = None
146
+
147
+ return df
148
+
149
+ async def start(self, **kwargs) -> bool:
150
+ """Initialize the component and validate required parameters."""
151
+ if self.previous:
152
+ self.data = self.input
153
+
154
+ if not isinstance(self.data, pd.DataFrame):
155
+ raise ComponentError(
156
+ "Input must be a DataFrame", status=404
157
+ )
158
+
159
+ if self.url_column not in self.data.columns:
160
+ raise ConfigError(
161
+ f"Column {self.url_column} not found in DataFrame"
162
+ )
163
+
164
+ # Initialize result columns
165
+ new_columns = [
166
+ 'search_term',
167
+ 'search_url',
168
+ 'company_name',
169
+ 'logo_url',
170
+ 'address',
171
+ 'phone_number', 'website',
172
+ 'stock_symbol', 'naics_code', 'sic_code',
173
+ 'employee_count', 'revenue_range', 'similar_companies'
174
+ ]
175
+ for col in new_columns:
176
+ if col not in self.data.columns:
177
+ self.data[col] = None
178
+
179
+ return True
180
+
181
+ def extract_company_info(self, soup: BeautifulSoup, search_term: str, search_url: str) -> Dict[str, Any]:
182
+ """Extract company information from the page."""
183
+ result = {}
184
+ result['search_term'] = search_term
185
+ result['search_url'] = search_url
186
+
187
+ # Get company name and logo URL from header
188
+ logo = soup.find('img', {'alt': True, 'width': '76.747'})
189
+ if logo:
190
+ result['company_name'] = logo.get('alt')
191
+ result['logo_url'] = logo.get('src')
192
+
193
+ # Extract information from About section
194
+ about_section = soup.find('app-about')
195
+ if about_section:
196
+ # Get headquarters/address
197
+ address_container = about_section.find('div', {'class': 'icon-text-container'})
198
+ if address_container and 'Headquarters' in address_container.text:
199
+ result['address'] = address_container.find('span', {'class': 'content'}).text.strip()
200
+
201
+ # Get phone number
202
+ phone_container = about_section.find_all('div', {'class': 'icon-text-container'})[1]
203
+ if phone_container and 'Phone Number' in phone_container.text:
204
+ result['phone_number'] = phone_container.find('span', {'class': 'content'}).text.strip()
205
+
206
+ # Get website
207
+ website_container = about_section.find_all('div', {'class': 'icon-text-container'})[2]
208
+ if website_container:
209
+ website_link = website_container.find('a', {'class': 'website-link'})
210
+ if website_link:
211
+ result['website'] = website_link.text.strip()
212
+
213
+ # Get revenue
214
+ revenue_container = about_section.find_all('div', {'class': 'icon-text-container'})[3]
215
+ if revenue_container and 'Revenue' in revenue_container.text:
216
+ result['revenue_range'] = revenue_container.find('span', {'class': 'content'}).text.strip()
217
+
218
+ # Get employee count from company compare section
219
+ company_compare = soup.find('app-company-compare-details', {'class': 'first-company'})
220
+ if company_compare:
221
+ emp_count = company_compare.find('div', {'class': 'num-of-emp'})
222
+ if emp_count:
223
+ result['employee_count'] = emp_count.text.strip()
224
+
225
+ # Get industry information
226
+ industry_chips = about_section.find('span', {'id': 'company-chips-wrapper'})
227
+ if industry_chips:
228
+ industries = [chip.text.strip() for chip in industry_chips.find_all('a', {'class': 'link'})]
229
+ result['industries'] = industries
230
+
231
+ # Get company description
232
+ overview = soup.find('app-company-overview')
233
+ if overview:
234
+ desc = overview.find('span', {'class': 'company-desc'})
235
+ if desc:
236
+ result['description'] = desc.text.strip()
237
+
238
+ # Get social media links
239
+ social_media = soup.find('span', {'id': 'social-media-icons-wrapper'})
240
+ if social_media:
241
+ social_links = {}
242
+ for link in social_media.find_all('a', {'class': 'social-media-icon'}):
243
+ platform = link.get('id').split('-')[1].lower()
244
+ social_links[platform] = link.get('href')
245
+ result['social_media'] = social_links
246
+
247
+ # Get SIC and NAICS codes
248
+ codes_wrapper = soup.find('span', {'id': 'codes-wrapper'})
249
+ if codes_wrapper:
250
+ for code in codes_wrapper.find_all('span', {'class': 'codes-content'}):
251
+ if 'SIC Code' in code.text:
252
+ result['sic_code'] = code.text.replace('SIC Code', '').strip()
253
+ elif 'NAICS Code' in code.text:
254
+ result['naics_code'] = code.text.replace('NAICS Code', '').strip()
255
+
256
+ # Get similar companies
257
+ similar_companies = []
258
+ company_compare = soup.find('app-company-compare')
259
+ if company_compare:
260
+ for company in company_compare.find_all('app-company-compare-details')[1:]: # Skip first (current company)
261
+ company_name = company.find('a', {'class': 'company-name'})
262
+ if not company_name:
263
+ continue
264
+
265
+ similar_company = {
266
+ 'name': company_name.text.strip(),
267
+ 'revenue': company.find('div', {'class': 'revenue'}).text.strip() if company.find('div', {'class': 'revenue'}) else None,
268
+ 'employee_count': company.find('div', {'class': 'num-of-emp'}).text.strip() if company.find('div', {'class': 'num-of-emp'}) else None
269
+ }
270
+ similar_companies.append(similar_company)
271
+
272
+ if similar_companies:
273
+ try:
274
+ result['similar_companies'] = json.dumps(
275
+ similar_companies,
276
+ ensure_ascii=False,
277
+ allow_nan=False,
278
+ separators=(',', ':')
279
+ )
280
+ except Exception as e:
281
+ self._logger.error(f"Error formatting similar companies JSON: {str(e)}")
282
+ result['similar_companies'] = None
283
+
284
+ if not result:
285
+ self._logger.warning("No data was extracted from the page")
286
+ else:
287
+ self._logger.info(f"Successfully extracted data")
288
+
289
+ return result
290
+
291
+ @backoff.on_exception(
292
+ backoff.expo,
293
+ (httpx.ConnectTimeout, httpx.ReadTimeout, httpx.HTTPStatusError),
294
+ max_tries=3,
295
+ max_time=30,
296
+ giveup=lambda e: not bad_gateway_exception(e) and not isinstance(e, (httpx.ConnectTimeout, httpx.ReadTimeout))
297
+ )
298
+ async def scrape_url(self, idx: int, row: pd.Series) -> tuple[int, Optional[Dict[str, Any]]]:
299
+ """Scrape a single ZoomInfo URL using either HTTP or Selenium."""
300
+ async with self._semaphore:
301
+ try:
302
+ url = row[self.url_column]
303
+ search_term = row['search_term']
304
+ search_url = row['search_url']
305
+
306
+ if pd.isna(url):
307
+ return idx, None
308
+
309
+ self._logger.notice(f"Scraping ZoomInfo URL: {url}")
310
+
311
+ if self.use_selenium:
312
+ # Use Selenium for scraping
313
+ try:
314
+ # Initialize driver with proxy if needed
315
+ if not self._driver and self.use_proxy:
316
+ await self.init_driver(
317
+ seleniumwire_options=self.seleniumwire_options
318
+ )
319
+ await self.get_page(url)
320
+ content = self._driver.page_source
321
+ soup = BeautifulSoup(content, 'html.parser')
322
+ except Exception as e:
323
+ self._logger.error(f"Selenium error for URL {url}: {str(e)}")
324
+ return idx, None
325
+ else:
326
+ # Use HTTP for scraping
327
+ try:
328
+ # Get proxies if using HTTP
329
+ if self.use_proxy:
330
+ proxies = await self.get_proxies()
331
+ proxy = proxies[0]
332
+ proxy_config = {
333
+ "http://": f"http://{proxy}",
334
+ "https://": f"http://{proxy}"
335
+ }
336
+ else:
337
+ proxy_config = None
338
+
339
+ response = await self._get(
340
+ url,
341
+ headers=self.headers,
342
+ cookies=self.session_cookies,
343
+ proxies=proxy_config
344
+ )
345
+
346
+ if response.status_code == 403:
347
+ self._logger.error(f"Access forbidden for URL {url}. Consider switching to Selenium.")
348
+ return idx, None
349
+
350
+ if response.status_code != 200:
351
+ self._logger.error(f"Failed to fetch URL {url}: {response.status_code}")
352
+ return idx, None
353
+
354
+ content = response.text
355
+ soup = BeautifulSoup(content, 'html.parser')
356
+
357
+ except Exception as e:
358
+ self._logger.error(f"HTTP error for URL {url}: {str(e)}")
359
+ return idx, None
360
+
361
+ # Check for blocks/captchas
362
+ if self._is_blocked(soup):
363
+ self._logger.error(f"Access blocked for URL {url}. Consider switching to Selenium.")
364
+ return idx, None
365
+
366
+ result = self.extract_company_info(soup, search_term, search_url)
367
+
368
+ if result:
369
+ self._counter += 1
370
+ return idx, result
371
+
372
+ except Exception as e:
373
+ self._logger.error(f"Error scraping URL {url}: {str(e)}")
374
+ return idx, None
375
+
376
+ def _is_blocked(self, soup: BeautifulSoup) -> bool:
377
+ """Check if the response indicates we're blocked or need to solve a CAPTCHA."""
378
+ blocked_indicators = [
379
+ 'captcha',
380
+ 'blocked',
381
+ 'access denied',
382
+ 'please verify you are a human'
383
+ ]
384
+
385
+ page_text = soup.get_text().lower()
386
+ return any(indicator in page_text for indicator in blocked_indicators)
387
+
388
+ async def run(self):
389
+ """Execute scraping for each URL in the DataFrame."""
390
+ tasks = [
391
+ self.scrape_url(idx, row) for idx, row in self.data.iterrows()
392
+ ]
393
+ df = await self._processing_tasks(tasks)
394
+ self.add_metric("PAGES_SCRAPED", self._counter)
395
+
396
+ if self._debug is True:
397
+ print(df)
398
+ print("::: Printing Column Information === ")
399
+ for column, t in df.dtypes.items():
400
+ print(column, "->", t, "->", df[column].iloc[0])
401
+
402
+ self._result = df
403
+ return self._result
404
+
405
+ async def close(self):
406
+ """Clean up resources."""
407
+ if self.use_selenium:
408
+ self.close_driver()
409
+ return True
@@ -0,0 +1,104 @@
1
+ from typing import Any
2
+ import asyncio
3
+ from pathlib import Path
4
+ import importlib
5
+ from concurrent.futures import ThreadPoolExecutor
6
+ from navconfig.logging import logging, logger
7
+ from ..exceptions import NotSupported, ComponentError
8
+ from ..download import download_component
9
+ from .abstract import AbstractFlow
10
+ from .flow import FlowComponent
11
+ from .user import UserComponent
12
+ from .group import GroupComponent
13
+
14
+
15
+ __all__ = (
16
+ "AbstractFlow",
17
+ "FlowComponent",
18
+ "UserComponent",
19
+ "GroupComponent",
20
+ )
21
+
22
+ _COMPONENTS: dict[str, Any] = {}
23
+
24
+
25
+ def importComponent(component: str, classpath: str = None, package: str = "components"):
26
+ if not classpath:
27
+ classpath = f"flowtask.components.{component}"
28
+ module = importlib.import_module(classpath, package=package)
29
+ obj = getattr(module, component)
30
+ return obj
31
+
32
+
33
+ def _download_helper(coroutine):
34
+ def _run_coro(coro):
35
+ event_loop = asyncio.new_event_loop()
36
+ try:
37
+ asyncio.set_event_loop(event_loop)
38
+ return event_loop.run_until_complete(coro)
39
+ finally:
40
+ event_loop.close()
41
+
42
+ with ThreadPoolExecutor(max_workers=1) as pool:
43
+ result = pool.submit(_run_coro, coroutine).result()
44
+ return result
45
+
46
+
47
+ def downloadComponent(component: str):
48
+ # Create a coroutine object
49
+ coro = download_component(component)
50
+ # Run the coroutine in a new event loop in a separate thread
51
+ result = _download_helper(coro)
52
+ return result
53
+
54
+
55
+ def loadComponent(component, program: str = None):
56
+ try:
57
+ # Getting Basic Components
58
+ classpath = f"flowtask.components.{component}"
59
+ return importComponent(component, classpath, package="components")
60
+ except ImportError as ex:
61
+ logging.warning(
62
+ f"Error Importing Component {component}: {ex}"
63
+ )
64
+ cpath = Path(__file__).parent.joinpath(f"{component}.py")
65
+ if cpath.exists():
66
+ logger.error(ex)
67
+ raise ComponentError(
68
+ f"Error Importing Component {component}: {ex}"
69
+ ) from ex
70
+ try:
71
+ # another, check if task is an User-Defined Component
72
+ classpath = f"flowtask.plugins.components.{component}"
73
+ obj = importComponent(component, classpath, package="components")
74
+ if issubclass(obj, (UserComponent, FlowComponent)):
75
+ return obj
76
+ raise ImportError(
77
+ f"Cannot import {component} Hint: Component need inherits from UserComponent"
78
+ )
79
+ except ImportError as e:
80
+ ### TODO: Download Component From Marketplace, installed on "plugins" folder.
81
+ if downloadComponent(component) is True:
82
+ ## re-import from plugins path
83
+ return importComponent(component, classpath, package="components")
84
+ raise NotSupported(
85
+ f"Error: No Component {component!r} was Found: {e}"
86
+ ) from e
87
+
88
+
89
+ def getComponent(component: str, program: str = None):
90
+ try:
91
+ if component in _COMPONENTS:
92
+ return _COMPONENTS[component]
93
+ else:
94
+ cls = loadComponent(component, program=program)
95
+ _COMPONENTS[component] = cls
96
+ return cls
97
+ except KeyError as err:
98
+ logger.exception(
99
+ f"Error loading component {component}: {err}",
100
+ stack_info=True
101
+ )
102
+ raise ComponentError(
103
+ f"Error loading component {component}: {err}"
104
+ ) from err
@@ -0,0 +1,18 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ class AbstractFlow(ABC):
5
+
6
+ @abstractmethod
7
+ async def start(self, **kwargs):
8
+ """Start Method called on every component.
9
+ """
10
+
11
+ @abstractmethod
12
+ async def close(self):
13
+ pass
14
+
15
+ @abstractmethod
16
+ async def run(self):
17
+ """Execute the code for component.
18
+ """