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,362 @@
1
+ import os
2
+ import logging
3
+ import asyncio
4
+ from collections.abc import Callable
5
+ import types
6
+ from functools import reduce
7
+ import pandas as pd
8
+ import numpy as np
9
+ import cchardet as chardet
10
+ from ..exceptions import ComponentError
11
+ from ..parsers.maps import open_model
12
+ from .flow import FlowComponent
13
+ from .OpenWithBase import detect_encoding, excel_based
14
+
15
+
16
+ class MergeFiles(FlowComponent):
17
+ """
18
+ MergeFiles
19
+
20
+ Overview
21
+
22
+ The MergeFiles class is a component for merging multiple files into a single file or dataframe. It supports various
23
+ file formats, including CSV, Excel, and HTML, and handles encoding detection and conversion as needed.
24
+
25
+ .. table:: Properties
26
+ :widths: auto
27
+
28
+ +------------------+----------+--------------------------------------------------------------------------------------------------+
29
+ | Name | Required | Description |
30
+ +------------------+----------+--------------------------------------------------------------------------------------------------+
31
+ | filename | No | The name of the merged output file. |
32
+ +------------------+----------+--------------------------------------------------------------------------------------------------+
33
+ | file | No | The file object to be merged. |
34
+ +------------------+----------+--------------------------------------------------------------------------------------------------+
35
+ | filepath | No | The directory path for the merged output file. |
36
+ +------------------+----------+--------------------------------------------------------------------------------------------------+
37
+ | ContentType | No | The content type of the files being merged, defaults to "text/csv". |
38
+ +------------------+----------+--------------------------------------------------------------------------------------------------+
39
+ | as_dataframe | No | Boolean flag indicating if the result should be returned as a dataframe, defaults to False. |
40
+ +------------------+----------+--------------------------------------------------------------------------------------------------+
41
+
42
+ Return
43
+
44
+ The methods in this class manage the merging of files, including initialization, execution, and result handling.
45
+
46
+
47
+
48
+ Example:
49
+
50
+ ```yaml
51
+ MergeFiles:
52
+ ContentType: application/vnd.ms-excel
53
+ model: worked_hours
54
+ pd_args:
55
+ skiprows: 6
56
+ as_dataframe: true
57
+ ```
58
+
59
+ """ # noqa
60
+
61
+ def __init__(
62
+ self,
63
+ loop: asyncio.AbstractEventLoop = None,
64
+ job: Callable = None,
65
+ stat: Callable = None,
66
+ **kwargs,
67
+ ) -> None:
68
+ """Init Method."""
69
+ self.filename = ""
70
+ self.file = None
71
+ self.filepath = ""
72
+ self.ContentType: str = "text/csv"
73
+ self.as_dataframe: bool = False
74
+ super(MergeFiles, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
75
+
76
+ async def start(self, **kwargs):
77
+ """
78
+ start.
79
+ Start connection.
80
+ """
81
+ if self.previous:
82
+ try:
83
+ if isinstance(self.input, list):
84
+ # is a list of files
85
+ self.data = self.input
86
+ elif isinstance(self.input, dict):
87
+ if "files" in self.input:
88
+ self.data = self.input["files"]
89
+ else:
90
+ self.data = {k: v for k, v in self.input.items()}
91
+ elif isinstance(self.input, types.GeneratorType):
92
+ # is a generator:
93
+ self.data = list(self.input)
94
+ else:
95
+ raise ComponentError(
96
+ "MergeFiles Error: incompatible kind of previous Object."
97
+ )
98
+ except Exception as err:
99
+ raise ComponentError(f"Error Filtering Data {err}") from err
100
+ self._logger.debug(f"List of Files: {self.data!r}")
101
+ if hasattr(self, "destination"):
102
+ # we need to calculated the result filename of this component
103
+ filename = self.destination["filename"]
104
+ self.filepath = self.destination["directory"]
105
+ if hasattr(self, "masks"):
106
+ for mask, replace in self._mask.items():
107
+ filename = str(filename).replace(mask, replace)
108
+ if self._variables:
109
+ filename = filename.format(**self._variables)
110
+ self.filename = os.path.join(self.filepath, filename)
111
+ self.add_metric("MERGED_FILENAME", self.filename)
112
+ return True
113
+
114
+ async def close(self):
115
+ """
116
+ close.
117
+
118
+ close method
119
+ """
120
+
121
+ def _merge_dataframe(self, dfs: list):
122
+ """
123
+ Merges a list of DataFrames based on their common columns.
124
+
125
+ Args:
126
+ dfs: A list of pandas DataFrames.
127
+
128
+ Returns:
129
+ A single merged DataFrame.
130
+ """
131
+ if not hasattr(self, 'use_merge'):
132
+ # Concatenate the DataFrames
133
+ return pd.concat(dfs)
134
+ # Calculate the common columns in all dataframes
135
+ common_columns = set(dfs[0].columns)
136
+ for df in dfs[1:]:
137
+ common_columns = common_columns.intersection(set(df.columns))
138
+ if not common_columns:
139
+ raise ComponentError("MergeFiles Error: No common columns found.")
140
+ if self.use_merge:
141
+ # Cast column types based on the first dataframe:
142
+ for df in dfs[1:]:
143
+ for col in common_columns:
144
+ df[col] = df[col].astype(dfs[0][col].dtype)
145
+ merged_df = reduce(
146
+ lambda left, right: pd.merge(left, right, how='outer', on=list(common_columns)), dfs
147
+ )
148
+ # Drop columns with all missing values (empty)
149
+ merged_df = merged_df.dropna(axis=1, how='all')
150
+ return merged_df
151
+ return pd.concat(dfs)
152
+
153
+ async def run(self):
154
+ """
155
+ run.
156
+
157
+ Run the connection and merge all the files
158
+ """
159
+ np_array_list = []
160
+ df = None
161
+ np_array_list = []
162
+ if isinstance(self.data, list):
163
+ # is a list of files
164
+ if self.ContentType in excel_based:
165
+ args = self.pd_args if hasattr(self, "pd_args") else {}
166
+ if self.ContentType == "application/vnd.ms-excel":
167
+ file_engine = "xlrd"
168
+ elif (
169
+ self.ContentType
170
+ == "application/vnd.ms-excel.sheet.binary.macroEnabled.12"
171
+ ):
172
+ file_engine = "pyxlsb"
173
+ else:
174
+ file_engine = "openpyxl"
175
+ # get the Model (if any):
176
+ if hasattr(self, "model"):
177
+ columns = await open_model(self.model, self._program)
178
+ fields = []
179
+ dates = []
180
+ for field, dtype in columns["fields"].items():
181
+ fields.append(field)
182
+ try:
183
+ t = dtype["data_type"]
184
+ except KeyError:
185
+ t = "str"
186
+ if t in {"date", "datetime", "time"}:
187
+ dates.append(field)
188
+ args["names"] = fields
189
+ if dates:
190
+ args["parse_dates"] = dates
191
+ files = []
192
+ file_stats = {}
193
+ for file in self.data:
194
+ if not file:
195
+ continue
196
+ try:
197
+ df = pd.read_excel(
198
+ file,
199
+ na_values=["TBD", "NULL", "null", "", "#NA"],
200
+ engine=file_engine,
201
+ keep_default_na=True,
202
+ **args,
203
+ )
204
+ file_args = {}
205
+ if hasattr(self, 'file_stats'):
206
+ first_row = df.iloc[0][self.file_stats['columns']].to_dict()
207
+ file_args = first_row
208
+ file_stats[file.name] = {
209
+ "numrows": len(df.index),
210
+ **file_args
211
+ }
212
+ except TypeError as ex:
213
+ self._logger.error(f"Merge Excel Error: {ex}")
214
+ files.append(df)
215
+ try:
216
+ self._result = self._merge_dataframe(files)
217
+ self.add_metric("FILE_STATS", file_stats)
218
+ self._print_data_(self._result, 'Merged data')
219
+ if self._debug is True:
220
+ print("::: Combined File ::: ")
221
+ print(self._result)
222
+ if self.as_dataframe is True:
223
+ numrows = len(self._result)
224
+ self.add_metric("NUMROWS", numrows)
225
+ self.add_metric("COLUMNS", self._result.shape[1])
226
+ return self._result
227
+ else:
228
+ # saved as CSV.
229
+ self._result.to_csv(
230
+ self.filename, index=False, encoding="utf-8-sig"
231
+ )
232
+ self._result = self.filename
233
+ self.add_metric("MERGED_FILE", self.filename)
234
+ return self._result
235
+ except Exception as err:
236
+ logging.exception(
237
+ f"Error Merging Excel Files: {err}", stack_info=True
238
+ )
239
+ self._result = None
240
+ return False
241
+ elif self.ContentType == "text/html":
242
+ encoding = "utf-8"
243
+ try:
244
+ if len(self.data) == 1:
245
+ # there is no other files to merge:
246
+ combined_csv = pd.read_html(self.data[0], encoding=encoding)
247
+ else:
248
+ dfs = []
249
+ for f in self.data:
250
+ try:
251
+ dt = pd.read_html(f, encoding=encoding)
252
+ dfs.append(dt[0])
253
+ except (TypeError, ValueError):
254
+ continue
255
+ # combine all files in the list
256
+ combined_csv = pd.concat(
257
+ dfs, sort=False, axis=0, ignore_index=True
258
+ ).reindex(dfs[0].index)
259
+ except UnicodeDecodeError:
260
+ combined_csv = pd.concat(
261
+ [pd.read_html(f, encoding="windows-1252") for f in self.data]
262
+ )
263
+ except Exception as err:
264
+ raise ComponentError(f"{err!s}") from err
265
+ try:
266
+ if self.as_dataframe is True:
267
+ self._result = combined_csv
268
+ self.add_metric("MERGED_DF", self._result.columns)
269
+ else:
270
+ # export to csv
271
+ combined_csv.to_csv(
272
+ self.filename, index=False, encoding="utf-8-sig"
273
+ )
274
+ self._result = self.filename
275
+ self.add_metric("MERGED_FILE", self.filename)
276
+ return self._result
277
+ except Exception as err:
278
+ logging.error(err)
279
+ self._result = None
280
+ return False
281
+ elif self.ContentType == "text/csv":
282
+ args = {}
283
+ if hasattr(self, "pd_args"):
284
+ args = self.pd_args
285
+ if hasattr(self, "encoding"):
286
+ encoding = self.encoding
287
+ else:
288
+ encoding = None
289
+ for file in self.data:
290
+ try:
291
+ buffer = None
292
+ with open(file, "rb") as f:
293
+ buffer = f.read(10000)
294
+ result_charset = chardet.detect(buffer)
295
+ enc = result_charset["encoding"]
296
+ if encoding is not None and enc != encoding:
297
+ logging.warning(
298
+ "MergeFiles: files has different encoding"
299
+ )
300
+ encoding = enc
301
+ if encoding == "ASCII":
302
+ encoding = "utf-8-sig"
303
+ except Exception as err:
304
+ logging.warning(f"MergeFiles: DECODING ERROR {err}")
305
+ _, encoding = detect_encoding(file, encoding)
306
+ if not encoding:
307
+ encoding = "utf-8-sig"
308
+ try:
309
+ if len(self.data) == 1:
310
+ # there is no other files to merge:
311
+ combined_csv = pd.read_csv(self.data[0], encoding=encoding)
312
+ else:
313
+ dfs = [pd.read_csv(f, encoding=encoding) for f in self.data]
314
+ # combine all files in the list
315
+ combined_csv = self._merge_dataframe(dfs)
316
+ print(f"COMBINED CSV: {combined_csv}")
317
+ except UnicodeDecodeError:
318
+ combined_csv = pd.concat(
319
+ [pd.read_csv(f, encoding="windows-1252") for f in self.data]
320
+ )
321
+ except Exception as err:
322
+ raise ComponentError(f"{err!s}") from err
323
+ try:
324
+ if self.as_dataframe is True:
325
+ self._result = combined_csv
326
+ self.add_metric("MERGED_DF", self._result.columns)
327
+ else:
328
+ # export to csv
329
+ combined_csv.to_csv(
330
+ self.filename, index=False, encoding="utf-8-sig"
331
+ )
332
+ self._result = self.filename
333
+ self.add_metric("MERGED_FILE", self.filename)
334
+ return self._result
335
+ except Exception as err:
336
+ self._logger.error(err)
337
+ self._result = None
338
+ return False
339
+ elif isinstance(self.data, dict):
340
+ for f in self.data:
341
+ ip = self.data[f]["data"]
342
+ if self.ContentType == "application/json":
343
+ if self.data[f]["type"] == "binary/octet-stream":
344
+ # wrapper = io.TextIOWrapper(input, encoding='utf-8')
345
+ content = ip.getvalue()
346
+ else:
347
+ # convert to string:
348
+ # wrapper = io.TextIOWrapper(input, encoding='utf-8')
349
+ content = ip
350
+ # content = wrapper.read()
351
+ df = pd.read_json(content, orient="records")
352
+ columns = list(df.columns)
353
+ np_array_list.append(df.values)
354
+ comb_np_array = np.vstack(np_array_list)
355
+ df = pd.DataFrame(comb_np_array)
356
+ df.columns = columns
357
+ self._result = df
358
+ self._print_data_(df, 'Merged data')
359
+ return True
360
+ else:
361
+ self._result = None
362
+ return False
@@ -0,0 +1,87 @@
1
+ """
2
+ Milvus Database Vectorstore Output.
3
+
4
+
5
+ Example:
6
+
7
+ ```yaml
8
+ MilvusOutput:
9
+ credentials:
10
+ collection_name: lg_products
11
+ db_name: lg
12
+ embedding_model:
13
+ model_name: thenlper/gte-base
14
+ model_type: transformers
15
+ vector_field: vector
16
+ text_field: text
17
+ pk: source_type
18
+ consistency_level: Bounded
19
+ ```
20
+
21
+ """
22
+ from collections.abc import Callable
23
+ import asyncio
24
+ from .flow import FlowComponent
25
+ from ..exceptions import DataNotFound, ComponentError, ConfigError
26
+ from ..interfaces.vectorstores import MilvusStore
27
+
28
+
29
+ class MilvusOutput(MilvusStore, FlowComponent):
30
+ def __init__(
31
+ self,
32
+ loop: asyncio.AbstractEventLoop = None,
33
+ job: Callable = None,
34
+ stat: Callable = None,
35
+ **kwargs,
36
+ ):
37
+ self.upsert: bool = kwargs.pop('upsert', True)
38
+ self.pk: str = kwargs.pop('pk', 'source_type')
39
+ super().__init__(loop=loop, job=job, stat=stat, **kwargs)
40
+
41
+ async def start(self, **kwargs):
42
+ if self.previous:
43
+ self.data = self.input
44
+ await super().start(**kwargs)
45
+ self.processing_credentials()
46
+ if not self.credentials:
47
+ raise ConfigError(
48
+ "Unable to find valid Credentials for Milvus DB."
49
+ )
50
+ if not self.data:
51
+ raise DataNotFound(
52
+ "List of Documents is Empty."
53
+ )
54
+ if not isinstance(self.data, list):
55
+ raise ComponentError(
56
+ f"Incompatible kind of data received, expected *list*, receives {type(self.data)}"
57
+ )
58
+ return True
59
+
60
+ async def close(self):
61
+ pass
62
+
63
+ async def run(self):
64
+ """
65
+ Saving Langchain Documents on a Milvus Database.
66
+ """
67
+ # Connecting to Milvus
68
+ # TODO: add Collection creation:
69
+ self._result = None
70
+ async with self as connection:
71
+ vector, documents = await connection.load_documents(
72
+ self.data,
73
+ collection=self.collection_name,
74
+ upsert=self.upsert,
75
+ pk=self.pk,
76
+ dimension=self._dimension,
77
+ index_type=self._index_type,
78
+ metric_type=self._metric_type
79
+ )
80
+ result = {
81
+ "vectorstore": vector,
82
+ "documents": documents
83
+ }
84
+ self._result = result
85
+ self.add_metric('DOCUMENTS_LOADED', len(self.data))
86
+ # self.add_metric('DOCUMENTS', documents)
87
+ return result
@@ -0,0 +1,175 @@
1
+ import asyncio
2
+ import pandas as pd
3
+ import geopandas as gpd
4
+ from shapely.geometry import Point
5
+ from concurrent.futures import ProcessPoolExecutor
6
+ from .flow import FlowComponent
7
+ from ..exceptions import ComponentError, DataNotFound
8
+
9
+
10
+ class NearByStores(FlowComponent):
11
+ """NearByStores.
12
+
13
+ Overview:
14
+ Calculates the nearest stores to an employee location.
15
+
16
+
17
+
18
+ Example:
19
+
20
+ ```yaml
21
+ NearByStores:
22
+ depends:
23
+ - QueryToPandas_1
24
+ - QueryToPandas_2
25
+ radius: 50
26
+ ```
27
+
28
+ """
29
+ async def start(self, **kwargs):
30
+ if self.previous:
31
+ try:
32
+ self.df1: pd.DataFrame = self.previous[0].output()
33
+ self.df2: pd.DataFrame = self.previous[1].output()
34
+ except IndexError:
35
+ raise ComponentError(
36
+ "NearByStores Requires 2 Dataframes", status=404
37
+ )
38
+ else:
39
+ raise DataNotFound(
40
+ "Data Not Found", status=404
41
+ )
42
+ await super().start(**kwargs)
43
+ return True
44
+
45
+ async def close(self):
46
+ pass
47
+
48
+ def _print_data_(self, df: pd.DataFrame, title: str = None):
49
+ if not title:
50
+ title = self.__class__.__name__
51
+ print(f"::: Printing {title} === ")
52
+ print("Data: ", df)
53
+ if df.empty:
54
+ print("The DataFrame is empty.")
55
+ else:
56
+ for column, t in df.dtypes.items():
57
+ print(f"{column} -> {t} -> {df[column].iloc[0]}")
58
+
59
+ def _find_nearby_stores(self, employee_row, stores_gdf, employees_gdf):
60
+ # Employee's buffer geometry
61
+ employee_buffer = employee_row['buffer']
62
+ employee_buffer_gdf = gpd.GeoDataFrame(
63
+ {'geometry': [employee_buffer]}, crs=employees_gdf.crs
64
+ )
65
+
66
+ # Spatial join to find stores within the buffer
67
+ nearby_stores = gpd.sjoin(
68
+ stores_gdf, employee_buffer_gdf, how='inner', predicate='intersects'
69
+ )
70
+
71
+ # If no stores are found, return an empty list
72
+ if nearby_stores.empty:
73
+ return []
74
+
75
+ # Build a list of dictionaries combining employee and store information
76
+ rows = []
77
+ employee_info = {
78
+ 'associate_oid': employee_row['associate_oid'],
79
+ 'corporate_email': employee_row['corporate_email'],
80
+ 'employee_coordinates': (employee_row.geometry.y, employee_row.geometry.x),
81
+ 'employee_position': (employee_row.latitude, employee_row.longitude)
82
+ }
83
+
84
+ for idx, store_row in nearby_stores.iterrows():
85
+ store_info = {
86
+ 'store_id': store_row['store_id'],
87
+ 'store_name': store_row['store_name'],
88
+ 'store_coordinates': (store_row.geometry.y, store_row.geometry.x),
89
+ 'store_position': (store_row.latitude, store_row.longitude),
90
+ 'visit_rule': store_row.get('visit_rule', None),
91
+ 'visit_category': store_row.get('visit_category', None)
92
+ }
93
+ # Combine employee and store info
94
+ combined_row = {**employee_info, **store_info}
95
+ rows.append(combined_row)
96
+
97
+ return rows
98
+
99
+ async def _async_find_nearby_stores(self, employee_row, stores_gdf, employees_gdf):
100
+ try:
101
+ result = await asyncio.to_thread(
102
+ self._find_nearby_stores,
103
+ employee_row,
104
+ stores_gdf,
105
+ employees_gdf
106
+ )
107
+ return result
108
+ except Exception as e:
109
+ # Log the exception and return None
110
+ print(f"An error occurred: {e}")
111
+ return None
112
+
113
+ async def run(self):
114
+ # Create geometry columns for employees
115
+ self.df2['geometry'] = self.df2.apply(
116
+ lambda row: Point(row['longitude'], row['latitude']), axis=1
117
+ )
118
+ employees_gdf = gpd.GeoDataFrame(self.df2, geometry='geometry', crs='EPSG:4326')
119
+
120
+ # Create geometry columns for stores
121
+ self.df1['geometry'] = self.df1.apply(
122
+ lambda row: Point(row['longitude'], row['latitude']), axis=1
123
+ )
124
+ stores_gdf = gpd.GeoDataFrame(self.df1, geometry='geometry', crs='EPSG:4326')
125
+
126
+ # Reproject to EPSG:3857 that allows accurate distance measurements in meters.
127
+ employees_gdf = employees_gdf.to_crs(epsg=3857)
128
+ stores_gdf = stores_gdf.to_crs(epsg=3857)
129
+
130
+ # Build spatial index for stores_gdf
131
+ stores_gdf.sindex
132
+
133
+ # radius:
134
+ radius = getattr(self, 'radius', 100)
135
+
136
+ # Convert miles to meters (1 mile = 1609.34 meters)
137
+ buffer_radius = radius * 1609.34 # 482,802 meters
138
+
139
+ # Create buffers
140
+ employees_gdf['buffer'] = employees_gdf.geometry.buffer(buffer_radius)
141
+
142
+ batch_size = 50
143
+
144
+ # Create a list of tasks
145
+ tasks = [
146
+ self._async_find_nearby_stores(employee_row, stores_gdf, employees_gdf)
147
+ for _, employee_row in employees_gdf.iterrows()
148
+ ]
149
+
150
+ tasks_chunks = [tasks[i:i + batch_size] for i in range(0, len(tasks), batch_size)]
151
+
152
+ results = []
153
+ for chunk in tasks_chunks:
154
+ # Run tasks in the chunk concurrently
155
+ chunk_results = await asyncio.gather(*chunk)
156
+ # Collect the rows from each result
157
+ for result in chunk_results:
158
+ if result: # Check if the list is not empty
159
+ results.extend(result) # Extend the results list with the returned rows
160
+
161
+ # Concatenate all results
162
+ if results:
163
+ final_df = pd.DataFrame(results)
164
+ else:
165
+ # If no results, create an empty DataFrame with the expected columns
166
+ final_df = pd.DataFrame(columns=[
167
+ 'associate_oid', 'corporate_email', 'employee_position',
168
+ 'store_id', 'store_position', 'visit_rule', 'visit_category'
169
+ ])
170
+
171
+ # Set the final output
172
+ self._print_data_(final_df)
173
+ self._result = final_df
174
+
175
+ return self._result
@@ -0,0 +1,6 @@
1
+ from .router import NetworkNinja
2
+
3
+
4
+ __all__ = (
5
+ 'NetworkNinja',
6
+ )
@@ -0,0 +1,52 @@
1
+ from .organization import Organization
2
+ from .client import Client
3
+ from .store import Store, StoreType, StoreGeography
4
+ from .user import Role, User, StaffingUser
5
+ from .photos import Document, Photo, PhotoCategory
6
+ from .project import Project
7
+ from .forms import Form, FormMetadata, FormData, FormDefinition
8
+ from .events import Event, EventPunch
9
+ from .account import Account
10
+
11
+
12
+ NetworkNinja_Map = {
13
+ "store": Store,
14
+ "client": Client,
15
+ "orgid": Organization,
16
+ "user": User,
17
+ "staffing_user": StaffingUser,
18
+ 'photo_category': PhotoCategory,
19
+ 'store_photo': Photo,
20
+ "role": Role,
21
+ "project": Project,
22
+ "store_type": StoreType,
23
+ "document": Document,
24
+ 'store_geography': StoreGeography,
25
+ 'form': FormDefinition,
26
+ 'form_metadata': FormMetadata,
27
+ 'form_data': FormData,
28
+ 'event': Event,
29
+ 'retailer': Account,
30
+ 'event_cico': EventPunch
31
+ }
32
+
33
+
34
+ NN_Order = [
35
+ 'client',
36
+ 'project',
37
+ 'orgid',
38
+ 'retailer',
39
+ 'role',
40
+ 'store_type',
41
+ 'store_geography',
42
+ 'store',
43
+ 'user',
44
+ 'staffing_user',
45
+ 'form',
46
+ 'event',
47
+ 'event_cico',
48
+ 'form_metadata',
49
+ 'form_data',
50
+ 'photo_category',
51
+ 'store_photo',
52
+ ]