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.
- flowtask/__init__.py +93 -0
- flowtask/__main__.py +38 -0
- flowtask/bots/__init__.py +6 -0
- flowtask/bots/check.py +93 -0
- flowtask/bots/codebot.py +51 -0
- flowtask/components/ASPX.py +148 -0
- flowtask/components/AddDataset.py +352 -0
- flowtask/components/Amazon.py +523 -0
- flowtask/components/AutoTask.py +314 -0
- flowtask/components/Azure.py +80 -0
- flowtask/components/AzureUsers.py +106 -0
- flowtask/components/BaseAction.py +91 -0
- flowtask/components/BaseLoop.py +198 -0
- flowtask/components/BestBuy.py +800 -0
- flowtask/components/CSVToGCS.py +120 -0
- flowtask/components/CompanyScraper/__init__.py +1 -0
- flowtask/components/CompanyScraper/parsers/__init__.py +6 -0
- flowtask/components/CompanyScraper/parsers/base.py +102 -0
- flowtask/components/CompanyScraper/parsers/explorium.py +192 -0
- flowtask/components/CompanyScraper/parsers/leadiq.py +206 -0
- flowtask/components/CompanyScraper/parsers/rocket.py +133 -0
- flowtask/components/CompanyScraper/parsers/siccode.py +109 -0
- flowtask/components/CompanyScraper/parsers/visualvisitor.py +130 -0
- flowtask/components/CompanyScraper/parsers/zoominfo.py +118 -0
- flowtask/components/CompanyScraper/scrapper.py +1054 -0
- flowtask/components/CopyTo.py +177 -0
- flowtask/components/CopyToBigQuery.py +243 -0
- flowtask/components/CopyToMongoDB.py +291 -0
- flowtask/components/CopyToPg.py +609 -0
- flowtask/components/CopyToRethink.py +207 -0
- flowtask/components/CreateGCSBucket.py +102 -0
- flowtask/components/CreateReport/CreateReport.py +228 -0
- flowtask/components/CreateReport/__init__.py +9 -0
- flowtask/components/CreateReport/charts/__init__.py +15 -0
- flowtask/components/CreateReport/charts/bar.py +51 -0
- flowtask/components/CreateReport/charts/base.py +66 -0
- flowtask/components/CreateReport/charts/pie.py +64 -0
- flowtask/components/CreateReport/utils.py +9 -0
- flowtask/components/CustomerSatisfaction.py +196 -0
- flowtask/components/DataInput.py +200 -0
- flowtask/components/DateList.py +255 -0
- flowtask/components/DbClient.py +163 -0
- flowtask/components/DialPad.py +146 -0
- flowtask/components/DocumentDBQuery.py +200 -0
- flowtask/components/DownloadFrom.py +371 -0
- flowtask/components/DownloadFromD2L.py +113 -0
- flowtask/components/DownloadFromFTP.py +181 -0
- flowtask/components/DownloadFromIMAP.py +315 -0
- flowtask/components/DownloadFromS3.py +198 -0
- flowtask/components/DownloadFromSFTP.py +265 -0
- flowtask/components/DownloadFromSharepoint.py +110 -0
- flowtask/components/DownloadFromSmartSheet.py +114 -0
- flowtask/components/DownloadS3File.py +229 -0
- flowtask/components/Dummy.py +59 -0
- flowtask/components/DuplicatePhoto.py +411 -0
- flowtask/components/EmployeeEvaluation.py +237 -0
- flowtask/components/ExecuteSQL.py +323 -0
- flowtask/components/ExtractHTML.py +178 -0
- flowtask/components/FileBase.py +178 -0
- flowtask/components/FileCopy.py +181 -0
- flowtask/components/FileDelete.py +82 -0
- flowtask/components/FileExists.py +146 -0
- flowtask/components/FileIteratorDelete.py +112 -0
- flowtask/components/FileList.py +194 -0
- flowtask/components/FileOpen.py +75 -0
- flowtask/components/FileRead.py +120 -0
- flowtask/components/FileRename.py +106 -0
- flowtask/components/FilterIf.py +284 -0
- flowtask/components/FilterRows/FilterRows.py +200 -0
- flowtask/components/FilterRows/__init__.py +10 -0
- flowtask/components/FilterRows/functions.py +4 -0
- flowtask/components/GCSToBigQuery.py +103 -0
- flowtask/components/GoogleA4.py +150 -0
- flowtask/components/GoogleGeoCoding.py +344 -0
- flowtask/components/GooglePlaces.py +315 -0
- flowtask/components/GoogleSearch.py +539 -0
- flowtask/components/HTTPClient.py +268 -0
- flowtask/components/ICIMS.py +146 -0
- flowtask/components/IF.py +179 -0
- flowtask/components/IcimsFolderCopy.py +173 -0
- flowtask/components/ImageFeatures/__init__.py +5 -0
- flowtask/components/ImageFeatures/process.py +233 -0
- flowtask/components/IteratorBase.py +251 -0
- flowtask/components/LangchainLoader/__init__.py +5 -0
- flowtask/components/LangchainLoader/loader.py +194 -0
- flowtask/components/LangchainLoader/loaders/__init__.py +22 -0
- flowtask/components/LangchainLoader/loaders/abstract.py +362 -0
- flowtask/components/LangchainLoader/loaders/basepdf.py +50 -0
- flowtask/components/LangchainLoader/loaders/docx.py +91 -0
- flowtask/components/LangchainLoader/loaders/html.py +119 -0
- flowtask/components/LangchainLoader/loaders/pdfblocks.py +146 -0
- flowtask/components/LangchainLoader/loaders/pdfmark.py +79 -0
- flowtask/components/LangchainLoader/loaders/pdftables.py +135 -0
- flowtask/components/LangchainLoader/loaders/qa.py +67 -0
- flowtask/components/LangchainLoader/loaders/txt.py +55 -0
- flowtask/components/LeadIQ.py +650 -0
- flowtask/components/Loop.py +253 -0
- flowtask/components/Lowes.py +334 -0
- flowtask/components/MS365Usage.py +156 -0
- flowtask/components/MSTeamsMessages.py +320 -0
- flowtask/components/MarketClustering.py +1051 -0
- flowtask/components/MergeFiles.py +362 -0
- flowtask/components/MilvusOutput.py +87 -0
- flowtask/components/NearByStores.py +175 -0
- flowtask/components/NetworkNinja/__init__.py +6 -0
- flowtask/components/NetworkNinja/models/__init__.py +52 -0
- flowtask/components/NetworkNinja/models/abstract.py +177 -0
- flowtask/components/NetworkNinja/models/account.py +39 -0
- flowtask/components/NetworkNinja/models/client.py +19 -0
- flowtask/components/NetworkNinja/models/district.py +14 -0
- flowtask/components/NetworkNinja/models/events.py +101 -0
- flowtask/components/NetworkNinja/models/forms.py +499 -0
- flowtask/components/NetworkNinja/models/market.py +16 -0
- flowtask/components/NetworkNinja/models/organization.py +34 -0
- flowtask/components/NetworkNinja/models/photos.py +125 -0
- flowtask/components/NetworkNinja/models/project.py +44 -0
- flowtask/components/NetworkNinja/models/region.py +28 -0
- flowtask/components/NetworkNinja/models/store.py +203 -0
- flowtask/components/NetworkNinja/models/user.py +151 -0
- flowtask/components/NetworkNinja/router.py +854 -0
- flowtask/components/Odoo.py +175 -0
- flowtask/components/OdooInjector.py +192 -0
- flowtask/components/OpenFromXML.py +126 -0
- flowtask/components/OpenWeather.py +41 -0
- flowtask/components/OpenWithBase.py +616 -0
- flowtask/components/OpenWithPandas.py +715 -0
- flowtask/components/PGPDecrypt.py +199 -0
- flowtask/components/PandasIterator.py +187 -0
- flowtask/components/PandasToFile.py +189 -0
- flowtask/components/Paradox.py +339 -0
- flowtask/components/ParamIterator.py +117 -0
- flowtask/components/ParseHTML.py +84 -0
- flowtask/components/PlacerStores.py +249 -0
- flowtask/components/Pokemon.py +507 -0
- flowtask/components/PositiveBot.py +62 -0
- flowtask/components/PowerPointSlide.py +400 -0
- flowtask/components/PrintMessage.py +127 -0
- flowtask/components/ProductCompetitors/__init__.py +5 -0
- flowtask/components/ProductCompetitors/parsers/__init__.py +7 -0
- flowtask/components/ProductCompetitors/parsers/base.py +72 -0
- flowtask/components/ProductCompetitors/parsers/bestbuy.py +86 -0
- flowtask/components/ProductCompetitors/parsers/lowes.py +103 -0
- flowtask/components/ProductCompetitors/scrapper.py +155 -0
- flowtask/components/ProductCompliant.py +169 -0
- flowtask/components/ProductInfo/__init__.py +1 -0
- flowtask/components/ProductInfo/parsers/__init__.py +5 -0
- flowtask/components/ProductInfo/parsers/base.py +83 -0
- flowtask/components/ProductInfo/parsers/brother.py +97 -0
- flowtask/components/ProductInfo/parsers/canon.py +167 -0
- flowtask/components/ProductInfo/parsers/epson.py +118 -0
- flowtask/components/ProductInfo/parsers/hp.py +131 -0
- flowtask/components/ProductInfo/parsers/samsung.py +97 -0
- flowtask/components/ProductInfo/scraper.py +319 -0
- flowtask/components/ProductPricing.py +118 -0
- flowtask/components/QS.py +261 -0
- flowtask/components/QSBase.py +201 -0
- flowtask/components/QueryIterator.py +273 -0
- flowtask/components/QueryToInsert.py +327 -0
- flowtask/components/QueryToPandas.py +432 -0
- flowtask/components/RESTClient.py +195 -0
- flowtask/components/RethinkDBQuery.py +189 -0
- flowtask/components/Rsync.py +74 -0
- flowtask/components/RunSSH.py +59 -0
- flowtask/components/RunShell.py +71 -0
- flowtask/components/SalesForce.py +20 -0
- flowtask/components/SaveImageBank/__init__.py +257 -0
- flowtask/components/SchedulingVisits.py +592 -0
- flowtask/components/ScrapPage.py +216 -0
- flowtask/components/ScrapSearch.py +79 -0
- flowtask/components/SendNotify.py +257 -0
- flowtask/components/SentimentAnalysis.py +694 -0
- flowtask/components/ServiceScrapper/__init__.py +5 -0
- flowtask/components/ServiceScrapper/parsers/__init__.py +1 -0
- flowtask/components/ServiceScrapper/parsers/base.py +94 -0
- flowtask/components/ServiceScrapper/parsers/costco.py +93 -0
- flowtask/components/ServiceScrapper/scrapper.py +199 -0
- flowtask/components/SetVariables.py +156 -0
- flowtask/components/SubTask.py +182 -0
- flowtask/components/SuiteCRM.py +48 -0
- flowtask/components/Switch.py +175 -0
- flowtask/components/TableBase.py +148 -0
- flowtask/components/TableDelete.py +312 -0
- flowtask/components/TableInput.py +143 -0
- flowtask/components/TableOutput/TableOutput.py +384 -0
- flowtask/components/TableOutput/__init__.py +3 -0
- flowtask/components/TableSchema.py +534 -0
- flowtask/components/Target.py +223 -0
- flowtask/components/ThumbnailGenerator.py +156 -0
- flowtask/components/ToPandas.py +67 -0
- flowtask/components/TransformRows/TransformRows.py +507 -0
- flowtask/components/TransformRows/__init__.py +9 -0
- flowtask/components/TransformRows/functions.py +559 -0
- flowtask/components/TransposeRows.py +176 -0
- flowtask/components/UPCDatabase.py +86 -0
- flowtask/components/UnGzip.py +171 -0
- flowtask/components/Uncompress.py +172 -0
- flowtask/components/UniqueRows.py +126 -0
- flowtask/components/Unzip.py +107 -0
- flowtask/components/UpdateOperationalVars.py +147 -0
- flowtask/components/UploadTo.py +299 -0
- flowtask/components/UploadToS3.py +136 -0
- flowtask/components/UploadToSFTP.py +160 -0
- flowtask/components/UploadToSharepoint.py +205 -0
- flowtask/components/UserFunc.py +122 -0
- flowtask/components/VivaTracker.py +140 -0
- flowtask/components/WSDLClient.py +123 -0
- flowtask/components/Wait.py +18 -0
- flowtask/components/Walmart.py +199 -0
- flowtask/components/Workplace.py +134 -0
- flowtask/components/XMLToPandas.py +267 -0
- flowtask/components/Zammad/__init__.py +41 -0
- flowtask/components/Zammad/models.py +0 -0
- flowtask/components/ZoomInfoScraper.py +409 -0
- flowtask/components/__init__.py +104 -0
- flowtask/components/abstract.py +18 -0
- flowtask/components/flow.py +530 -0
- flowtask/components/google.py +335 -0
- flowtask/components/group.py +221 -0
- flowtask/components/py.typed +0 -0
- flowtask/components/reviewscrap.py +132 -0
- flowtask/components/tAutoincrement.py +117 -0
- flowtask/components/tConcat.py +109 -0
- flowtask/components/tExplode.py +119 -0
- flowtask/components/tFilter.py +184 -0
- flowtask/components/tGroup.py +236 -0
- flowtask/components/tJoin.py +270 -0
- flowtask/components/tMap/__init__.py +9 -0
- flowtask/components/tMap/functions.py +54 -0
- flowtask/components/tMap/tMap.py +450 -0
- flowtask/components/tMelt.py +112 -0
- flowtask/components/tMerge.py +114 -0
- flowtask/components/tOrder.py +93 -0
- flowtask/components/tPandas.py +94 -0
- flowtask/components/tPivot.py +71 -0
- flowtask/components/tPluckCols.py +76 -0
- flowtask/components/tUnnest.py +82 -0
- flowtask/components/user.py +401 -0
- flowtask/conf.py +457 -0
- flowtask/download.py +102 -0
- flowtask/events/__init__.py +11 -0
- flowtask/events/events/__init__.py +20 -0
- flowtask/events/events/abstract.py +95 -0
- flowtask/events/events/alerts/__init__.py +362 -0
- flowtask/events/events/alerts/colfunctions.py +131 -0
- flowtask/events/events/alerts/functions.py +158 -0
- flowtask/events/events/dummy.py +12 -0
- flowtask/events/events/exec.py +124 -0
- flowtask/events/events/file/__init__.py +7 -0
- flowtask/events/events/file/base.py +51 -0
- flowtask/events/events/file/copy.py +23 -0
- flowtask/events/events/file/delete.py +16 -0
- flowtask/events/events/interfaces/__init__.py +9 -0
- flowtask/events/events/interfaces/client.py +67 -0
- flowtask/events/events/interfaces/credentials.py +28 -0
- flowtask/events/events/interfaces/notifications.py +58 -0
- flowtask/events/events/jira.py +122 -0
- flowtask/events/events/log.py +26 -0
- flowtask/events/events/logerr.py +52 -0
- flowtask/events/events/notify.py +59 -0
- flowtask/events/events/notify_event.py +160 -0
- flowtask/events/events/publish.py +54 -0
- flowtask/events/events/sendfile.py +104 -0
- flowtask/events/events/task.py +97 -0
- flowtask/events/events/teams.py +98 -0
- flowtask/events/events/webhook.py +58 -0
- flowtask/events/manager.py +287 -0
- flowtask/exceptions.c +39393 -0
- flowtask/exceptions.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/extensions/__init__.py +3 -0
- flowtask/extensions/abstract.py +82 -0
- flowtask/extensions/logging/__init__.py +65 -0
- flowtask/hooks/__init__.py +9 -0
- flowtask/hooks/actions/__init__.py +22 -0
- flowtask/hooks/actions/abstract.py +66 -0
- flowtask/hooks/actions/dummy.py +23 -0
- flowtask/hooks/actions/jira.py +74 -0
- flowtask/hooks/actions/rest.py +320 -0
- flowtask/hooks/actions/sampledata.py +37 -0
- flowtask/hooks/actions/sensor.py +23 -0
- flowtask/hooks/actions/task.py +9 -0
- flowtask/hooks/actions/ticket.py +37 -0
- flowtask/hooks/actions/zammad.py +55 -0
- flowtask/hooks/hook.py +62 -0
- flowtask/hooks/models.py +17 -0
- flowtask/hooks/service.py +187 -0
- flowtask/hooks/step.py +91 -0
- flowtask/hooks/types/__init__.py +23 -0
- flowtask/hooks/types/base.py +129 -0
- flowtask/hooks/types/brokers/__init__.py +11 -0
- flowtask/hooks/types/brokers/base.py +54 -0
- flowtask/hooks/types/brokers/mqtt.py +35 -0
- flowtask/hooks/types/brokers/rabbitmq.py +82 -0
- flowtask/hooks/types/brokers/redis.py +83 -0
- flowtask/hooks/types/brokers/sqs.py +44 -0
- flowtask/hooks/types/fs.py +232 -0
- flowtask/hooks/types/http.py +49 -0
- flowtask/hooks/types/imap.py +200 -0
- flowtask/hooks/types/jira.py +279 -0
- flowtask/hooks/types/mail.py +205 -0
- flowtask/hooks/types/postgres.py +98 -0
- flowtask/hooks/types/responses/__init__.py +8 -0
- flowtask/hooks/types/responses/base.py +5 -0
- flowtask/hooks/types/sharepoint.py +288 -0
- flowtask/hooks/types/ssh.py +141 -0
- flowtask/hooks/types/tagged.py +59 -0
- flowtask/hooks/types/upload.py +85 -0
- flowtask/hooks/types/watch.py +71 -0
- flowtask/hooks/types/web.py +36 -0
- flowtask/interfaces/AzureClient.py +137 -0
- flowtask/interfaces/AzureGraph.py +839 -0
- flowtask/interfaces/Boto3Client.py +326 -0
- flowtask/interfaces/DropboxClient.py +173 -0
- flowtask/interfaces/ExcelHandler.py +94 -0
- flowtask/interfaces/FTPClient.py +131 -0
- flowtask/interfaces/GoogleCalendar.py +201 -0
- flowtask/interfaces/GoogleClient.py +133 -0
- flowtask/interfaces/GoogleDrive.py +127 -0
- flowtask/interfaces/GoogleGCS.py +89 -0
- flowtask/interfaces/GoogleGeocoding.py +93 -0
- flowtask/interfaces/GoogleLang.py +114 -0
- flowtask/interfaces/GooglePub.py +61 -0
- flowtask/interfaces/GoogleSheet.py +68 -0
- flowtask/interfaces/IMAPClient.py +137 -0
- flowtask/interfaces/O365Calendar.py +113 -0
- flowtask/interfaces/O365Client.py +220 -0
- flowtask/interfaces/OneDrive.py +284 -0
- flowtask/interfaces/Outlook.py +155 -0
- flowtask/interfaces/ParrotBot.py +130 -0
- flowtask/interfaces/SSHClient.py +378 -0
- flowtask/interfaces/Sharepoint.py +496 -0
- flowtask/interfaces/__init__.py +36 -0
- flowtask/interfaces/azureauth.py +119 -0
- flowtask/interfaces/cache.py +201 -0
- flowtask/interfaces/client.py +82 -0
- flowtask/interfaces/compress.py +525 -0
- flowtask/interfaces/credentials.py +124 -0
- flowtask/interfaces/d2l.py +239 -0
- flowtask/interfaces/databases/__init__.py +5 -0
- flowtask/interfaces/databases/db.py +223 -0
- flowtask/interfaces/databases/documentdb.py +55 -0
- flowtask/interfaces/databases/rethink.py +39 -0
- flowtask/interfaces/dataframes/__init__.py +11 -0
- flowtask/interfaces/dataframes/abstract.py +21 -0
- flowtask/interfaces/dataframes/arrow.py +71 -0
- flowtask/interfaces/dataframes/dt.py +69 -0
- flowtask/interfaces/dataframes/pandas.py +167 -0
- flowtask/interfaces/dataframes/polars.py +60 -0
- flowtask/interfaces/db.py +263 -0
- flowtask/interfaces/env.py +46 -0
- flowtask/interfaces/func.py +137 -0
- flowtask/interfaces/http.py +1780 -0
- flowtask/interfaces/locale.py +40 -0
- flowtask/interfaces/log.py +75 -0
- flowtask/interfaces/mask.py +143 -0
- flowtask/interfaces/notification.py +154 -0
- flowtask/interfaces/playwright.py +339 -0
- flowtask/interfaces/powerpoint.py +368 -0
- flowtask/interfaces/py.typed +0 -0
- flowtask/interfaces/qs.py +376 -0
- flowtask/interfaces/result.py +87 -0
- flowtask/interfaces/selenium_service.py +779 -0
- flowtask/interfaces/smartsheet.py +154 -0
- flowtask/interfaces/stat.py +39 -0
- flowtask/interfaces/task.py +96 -0
- flowtask/interfaces/template.py +118 -0
- flowtask/interfaces/vectorstores/__init__.py +1 -0
- flowtask/interfaces/vectorstores/abstract.py +133 -0
- flowtask/interfaces/vectorstores/milvus.py +669 -0
- flowtask/interfaces/zammad.py +107 -0
- flowtask/models.py +193 -0
- flowtask/parsers/__init__.py +15 -0
- flowtask/parsers/_yaml.c +11978 -0
- flowtask/parsers/_yaml.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/argparser.py +235 -0
- flowtask/parsers/base.c +15155 -0
- flowtask/parsers/base.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/json.c +11968 -0
- flowtask/parsers/json.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/maps.py +49 -0
- flowtask/parsers/toml.c +11968 -0
- flowtask/parsers/toml.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/plugins/__init__.py +16 -0
- flowtask/plugins/components/__init__.py +0 -0
- flowtask/plugins/handler/__init__.py +45 -0
- flowtask/plugins/importer.py +31 -0
- flowtask/plugins/sources/__init__.py +0 -0
- flowtask/runner.py +283 -0
- flowtask/scheduler/__init__.py +9 -0
- flowtask/scheduler/functions.py +493 -0
- flowtask/scheduler/handlers/__init__.py +8 -0
- flowtask/scheduler/handlers/manager.py +504 -0
- flowtask/scheduler/handlers/models.py +58 -0
- flowtask/scheduler/handlers/service.py +72 -0
- flowtask/scheduler/notifications.py +65 -0
- flowtask/scheduler/scheduler.py +993 -0
- flowtask/services/__init__.py +0 -0
- flowtask/services/bots/__init__.py +0 -0
- flowtask/services/bots/telegram.py +264 -0
- flowtask/services/files/__init__.py +11 -0
- flowtask/services/files/manager.py +522 -0
- flowtask/services/files/model.py +37 -0
- flowtask/services/files/service.py +767 -0
- flowtask/services/jira/__init__.py +3 -0
- flowtask/services/jira/jira_actions.py +191 -0
- flowtask/services/tasks/__init__.py +13 -0
- flowtask/services/tasks/launcher.py +213 -0
- flowtask/services/tasks/manager.py +323 -0
- flowtask/services/tasks/service.py +275 -0
- flowtask/services/tasks/task_manager.py +376 -0
- flowtask/services/tasks/tasks.py +155 -0
- flowtask/storages/__init__.py +16 -0
- flowtask/storages/exceptions.py +12 -0
- flowtask/storages/files/__init__.py +8 -0
- flowtask/storages/files/abstract.py +29 -0
- flowtask/storages/files/filesystem.py +66 -0
- flowtask/storages/tasks/__init__.py +19 -0
- flowtask/storages/tasks/abstract.py +26 -0
- flowtask/storages/tasks/database.py +33 -0
- flowtask/storages/tasks/filesystem.py +108 -0
- flowtask/storages/tasks/github.py +119 -0
- flowtask/storages/tasks/memory.py +45 -0
- flowtask/storages/tasks/row.py +25 -0
- flowtask/tasks/__init__.py +0 -0
- flowtask/tasks/abstract.py +526 -0
- flowtask/tasks/command.py +118 -0
- flowtask/tasks/pile.py +486 -0
- flowtask/tasks/py.typed +0 -0
- flowtask/tasks/task.py +778 -0
- flowtask/template/__init__.py +161 -0
- flowtask/tests.py +257 -0
- flowtask/types/__init__.py +8 -0
- flowtask/types/typedefs.c +11347 -0
- flowtask/types/typedefs.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/utils/__init__.py +24 -0
- flowtask/utils/constants.py +117 -0
- flowtask/utils/encoders.py +21 -0
- flowtask/utils/executor.py +112 -0
- flowtask/utils/functions.cpp +14280 -0
- flowtask/utils/functions.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/utils/json.cpp +13349 -0
- flowtask/utils/json.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/utils/mail.py +63 -0
- flowtask/utils/parseqs.c +13324 -0
- flowtask/utils/parserqs.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/utils/stats.py +308 -0
- flowtask/utils/transformations.py +74 -0
- flowtask/utils/uv.py +12 -0
- flowtask/utils/validators.py +97 -0
- flowtask/version.py +11 -0
- flowtask-5.8.4.dist-info/LICENSE +201 -0
- flowtask-5.8.4.dist-info/METADATA +209 -0
- flowtask-5.8.4.dist-info/RECORD +470 -0
- flowtask-5.8.4.dist-info/WHEEL +6 -0
- flowtask-5.8.4.dist-info/entry_points.txt +3 -0
- flowtask-5.8.4.dist-info/top_level.txt +2 -0
- plugins/components/CreateQR.py +39 -0
- plugins/components/TestComponent.py +28 -0
- plugins/components/Use1.py +13 -0
- plugins/components/Workplace.py +117 -0
- plugins/components/__init__.py +3 -0
- plugins/sources/__init__.py +0 -0
- plugins/sources/get_populartimes.py +78 -0
- plugins/sources/google.py +150 -0
- plugins/sources/hubspot.py +679 -0
- plugins/sources/icims.py +679 -0
- plugins/sources/mobileinsight.py +501 -0
- plugins/sources/newrelic.py +262 -0
- plugins/sources/uap.py +268 -0
- plugins/sources/venu.py +244 -0
- plugins/sources/vocinity.py +314 -0
@@ -0,0 +1,493 @@
|
|
1
|
+
import asyncio
|
2
|
+
from typing import Any
|
3
|
+
from collections.abc import Callable
|
4
|
+
import time
|
5
|
+
from functools import partial
|
6
|
+
from concurrent.futures import ThreadPoolExecutor
|
7
|
+
from asyncdb import AsyncDB
|
8
|
+
from asyncdb.exceptions import NoDataFound
|
9
|
+
from navconfig.logging import logging
|
10
|
+
from redis import asyncio as aioredis
|
11
|
+
from querysource.types.validators import Entity
|
12
|
+
# Queue Worker Client:
|
13
|
+
from qw.wrappers import TaskWrapper
|
14
|
+
from qw.client import QClient
|
15
|
+
from ..conf import (
|
16
|
+
DEBUG,
|
17
|
+
default_pg,
|
18
|
+
SCHEDULER_WORKER_TIMEOUT,
|
19
|
+
SCHEDULER_RETRY_ENQUEUE,
|
20
|
+
SCHEDULER_MAX_RETRY_ENQUEUE,
|
21
|
+
SCHEDULER_DEFAULT_NOTIFY,
|
22
|
+
PUBSUB_REDIS,
|
23
|
+
WORKERS_LIST
|
24
|
+
)
|
25
|
+
from ..tasks.task import Task
|
26
|
+
from ..exceptions import (
|
27
|
+
FileError,
|
28
|
+
FileNotFound,
|
29
|
+
NotSupported,
|
30
|
+
TaskFailed,
|
31
|
+
TaskNotFound,
|
32
|
+
DataNotFound,
|
33
|
+
)
|
34
|
+
from .notifications import send_notification
|
35
|
+
|
36
|
+
|
37
|
+
def import_from_path(path):
|
38
|
+
"""Import a module / class from a path string.
|
39
|
+
:param str path: class path, e.g., ndscheduler.corescheduler.job
|
40
|
+
:return: class object
|
41
|
+
:rtype: class
|
42
|
+
"""
|
43
|
+
components = path.split(".")
|
44
|
+
module = __import__(".".join(components[:-1]))
|
45
|
+
for comp in components[1:-1]:
|
46
|
+
module = getattr(module, comp)
|
47
|
+
return getattr(module, components[-1])
|
48
|
+
|
49
|
+
|
50
|
+
class TaskScheduler:
|
51
|
+
def __init__(
|
52
|
+
self,
|
53
|
+
program,
|
54
|
+
task,
|
55
|
+
job_id: str,
|
56
|
+
priority: str = "low",
|
57
|
+
worker: Callable = None,
|
58
|
+
**kwargs,
|
59
|
+
):
|
60
|
+
self.task = task
|
61
|
+
self.program = program
|
62
|
+
self.priority = priority
|
63
|
+
self.worker = worker
|
64
|
+
self._scheduled: bool = False
|
65
|
+
self.wrapper = TaskWrapper(
|
66
|
+
program=program, task=task, ignore_results=True, **kwargs
|
67
|
+
)
|
68
|
+
self.task_id = self.wrapper.id
|
69
|
+
self.job_id = job_id
|
70
|
+
self.logger = logging.getLogger(
|
71
|
+
f"Job.{job_id}.{self.task_id}"
|
72
|
+
)
|
73
|
+
|
74
|
+
async def set_task_status(self, state, error):
|
75
|
+
# TODO: migrate to Prepared statements
|
76
|
+
_new = False
|
77
|
+
try:
|
78
|
+
event_loop = asyncio.get_event_loop()
|
79
|
+
except RuntimeError:
|
80
|
+
event_loop = asyncio.new_event_loop()
|
81
|
+
asyncio.set_event_loop(event_loop)
|
82
|
+
_new = True
|
83
|
+
trace = Entity.escapeString(error)
|
84
|
+
sentence = f"""UPDATE {self.program}.tasks
|
85
|
+
SET task_state='{state}', traceback='{trace}'
|
86
|
+
WHERE task = '{self.task}';"""
|
87
|
+
result = None
|
88
|
+
options = {
|
89
|
+
"server_settings": {
|
90
|
+
"application_name": "Flowtask.Scheduler",
|
91
|
+
"client_min_messages": "notice",
|
92
|
+
}
|
93
|
+
}
|
94
|
+
conn = AsyncDB(
|
95
|
+
"pg",
|
96
|
+
dsn=default_pg,
|
97
|
+
loop=event_loop,
|
98
|
+
**options
|
99
|
+
)
|
100
|
+
try:
|
101
|
+
async with await conn.connection() as conn:
|
102
|
+
result, error = await conn.execute(sentence)
|
103
|
+
if error:
|
104
|
+
self.logger.error(str(error))
|
105
|
+
return result
|
106
|
+
except Exception as err:
|
107
|
+
self.logger.error(f"Task State Error: {err}")
|
108
|
+
finally:
|
109
|
+
if _new:
|
110
|
+
event_loop.stop()
|
111
|
+
|
112
|
+
async def _schedule_task(self, wrapper, queue):
|
113
|
+
start_time = time.time()
|
114
|
+
try:
|
115
|
+
while True:
|
116
|
+
try:
|
117
|
+
return await asyncio.wait_for(
|
118
|
+
queue.queue(wrapper), timeout=SCHEDULER_WORKER_TIMEOUT
|
119
|
+
)
|
120
|
+
except asyncio.QueueFull as exc:
|
121
|
+
self.logger.error(
|
122
|
+
f"Task {wrapper!r} was missed for enqueue due Queue Full {exc}"
|
123
|
+
)
|
124
|
+
# Set Task State as Discarded:
|
125
|
+
await self.set_task_status(13, str(exc))
|
126
|
+
raise TaskFailed(
|
127
|
+
f"Task {wrapper!r} was discarded due Queue Full {exc}"
|
128
|
+
) from exc
|
129
|
+
except asyncio.TimeoutError as exc:
|
130
|
+
elapsed_time = time.time() - start_time
|
131
|
+
# If more than SCHEDULER_MAX_RETRY_ENQUEUE seconds have passed
|
132
|
+
if elapsed_time >= SCHEDULER_MAX_RETRY_ENQUEUE:
|
133
|
+
self.logger.error(
|
134
|
+
f"Task Discarded {self.program}.{self.task}: {exc}"
|
135
|
+
)
|
136
|
+
# Set Task State as Discarded:
|
137
|
+
await self.set_task_status(13, str(exc))
|
138
|
+
raise TaskFailed(
|
139
|
+
f"Task {wrapper!r} was discarded due timeout {exc}"
|
140
|
+
) from exc
|
141
|
+
self.logger.warning(
|
142
|
+
f"Task {wrapper!r} could not be enqueued.\
|
143
|
+
Retrying in {SCHEDULER_RETRY_ENQUEUE} seconds."
|
144
|
+
)
|
145
|
+
# Wait for 10 seconds before retrying
|
146
|
+
await asyncio.sleep(SCHEDULER_RETRY_ENQUEUE)
|
147
|
+
except OSError as exc:
|
148
|
+
self.logger.error(
|
149
|
+
f"Task {wrapper!r} can't be enqueued Due OS Error: {exc}"
|
150
|
+
)
|
151
|
+
raise
|
152
|
+
except Exception as exc:
|
153
|
+
msg = f"Task {wrapper!r} can't be enqueued Due Error: {exc}"
|
154
|
+
await self.set_task_status(13, str(msg))
|
155
|
+
self.logger.error(
|
156
|
+
f"Task {wrapper!r} can't be enqueued by Error: {exc}"
|
157
|
+
)
|
158
|
+
raise
|
159
|
+
except KeyboardInterrupt:
|
160
|
+
return None
|
161
|
+
|
162
|
+
async def _send_task(self, wrapper, queue):
|
163
|
+
"""_send_task.
|
164
|
+
|
165
|
+
Send a Task directly to Worker avoiding Worker Queue.
|
166
|
+
"""
|
167
|
+
try:
|
168
|
+
result = await queue.run(wrapper)
|
169
|
+
await asyncio.sleep(0.01)
|
170
|
+
return result
|
171
|
+
except (OSError, asyncio.TimeoutError):
|
172
|
+
raise
|
173
|
+
except Exception as exc:
|
174
|
+
self.logger.error(f"{exc}")
|
175
|
+
raise
|
176
|
+
|
177
|
+
async def _publish_task(self, wrapper, queue):
|
178
|
+
try:
|
179
|
+
result = await queue.publish(wrapper)
|
180
|
+
await asyncio.sleep(0.01)
|
181
|
+
return result
|
182
|
+
except asyncio.TimeoutError:
|
183
|
+
raise
|
184
|
+
except Exception as exc:
|
185
|
+
self.logger.error(f"{exc}")
|
186
|
+
raise
|
187
|
+
|
188
|
+
async def save_task_id(self):
|
189
|
+
try:
|
190
|
+
redis = aioredis.from_url(
|
191
|
+
PUBSUB_REDIS, encoding="utf-8", decode_responses=True
|
192
|
+
)
|
193
|
+
# Expire the key after 1 hour (3600 seconds)
|
194
|
+
await redis.setex(str(self.task_id), 3600, self.job_id)
|
195
|
+
except Exception as exc:
|
196
|
+
self.logger.error(
|
197
|
+
f"Task ID {self.task_id!r} can't be saved due Error: {exc}"
|
198
|
+
)
|
199
|
+
raise
|
200
|
+
finally:
|
201
|
+
await redis.close()
|
202
|
+
try:
|
203
|
+
await redis.connection_pool.disconnect()
|
204
|
+
except Exception:
|
205
|
+
pass
|
206
|
+
|
207
|
+
def __call__(self, *args, **kwargs):
|
208
|
+
try:
|
209
|
+
try:
|
210
|
+
loop = asyncio.new_event_loop()
|
211
|
+
except RuntimeError as exc:
|
212
|
+
raise RuntimeError(
|
213
|
+
f"Unable to create a New Event Loop for Dispatching Tasks: {exc}"
|
214
|
+
) from exc
|
215
|
+
asyncio.set_event_loop(loop)
|
216
|
+
self.logger.info(
|
217
|
+
f":::: Calling Task {self.program}.{self.task}: priority {self.priority!s}"
|
218
|
+
)
|
219
|
+
if self.priority == "direct":
|
220
|
+
# Direct connection to worker (avoid Worker Queue)
|
221
|
+
task = loop.create_task(
|
222
|
+
self._send_task(self.wrapper, self.worker)
|
223
|
+
)
|
224
|
+
elif self.priority == "pub":
|
225
|
+
# Using Channel Group mechanism (avoid queueing)
|
226
|
+
task = loop.create_task(
|
227
|
+
self._publish_task(self.wrapper, self.worker)
|
228
|
+
)
|
229
|
+
elif self.priority in ('high', 'low'):
|
230
|
+
task = loop.create_task(
|
231
|
+
self._schedule_task(self.wrapper, self.worker)
|
232
|
+
)
|
233
|
+
self._scheduled = True
|
234
|
+
else:
|
235
|
+
# Extract which worker to use:
|
236
|
+
try:
|
237
|
+
w = WORKERS_LIST[self.priority]
|
238
|
+
worker = QClient(worker_list=w)
|
239
|
+
except KeyError:
|
240
|
+
self.logger.error(
|
241
|
+
f"Worker {self.priority!r} not found in Workers List"
|
242
|
+
)
|
243
|
+
worker = self.worker
|
244
|
+
task = loop.create_task(
|
245
|
+
self._schedule_task(self.wrapper, worker)
|
246
|
+
)
|
247
|
+
self._scheduled = True
|
248
|
+
try:
|
249
|
+
result = loop.run_until_complete(task)
|
250
|
+
if hasattr(result, "get"):
|
251
|
+
message = result.get("message", None)
|
252
|
+
self.logger.info(f"SCHED: {message!r}")
|
253
|
+
else:
|
254
|
+
self.logger.info(
|
255
|
+
f"Executed: {self.program}.{self.task} with status {result!r}"
|
256
|
+
)
|
257
|
+
# Save UUID of task execution:
|
258
|
+
loop.run_until_complete(self.save_task_id())
|
259
|
+
return result
|
260
|
+
except asyncio.TimeoutError: # pragma: no cover
|
261
|
+
self.logger.error(
|
262
|
+
f"Scheduler: Cannot add task {self.program}.{self.task} to Queue Worker due Timeout."
|
263
|
+
)
|
264
|
+
send_notification(
|
265
|
+
loop,
|
266
|
+
message=f"Scheduler: Error sending task {self.program}.{self.task} to Worker",
|
267
|
+
provider=SCHEDULER_DEFAULT_NOTIFY,
|
268
|
+
)
|
269
|
+
except KeyboardInterrupt:
|
270
|
+
self._scheduled = True
|
271
|
+
except OSError as exc:
|
272
|
+
self.logger.error(
|
273
|
+
f"Connection Error: {exc}"
|
274
|
+
)
|
275
|
+
send_notification(
|
276
|
+
loop,
|
277
|
+
message=f"Scheduler: Task {self.program}.{self.task} Connection Refused: {exc!s}",
|
278
|
+
provider=SCHEDULER_DEFAULT_NOTIFY,
|
279
|
+
)
|
280
|
+
raise
|
281
|
+
except Exception as exc:
|
282
|
+
self.logger.exception(
|
283
|
+
f"Scheduler Queue Error: {exc}",
|
284
|
+
stack_info=True
|
285
|
+
)
|
286
|
+
send_notification(
|
287
|
+
loop,
|
288
|
+
message=f"Scheduler: Exception on Enqueue {self.program}.{self.task}: {exc!s}",
|
289
|
+
provider=SCHEDULER_DEFAULT_NOTIFY,
|
290
|
+
)
|
291
|
+
raise
|
292
|
+
finally:
|
293
|
+
try:
|
294
|
+
loop.close()
|
295
|
+
except Exception:
|
296
|
+
pass
|
297
|
+
|
298
|
+
|
299
|
+
async def launch_task(program, task_id, loop, ENV, *args, **kwargs):
|
300
|
+
task = Task(
|
301
|
+
task=task_id,
|
302
|
+
program=program,
|
303
|
+
loop=loop,
|
304
|
+
ignore_results=True,
|
305
|
+
ENV=ENV,
|
306
|
+
debug=DEBUG,
|
307
|
+
**kwargs,
|
308
|
+
)
|
309
|
+
try:
|
310
|
+
await task.start()
|
311
|
+
except Exception as err:
|
312
|
+
logging.error(f"Failing Task Start: {program}.{task_id} with error: {err}")
|
313
|
+
raise TaskFailed(f"{err!s}") from err
|
314
|
+
try:
|
315
|
+
result = await task.run()
|
316
|
+
return result
|
317
|
+
except (NotSupported, FileNotFound, NoDataFound, DataNotFound):
|
318
|
+
raise
|
319
|
+
except TaskNotFound as err:
|
320
|
+
raise TaskNotFound(f"Task: {task_id}: {err!s}") from err
|
321
|
+
except TaskFailed as err:
|
322
|
+
raise TaskFailed(f"Task {task_id} failed: {err}") from err
|
323
|
+
except FileError as err:
|
324
|
+
raise FileError(f"Task {task_id}, File Not Found: {err}") from err
|
325
|
+
except Exception as err:
|
326
|
+
raise TaskFailed(f"Error: Task {task_id} failed: {err}") from err
|
327
|
+
finally:
|
328
|
+
try:
|
329
|
+
await task.close()
|
330
|
+
except Exception as err:
|
331
|
+
logging.error(err)
|
332
|
+
|
333
|
+
|
334
|
+
def thread_wrapper(program, task_id, loop, *args, **kwargs):
|
335
|
+
logging.info(
|
336
|
+
f"Calling Task: {program}.{task_id} on ThreadPool Executor."
|
337
|
+
)
|
338
|
+
|
339
|
+
def run_task(loop: asyncio.AbstractEventLoop):
|
340
|
+
asyncio.set_event_loop(loop)
|
341
|
+
result = None
|
342
|
+
task = Task(
|
343
|
+
program=program, task=task_id, ignore_results=True, loop=loop, debug=DEBUG
|
344
|
+
)
|
345
|
+
try:
|
346
|
+
loop.run_until_complete(task.start())
|
347
|
+
result = loop.run_until_complete(task.run())
|
348
|
+
return result
|
349
|
+
except (NotSupported, FileNotFound, NoDataFound):
|
350
|
+
raise
|
351
|
+
except TaskNotFound as err:
|
352
|
+
raise TaskNotFound(
|
353
|
+
f"Task: {task_id}: {err!s}"
|
354
|
+
) from err
|
355
|
+
except TaskFailed as err:
|
356
|
+
raise TaskFailed(
|
357
|
+
f"Task {task_id} failed: {err}"
|
358
|
+
) from err
|
359
|
+
except FileError as err:
|
360
|
+
raise FileError(
|
361
|
+
f"Task {task_id}, File Not Found: {err}"
|
362
|
+
) from err
|
363
|
+
except Exception as err:
|
364
|
+
logging.error(
|
365
|
+
f"Error running Task: {program}.{task_id} from Process: {err!s}"
|
366
|
+
)
|
367
|
+
raise TaskFailed(f"{err!s}") from err
|
368
|
+
finally:
|
369
|
+
loop.run_until_complete(task.close())
|
370
|
+
|
371
|
+
try:
|
372
|
+
loop = asyncio.new_event_loop()
|
373
|
+
with ThreadPoolExecutor(max_workers=10) as pool:
|
374
|
+
result = loop.run_in_executor(pool, run_task)
|
375
|
+
return result
|
376
|
+
except (NotSupported, FileNotFound, FileError, NoDataFound, DataNotFound):
|
377
|
+
raise
|
378
|
+
except TaskFailed:
|
379
|
+
raise
|
380
|
+
except Exception as err:
|
381
|
+
raise TaskFailed(
|
382
|
+
f"Error: Task {program}.{task_id} failed: {err}"
|
383
|
+
) from err
|
384
|
+
# finally:
|
385
|
+
# loop.stop()
|
386
|
+
|
387
|
+
|
388
|
+
def process_wrapper(program, task_id, *args, **kwargs):
|
389
|
+
logging.info(
|
390
|
+
f"Calling Task: {program}.{task_id} on ProcessPool Executor."
|
391
|
+
)
|
392
|
+
loop = asyncio.new_event_loop()
|
393
|
+
asyncio.set_event_loop(loop)
|
394
|
+
|
395
|
+
def run_task():
|
396
|
+
result = None
|
397
|
+
task = Task(
|
398
|
+
program=program,
|
399
|
+
task=task_id,
|
400
|
+
ignore_results=True,
|
401
|
+
loop=loop,
|
402
|
+
debug=DEBUG
|
403
|
+
)
|
404
|
+
try:
|
405
|
+
loop.run_until_complete(task.start())
|
406
|
+
result = loop.run_until_complete(task.run())
|
407
|
+
return result
|
408
|
+
except (NotSupported, FileNotFound, NoDataFound):
|
409
|
+
raise
|
410
|
+
except TaskNotFound as err:
|
411
|
+
raise TaskNotFound(f"Task: {task_id}: {err!s}") from err
|
412
|
+
except TaskFailed as err:
|
413
|
+
raise TaskFailed(f"Task {task_id} failed: {err}") from err
|
414
|
+
except FileError as err:
|
415
|
+
raise FileError(f"Task {task_id}, File Not Found: {err}") from err
|
416
|
+
except Exception as err:
|
417
|
+
logging.error(
|
418
|
+
f"Error running Task: {program}.{task_id} from Process: {err!s}"
|
419
|
+
)
|
420
|
+
raise TaskFailed(f"{err!s}") from err
|
421
|
+
finally:
|
422
|
+
loop.run_until_complete(task.close())
|
423
|
+
|
424
|
+
try:
|
425
|
+
return run_task() # This function will be called in the child process
|
426
|
+
finally:
|
427
|
+
loop.close()
|
428
|
+
|
429
|
+
|
430
|
+
def get_function(job: dict, priority: str = "low", worker: Callable = None):
|
431
|
+
fn = job["job"]
|
432
|
+
if not fn:
|
433
|
+
raise ValueError(
|
434
|
+
f"Job with bad syntax: {job!r}"
|
435
|
+
)
|
436
|
+
try:
|
437
|
+
job_id = job["job_id"]
|
438
|
+
except KeyError:
|
439
|
+
raise RuntimeError(
|
440
|
+
f"Job with bad syntax: {job!r}"
|
441
|
+
)
|
442
|
+
# default is a task function
|
443
|
+
t = fn.get('type', 'task')
|
444
|
+
params = job.get('params', {})
|
445
|
+
if not params:
|
446
|
+
params = {}
|
447
|
+
try:
|
448
|
+
func = fn[t]
|
449
|
+
except KeyError as ex:
|
450
|
+
raise RuntimeError(
|
451
|
+
f"Error getting Function on Schedule {t}: {ex}"
|
452
|
+
) from ex
|
453
|
+
if t == "function":
|
454
|
+
try:
|
455
|
+
fn = globals()[func]
|
456
|
+
return fn
|
457
|
+
except Exception as err:
|
458
|
+
raise RuntimeError(f"Error: {err!s}") from err
|
459
|
+
elif t == "package":
|
460
|
+
try:
|
461
|
+
fn = import_from_path(func)
|
462
|
+
return fn
|
463
|
+
except Exception as err:
|
464
|
+
raise RuntimeError(f"Error: {err!s}") from err
|
465
|
+
elif t == "task":
|
466
|
+
task, program = fn["task"].values()
|
467
|
+
if priority == "local":
|
468
|
+
# run in a function wrapper
|
469
|
+
func = partial(launch_task, program, task)
|
470
|
+
return func
|
471
|
+
else:
|
472
|
+
executor = job["executor"]
|
473
|
+
if executor == "default":
|
474
|
+
# Using asyncio Executor
|
475
|
+
sched = TaskScheduler(
|
476
|
+
program,
|
477
|
+
task,
|
478
|
+
job_id,
|
479
|
+
priority,
|
480
|
+
worker,
|
481
|
+
**params
|
482
|
+
)
|
483
|
+
sched.__class__.__name__ = f"Task({program}.{task})"
|
484
|
+
return sched
|
485
|
+
elif executor == "process":
|
486
|
+
return process_wrapper
|
487
|
+
elif executor == "thread":
|
488
|
+
func = partial(thread_wrapper, program, task, **params)
|
489
|
+
return func
|
490
|
+
else:
|
491
|
+
raise RuntimeError(f"Error: Executor {executor!r} not supported")
|
492
|
+
else:
|
493
|
+
return None
|