flowtask 5.8.4__cp39-cp39-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-39-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-39-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-39-x86_64-linux-gnu.so +0 -0
  377. flowtask/parsers/json.c +11968 -0
  378. flowtask/parsers/json.cpython-39-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-39-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-39-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-39-x86_64-linux-gnu.so +0 -0
  440. flowtask/utils/json.cpp +13349 -0
  441. flowtask/utils/json.cpython-39-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-39-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,499 @@
1
+ from typing import List, Optional, Union, Any
2
+ import logging
3
+ from datetime import datetime, timezone
4
+ from asyncpg.exceptions import UniqueViolationError
5
+ from asyncdb import AsyncDB
6
+ from datamodel import BaseModel, Field
7
+ from querysource.conf import default_dsn, async_default_dsn
8
+ from querysource.outputs.tables import PgOutput
9
+ from .abstract import AbstractPayload
10
+ from .organization import Organization
11
+ from .client import Client
12
+ from .store import CustomStoreField, Store, StoreType
13
+ from .user import User, StaffingUser
14
+ from .region import Region
15
+ from .account import Account
16
+
17
+
18
+ class Condition(BaseModel):
19
+ """
20
+ Defines a Condition, a condition for a Logic Group.
21
+ Example:
22
+ {
23
+ "condition_id": 1835,
24
+ "condition_logic": "EQUALS",
25
+ "condition_comparison_value": "Regular",
26
+ "condition_question_reference_id": 48,
27
+ "condition_option_id": 4308
28
+ }
29
+ """
30
+ condition_id: int = Field(primary_key=True, required=True)
31
+ condition_logic: str = Field(required=True)
32
+ condition_comparison_value: str = Field(required=True)
33
+ condition_question_reference_id: str
34
+ condition_option_id: str
35
+
36
+
37
+ class Validation(BaseModel):
38
+ """
39
+ Defines a Validation, a validation rule for a question.
40
+ Example:
41
+ {
42
+ "validation_id": 43,
43
+ "validation_type": "responseRequired",
44
+ "validation_logic": null,
45
+ "validation_comparison_value": null,
46
+ "validation_question_reference_id": null
47
+ }
48
+ """
49
+ validation_id: int = Field(primary_key=True, required=True)
50
+ validation_type: str = Field(required=True)
51
+ validation_logic: str
52
+ validation_comparison_value: str
53
+ validation_question_reference_id: str
54
+ condition_option_id: str
55
+
56
+
57
+ class LogicGroup(BaseModel):
58
+ """
59
+ Defines a Logic Group, a group of questions in a Form.
60
+ Example:
61
+ {
62
+ "logic_group_id": 1706,
63
+ "conditions": [
64
+ {
65
+ "condition_id": 1835,
66
+ "condition_logic": "EQUALS",
67
+ "condition_comparison_value": "Regular",
68
+ "condition_question_reference_id": 48,
69
+ "condition_option_id": 4308
70
+ }
71
+ ]
72
+ }
73
+ """
74
+ logic_group_id: int = Field(primary_key=True, required=True)
75
+ conditions: List[Condition]
76
+
77
+
78
+ class Question(BaseModel):
79
+ """
80
+ Defines a Question, a single question in a Form.
81
+ Example:
82
+ {
83
+ "question_id": 48,
84
+ "question_column_name": "8501",
85
+ "question_description": "Purpose of Visit",
86
+ "question_logic_groups": [],
87
+ "validations": [
88
+ {
89
+ "validation_id": 43,
90
+ "validation_type": "responseRequired",
91
+ "validation_logic": null,
92
+ "validation_comparison_value": null,
93
+ "validation_question_reference_id": null
94
+ }
95
+ ]
96
+ }
97
+ """
98
+ question_id: int = Field(primary_key=True, required=True)
99
+ question_column_name: Union[str, int] = Field(required=True)
100
+ question_description: str = Field(required=True)
101
+ question_logic_groups: List[LogicGroup]
102
+ validations: List[Validation]
103
+
104
+ class QuestionBlock(BaseModel):
105
+ """
106
+ Defines a Question Block, a collection of questions in a Form.
107
+
108
+ Example:
109
+ {
110
+ "question_block_id": 9,
111
+ "question_block_type": "simple",
112
+ "question_block_logic_groups": [],
113
+ "questions": []
114
+ }
115
+ """
116
+ block_id: int = Field(primary_key=True, required=True, alias="question_block_id")
117
+ block_type: str = Field(alias="question_block_type")
118
+ block_logic_groups: List[dict] = Field(alias="question_block_logic_groups")
119
+ questions: List[dict]
120
+
121
+ class FormDefinition(AbstractPayload):
122
+ """
123
+ Defines a Form (recap) definition.
124
+ """
125
+ formid: int = Field(primary_key=True, required=True)
126
+ client_id: Client = Field(required=True, primary_key=True)
127
+ client_name: str
128
+ form_name: str
129
+ description: str = Field(alias='form_description')
130
+ active: bool = Field(default=True)
131
+ is_store_stamp: bool = Field(default=True)
132
+ created_on: datetime
133
+ updated_on: datetime
134
+ orgid: Organization
135
+ question_blocks: Optional[List[QuestionBlock]] = Field(default_factory=list)
136
+
137
+ class Meta:
138
+ strict = True
139
+ as_objects = True
140
+ name = 'forms'
141
+ schema: str = 'networkninja'
142
+
143
+ def __post_init__(self):
144
+ super().__post_init__()
145
+ if not self.description:
146
+ self.description = self.form_name
147
+ if self.client_id:
148
+ self.client_id.client_name = self.client_name
149
+ self.client_id.orgid = self.orgid
150
+
151
+ class Form(AbstractPayload):
152
+ """
153
+ Reference to a Form:
154
+ """
155
+ formid: int = Field(primary_key=True, required=True)
156
+ form_name: Optional[str]
157
+ active: bool = Field(default=True)
158
+ client_id: Client
159
+ client_name: str
160
+ orgid: Organization
161
+
162
+ class Meta:
163
+ strict = True
164
+ as_objects = True
165
+ name = 'forms'
166
+ schema: str = 'networkninja'
167
+
168
+ def __post_init__(self):
169
+ super().__post_init__()
170
+ if self.client_id:
171
+ self.client_id.client_name = self.client_name
172
+ self.client_id.orgid = self.orgid
173
+
174
+ async def on_sync(self):
175
+ """
176
+ Sync the form with the database.
177
+ """
178
+ class FormMetadata(AbstractPayload):
179
+ """
180
+ Defines a Form Metadata, a single question from a Form.
181
+
182
+ Example:
183
+ {
184
+ "column_name": "8452",
185
+ "description": "Please provide a photo of the starting odometer reading",
186
+ "is_active": true,
187
+ "data_type": "FIELD_IMAGE_UPLOAD",
188
+ "formid": 1,
189
+ "form_name": "Territory Manager Visit Form TEST",
190
+ "client_id": 59,
191
+ "client_name": "TRENDMICRO",
192
+ "orgid": 77
193
+ }
194
+ """
195
+ # Column ID is not returned by Form Metadata payload but Form Data.
196
+ column_id: int
197
+ formid: Form = Field(primary_key=True, required=True)
198
+ client_id: Client = Field(primary_key=True, required=True)
199
+ column_name: Union[str, int] = Field(primary_key=True, required=True)
200
+ description: str
201
+ data_type: str = Field(required=True, alias='data_type')
202
+ form_name: str
203
+ is_active: bool = Field(required=True, default=True)
204
+ client_name: str
205
+ orgid: Organization = Field(required=True)
206
+
207
+ class Meta:
208
+ strict = True
209
+ as_objects = True
210
+ name = 'form_metadata'
211
+ schema: str = 'networkninja'
212
+
213
+ def __post_init__(self):
214
+ super().__post_init__()
215
+ self.formid.form_name = self.form_name
216
+ if self.column_id is None:
217
+ try:
218
+ self.column_id = int(self.column_name)
219
+ except ValueError:
220
+ self.column_id = 0
221
+ if self.client_id:
222
+ self.client_id.client_name = self.client_name
223
+ self.client_id.orgid = self.orgid
224
+ if self.formid:
225
+ self.formid.client_id = self.client_id
226
+ self.formid.client_name = self.client_name
227
+ self.formid.orgid = self.orgid
228
+ self.formid.form_name = self.form_name
229
+ self.formid.active = self.is_active
230
+
231
+ async def insert_record(self, conn: Any, **kwargs):
232
+ """Insert Record to Database.
233
+ """
234
+ # Convert all objects in dataclass into a INSERT statement
235
+ columns = self.get_fields()
236
+ # remove from column list the "_pgoutput" field
237
+ columns = [col for col in columns if col != '_pgoutput']
238
+ cols = ",".join(columns)
239
+ data = self.to_dict(as_values=True)
240
+ # print('DATA > ', data)
241
+ data.pop('_pgoutput', None)
242
+ _values = ', '.join([f"${i+1}" for i, _ in enumerate(columns)])
243
+ insert = f"INSERT INTO {self.Meta.schema}.{self.Meta.name}({cols}) VALUES({_values})"
244
+ try:
245
+ # Convert data dictionary into a list, ordered by column list:
246
+ source = [data.get(col) for col in columns]
247
+ stmt = await conn.engine().prepare(insert)
248
+ result = await stmt.fetchrow(*source, timeout=2)
249
+ # logging.debug(f"Result: {result}, Status: {stmt.get_statusmsg()}")
250
+ return True
251
+ except UniqueViolationError as e:
252
+ logging.warning(
253
+ f"Error Inserting Record, doing Upsert: {e}"
254
+ )
255
+ return await self.upsert_record(
256
+ pk=['column_name', 'client_id', 'formid'],
257
+ **kwargs
258
+ )
259
+ except Exception as e:
260
+ print(type(e))
261
+ logging.error(
262
+ f"Error Inserting Record: {e}"
263
+ )
264
+ return False
265
+
266
+ class FormResponse(BaseModel):
267
+ """
268
+ Defines a Form Response, a response to a Form.
269
+
270
+ Example:
271
+ {
272
+ "event_id": 10516,
273
+ "column_name": 8550,
274
+ "data": "Arturo",
275
+ "question_shown_to_user": true,
276
+ "column_id": "150698"
277
+ }
278
+ """
279
+ formid: int = Field(required=False)
280
+ form_id: int = Field(required=False)
281
+ column_name: str = Field(primary_key=True)
282
+ column_id: str
283
+ event_id: int
284
+ data: Union[str, None]
285
+ question_shown_to_user: bool = Field(default=True)
286
+ client_id: int
287
+ orgid: int
288
+
289
+ class Meta:
290
+ name: str = 'form_responses'
291
+ schema: str = 'networkninja'
292
+
293
+ class FormData(AbstractPayload):
294
+ """
295
+ Defines a Form Data, a collection of responses to a Form.
296
+
297
+ Example:
298
+ {
299
+ "form_data_id": 1,
300
+ "formid": 1,
301
+ "client_id": 59,
302
+ "orgid": 77,
303
+ "store_id": 1,
304
+ "store_name": "Best Buy 4350",
305
+ "user_id": 1,
306
+ "user_name": "Arturo",
307
+ "created_at": "2025-02-01T00:00:00-06:00",
308
+ "updated_at": "2025-02-01T00:00:00-06:00",
309
+ "form_responses": [
310
+ {
311
+ "column_name": "8550",
312
+ "data": "Arturo",
313
+ "question_shown_to_user": true,
314
+ "column_id": "150698"
315
+ }
316
+ ]
317
+ }
318
+ """
319
+ form_id: int = Field(primary_key=True, required=True)
320
+ formid: int = Field(primary_key=True, required=True)
321
+ previous_form_id: int
322
+ current_form_id: int
323
+ event_id: int = Field(required=False)
324
+ version: str
325
+ creation_timestamp: Optional[datetime]
326
+ start_lat: Optional[float]
327
+ start_lon: Optional[float]
328
+ end_lat: Optional[float]
329
+ end_lon: Optional[float]
330
+ visit_timestamp: Optional[datetime]
331
+ updated_timestamp: Optional[datetime]
332
+ project_id: int = Field(alias='program_id')
333
+ time_in_local: str
334
+ time_in: datetime
335
+ visit_start_local: Optional[datetime]
336
+ visit_end_local: Optional[datetime]
337
+ time_out_local: str
338
+ time_out: datetime
339
+ device_model: str
340
+ visitor_id: int
341
+ visitor_username: str
342
+ visitor_name: str
343
+ visitor_email: str
344
+ visitor_mobile_number: str
345
+ visitor_geography_timezone: str
346
+ user_id: StaffingUser
347
+ position_id: str # TODO: validate position ID
348
+ store_visits_category: int
349
+ store_visits_category_name: str
350
+ visit_status: str
351
+ ad_hoc: bool = Field(required=True, default=False)
352
+ visitor_role: str
353
+ account_id: int
354
+ account_name: str
355
+ retailer: str
356
+ store_number: int = Field(alias="store_id")
357
+ store: Store
358
+ store_name: str
359
+ store_type_id: int
360
+ store_type_name: str
361
+ store_timezone: str
362
+ store_is_active: bool = Field(default=True)
363
+ # hierarchy:
364
+ store_market_id: int
365
+ store_market_name: str
366
+ store_city: str
367
+ store_zipcode: str
368
+ region_id: int
369
+ region_name: str
370
+ district_id: int
371
+ district_name: str
372
+ market_id: int
373
+ market_name: str
374
+ client_id: int = Field(required=True)
375
+ client_name: str
376
+ orgid: int = Field(required=True)
377
+ field_responses: List[FormResponse]
378
+ store_custom_fields: List[CustomStoreField]
379
+ manager_role: str
380
+ is_archived: bool = Field(default=False)
381
+ is_deleted: bool = Field(default=False)
382
+
383
+ class Meta:
384
+ strict = False
385
+ as_objects = True
386
+ name = 'form_data'
387
+ schema: str = 'networkninja'
388
+
389
+ def __post_init__(self):
390
+ super().__post_init__()
391
+ responses = []
392
+ for f in self.field_responses:
393
+ if isinstance(f, dict):
394
+ try:
395
+ responses.append(
396
+ FormResponse(**f)
397
+ )
398
+ except Exception as e:
399
+ print('Error in creating FormResponse instance:', e)
400
+ else:
401
+ responses.append(f)
402
+ self.field_responses = responses
403
+ # Definition of Store Custom Fields
404
+ if self.store_custom_fields:
405
+ for st in self.store_custom_fields:
406
+ st.orgid = self.orgid
407
+ # Definition of Store associated
408
+ if self.store_number:
409
+ self.store = Store(store_number=self.store_number)
410
+ self.store.store_name = self.store_name
411
+ self.store.city = self.store_city
412
+ self.store.zipcode = self.store_zipcode
413
+ self.store.account_id = self.account_id
414
+ self.store.account_name = self.account_name
415
+ if self.store_type_id:
416
+ self.store.store_type_id = StoreType(
417
+ store_type_id=self.store_type_id,
418
+ store_type=self.store_type_name,
419
+ description=self.store_type_name,
420
+ client_id=self.client_id,
421
+ client_name=self.client_name
422
+ )
423
+ self.store.store_timezone = self.store_timezone
424
+ self.store.store_is_active = self.store_is_active
425
+ # Client info:
426
+ self.store.client_id = self.client_id
427
+ self.store.client_name = self.client_name
428
+ self.store.orgid = self.orgid
429
+ self.store.custom_fields = self.store_custom_fields
430
+ # Definition of User associated
431
+ if self.visitor_id:
432
+ args = {
433
+ 'user_id': self.visitor_id,
434
+ 'username': self.visitor_username,
435
+ 'display_name': self.visitor_name,
436
+ 'email_address': self.visitor_email,
437
+ 'mobile_number': self.visitor_mobile_number,
438
+ 'position_id': self.position_id,
439
+ 'role_name': self.visitor_role,
440
+ 'orgid': self.orgid,
441
+ 'client_id': self.client_id,
442
+ }
443
+ try:
444
+ self.user_id = StaffingUser(**args)
445
+ except Exception as e:
446
+ logging.warning(
447
+ f'Error in creating StaffingUser instance: {e}'
448
+ )
449
+
450
+ async def update_form(self):
451
+ new_form = self.form_id
452
+ previous_form = self.previous_form_id
453
+ qry = "UPDATE networkninja.form_data SET form_id = $1 WHERE form_id = $2"
454
+ db = AsyncDB('pg', dsn=default_dsn)
455
+ async with await db.connection() as conn:
456
+ try:
457
+ await conn.execute(qry, new_form, previous_form)
458
+ # But also, delete all the form_responses:
459
+ qry = "DELETE FROM networkninja.form_responses WHERE form_id = $1"
460
+ await conn.execute(qry, previous_form)
461
+ except Exception as e:
462
+ logging.error(f"Error Updating Form: {e}")
463
+
464
+ async def save(self, conn: Any, pk: Union[str, list] = None, **kwargs):
465
+ """
466
+ Always do an UPSERT on Form Data:
467
+ """
468
+ try:
469
+ async with self._pgoutput as conn:
470
+ result = await conn.do_upsert(
471
+ self,
472
+ table_name=self.Meta.name,
473
+ schema=self.Meta.schema,
474
+ primary_keys=['form_id', 'formid'],
475
+ use_conn=conn.get_connection()
476
+ )
477
+ return result
478
+ # # If conn is provided, use it, otherwise use our output connection
479
+ # if conn:
480
+ # result = await self._pgoutput.do_upsert(
481
+ # self,
482
+ # table_name=self.Meta.name,
483
+ # schema=self.Meta.schema,
484
+ # primary_keys=['form_id', 'formid'],
485
+ # use_conn=conn
486
+ # )
487
+ # else:
488
+ # # Use the connection pool for better management
489
+ # async with self._pgoutput as output:
490
+ # result = await output.do_upsert(
491
+ # self,
492
+ # table_name=self.Meta.name,
493
+ # schema=self.Meta.schema,
494
+ # primary_keys=['form_id', 'formid']
495
+ # )
496
+ # return result
497
+ except Exception as e:
498
+ logging.error(f"Error saving form data: {e}")
499
+ raise
@@ -0,0 +1,16 @@
1
+ from datamodel import BaseModel, Field
2
+ from .abstract import AbstractPayload
3
+
4
+ class Market(AbstractPayload):
5
+ market_id: str = Field(required=False, alias='id')
6
+ market_name: str = Field(required=False, alias='name')
7
+ district_id: int
8
+ region_id: int
9
+ client_id: int
10
+ orgid: int
11
+ is_active: bool = Field(required=False, alias='active', default=True)
12
+
13
+ class Meta:
14
+ name: str = 'markets'
15
+ schema: str = 'networkninja'
16
+ strict: bool = True
@@ -0,0 +1,34 @@
1
+ from typing import List, Optional, Union, Any
2
+ from datetime import datetime
3
+ from datamodel import BaseModel, Field
4
+ from asyncdb import AsyncDB
5
+ from querysource.conf import default_dsn
6
+ from .abstract import AbstractPayload
7
+
8
+ class Organization(AbstractPayload):
9
+ orgid: int = Field(required=False)
10
+ organization_name: str
11
+ program_slug: str
12
+ program_id: int
13
+ status: bool = Field(required=True, default=True)
14
+
15
+ class Meta:
16
+ name: str = 'organizations'
17
+ schema: str = 'networkninja'
18
+ strict: bool = True
19
+
20
+ async def _sync_object(self, conn):
21
+ """
22
+ Sync the organization with the Database.
23
+ """
24
+ query = f"""
25
+ select organization_name, company_slug as program_slug, p.program_id
26
+ from troc.organizations o
27
+ inner join auth.programs p on p.program_slug = o.company_slug
28
+ where orgid = {self.orgid}
29
+ """
30
+ result = await conn.fetch_one(query)
31
+ if result:
32
+ self.organization_name = result['organization_name']
33
+ self.program_id = result['program_id']
34
+ self.program_slug = result['program_slug']
@@ -0,0 +1,125 @@
1
+ from typing import Dict, List, Optional, Any, Union
2
+ from datetime import datetime
3
+ from urllib.parse import urlparse, ParseResult
4
+ from datamodel import Field
5
+ from .abstract import AbstractPayload
6
+ from .account import Account
7
+
8
+
9
+ class PhotoCategory(AbstractPayload):
10
+ """
11
+ Photo Category Model.
12
+
13
+ Represents a photo category in the system.
14
+
15
+ Example:
16
+ {
17
+ "category_id": 53,
18
+ "name": "TEST Category",
19
+ "client_id": 61,
20
+ "enabled": false,
21
+ "orgid": 71,
22
+ "client_name": "TRO Walmart Assembly"
23
+ }
24
+ """
25
+ category_id: int = Field(primary_key=True, required=True)
26
+ name: str = Field(alias='category_name')
27
+ client_id: int = Field(alias="category_client_id")
28
+ enabled: bool = Field(default=True)
29
+ orgid: int = Field(alias="category_orgid")
30
+ client_name: str = Field(alias="category_client_name")
31
+
32
+ class Meta:
33
+ strict = True
34
+ as_objects = True
35
+ name = 'photo_categories'
36
+ schema: str = 'networkninja'
37
+
38
+ class Document(AbstractPayload):
39
+ """
40
+ Document Model.
41
+
42
+ Represents a document in the system.
43
+
44
+ Example:
45
+ {
46
+ "document_id": 1,
47
+ "document_name": "Test Document",
48
+ "document_path": "https://www.example.com/test.pdf",
49
+ "description": "Test Document Description",
50
+ "created_on": "2025-02-01T00:00:00-06:00",
51
+ "store_number": "12345",
52
+ "account_id": 1,
53
+ "account_name": "Test Account",
54
+ "question_name": "Test Question",
55
+ "url_parts": "https://www.example.com/test.pdf"
56
+ }
57
+ """
58
+ document_id: int = Field(primary_key=True, required=True)
59
+ document_name: str
60
+ document_path: str
61
+ description: str
62
+ created_on: datetime
63
+ store_number: str
64
+ account_id: Optional[Account]
65
+ account_name: str
66
+ question_name: str
67
+ url_parts: str
68
+
69
+ class Meta:
70
+ strict = True
71
+ as_objects = True
72
+ name = 'documents'
73
+ schema: str = 'networkninja'
74
+
75
+ def __post_init__(self):
76
+ super().__post_init__()
77
+ # split the document_path into parts:
78
+ if self.document_path is not None:
79
+ self.url_parts = urlparse(self.document_path)
80
+
81
+
82
+ class Photo(AbstractPayload):
83
+ photo_id: int = Field(primary_key=True, required=True)
84
+ form_id: int
85
+ formid: Optional[int]
86
+ event_id: int
87
+ description: str
88
+ filename: str
89
+ created_on: datetime
90
+ store_number: Optional[int] = Field(alias='store_id')
91
+ account_id: Account
92
+ account_name: Optional[str]
93
+ column_name: Union[str, int]
94
+ question_name: Optional[str]
95
+ url_parts: Optional[dict]
96
+ photo_path: str
97
+ client_id: int
98
+ client_name: str
99
+ categories: Optional[List[PhotoCategory]]
100
+ is_deleted: bool = Field(default=False)
101
+ is_archived: bool = Field(default=False)
102
+
103
+ class Meta:
104
+ strict = True
105
+ as_objects = True
106
+ name = 'stores_photos'
107
+ schema: str = 'networkninja'
108
+
109
+ def __post_init__(self):
110
+ super().__post_init__()
111
+ self.filename = self.description
112
+ # split the photo_path into parts:
113
+ if self.photo_path is not None:
114
+ # Iterate over all parts and convert into a dictionary of strings:
115
+ parts = urlparse(self.photo_path)
116
+ self.url_parts = {
117
+ 'scheme': parts.scheme,
118
+ 'netloc': parts.netloc,
119
+ 'path': parts.path,
120
+ 'params': parts.params,
121
+ 'query': parts.query,
122
+ 'fragment': parts.fragment,
123
+ }
124
+ if self.account_id:
125
+ self.account_id.account_name = self.account_name