flowtask 5.8.4__cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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-310-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-310-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/argparser.py +235 -0
- flowtask/parsers/base.c +15155 -0
- flowtask/parsers/base.cpython-310-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/json.c +11968 -0
- flowtask/parsers/json.cpython-310-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/maps.py +49 -0
- flowtask/parsers/toml.c +11968 -0
- flowtask/parsers/toml.cpython-310-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-310-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-310-x86_64-linux-gnu.so +0 -0
- flowtask/utils/json.cpp +13349 -0
- flowtask/utils/json.cpython-310-x86_64-linux-gnu.so +0 -0
- flowtask/utils/mail.py +63 -0
- flowtask/utils/parseqs.c +13324 -0
- flowtask/utils/parserqs.cpython-310-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,182 @@
|
|
1
|
+
import asyncio
|
2
|
+
import logging
|
3
|
+
from collections.abc import Callable
|
4
|
+
import traceback
|
5
|
+
import pprint
|
6
|
+
from asyncdb.exceptions import NoDataFound
|
7
|
+
from ..tasks.task import Task
|
8
|
+
from ..utils.functions import check_empty
|
9
|
+
from ..exceptions import (
|
10
|
+
DataNotFound,
|
11
|
+
NotSupported,
|
12
|
+
ComponentError,
|
13
|
+
TaskNotFound,
|
14
|
+
TaskDefinition,
|
15
|
+
TaskFailed,
|
16
|
+
FileNotFound,
|
17
|
+
)
|
18
|
+
from .flow import FlowComponent
|
19
|
+
|
20
|
+
|
21
|
+
class SubTask(FlowComponent):
|
22
|
+
"""
|
23
|
+
SubTask
|
24
|
+
|
25
|
+
Overview
|
26
|
+
|
27
|
+
The SubTask class is a component for executing a specified task as a sub-task within a workflow.
|
28
|
+
It allows passing configurations and parameters, including conditional steps, to dynamically manage
|
29
|
+
and execute the named task in the specified program.
|
30
|
+
|
31
|
+
.. table:: Properties
|
32
|
+
:widths: auto
|
33
|
+
|
34
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
35
|
+
| Name | Required | Summary |
|
36
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
37
|
+
| task | Yes | The name of the task to execute as a sub-task. |
|
38
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
39
|
+
| program | Yes | The name of the program under which the task is defined. |
|
40
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
41
|
+
| ignore_steps | No | List of steps to ignore during the sub-task execution. |
|
42
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
43
|
+
| run_only | No | List of specific steps to run, ignoring others. |
|
44
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
45
|
+
| conditions | No | Dictionary of conditions to apply to the sub-task execution. |
|
46
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
47
|
+
|
48
|
+
Returns
|
49
|
+
|
50
|
+
This component executes the specified task and returns the task’s output or state upon completion.
|
51
|
+
If the task encounters an error or lacks data, an appropriate exception is raised. The component tracks
|
52
|
+
task and program details in the metrics, and logs the state of the task if debugging is enabled.
|
53
|
+
|
54
|
+
|
55
|
+
Example:
|
56
|
+
|
57
|
+
```yaml
|
58
|
+
SubTask:
|
59
|
+
task: forms
|
60
|
+
program: banco_chile
|
61
|
+
```
|
62
|
+
|
63
|
+
"""
|
64
|
+
|
65
|
+
def __init__(
|
66
|
+
self,
|
67
|
+
loop: asyncio.AbstractEventLoop = None,
|
68
|
+
job: Callable = None,
|
69
|
+
stat: Callable = None,
|
70
|
+
**kwargs,
|
71
|
+
):
|
72
|
+
"""Init Method."""
|
73
|
+
self._params = {}
|
74
|
+
self.task: str = ""
|
75
|
+
self._task = None
|
76
|
+
self.program: str = ""
|
77
|
+
self.conditions = {}
|
78
|
+
self._arguments = {}
|
79
|
+
self.ignore_steps: list = []
|
80
|
+
self.run_only: list = []
|
81
|
+
super(SubTask, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
|
82
|
+
self.program = self._program
|
83
|
+
|
84
|
+
async def start(self, **kwargs):
|
85
|
+
program = self.program
|
86
|
+
self._program = program
|
87
|
+
try:
|
88
|
+
del self._params["program"]
|
89
|
+
except KeyError:
|
90
|
+
pass
|
91
|
+
try:
|
92
|
+
# task = self.task
|
93
|
+
del self._params["task"]
|
94
|
+
except KeyError:
|
95
|
+
pass
|
96
|
+
# remove the SkipError (avoid passed to SubTask.)
|
97
|
+
try:
|
98
|
+
del self._params["skipError"]
|
99
|
+
except KeyError:
|
100
|
+
pass
|
101
|
+
# passing variables to SubTask
|
102
|
+
params = {
|
103
|
+
"vars": self._vars,
|
104
|
+
"variables": self._variables,
|
105
|
+
"ignore_steps": self.ignore_steps,
|
106
|
+
"run_only": self.run_only,
|
107
|
+
"memory": self._memory,
|
108
|
+
"attributes": self._attributes,
|
109
|
+
"arguments": self._arguments,
|
110
|
+
"is_subtask": True,
|
111
|
+
"conditions": self.conditions,
|
112
|
+
"params": self._params,
|
113
|
+
}
|
114
|
+
if self._debug is True:
|
115
|
+
pp = pprint.PrettyPrinter(indent=4)
|
116
|
+
print(" Subtask Properties ==================")
|
117
|
+
pp.pprint(params)
|
118
|
+
print(" ==================")
|
119
|
+
if "debug" in self._params:
|
120
|
+
del self._params["debug"]
|
121
|
+
# definition of task
|
122
|
+
try:
|
123
|
+
self._task = Task(
|
124
|
+
task=self.task,
|
125
|
+
program=self.program,
|
126
|
+
loop=self._loop,
|
127
|
+
debug=self._debug,
|
128
|
+
stat=self.stat.parent(),
|
129
|
+
**params,
|
130
|
+
)
|
131
|
+
self.add_metric(
|
132
|
+
"TASK", f"{self.program}.{self.task}"
|
133
|
+
)
|
134
|
+
try:
|
135
|
+
if self._task:
|
136
|
+
prepare = await self._task.start()
|
137
|
+
if prepare:
|
138
|
+
return True
|
139
|
+
else:
|
140
|
+
return False
|
141
|
+
except (TaskDefinition, TaskFailed) as err:
|
142
|
+
logging.exception(err, stack_info=True)
|
143
|
+
except TaskNotFound as err:
|
144
|
+
logging.exception(err, stack_info=True)
|
145
|
+
except Exception as err:
|
146
|
+
traceback.print_exc()
|
147
|
+
print(err, err.__class__)
|
148
|
+
logging.exception(err, stack_info=True)
|
149
|
+
|
150
|
+
async def close(self):
|
151
|
+
if self._task:
|
152
|
+
try:
|
153
|
+
await self._task.close()
|
154
|
+
except Exception as err:
|
155
|
+
raise TaskFailed(
|
156
|
+
f"Error closing Task {self.task!s}, error: {err}"
|
157
|
+
) from err
|
158
|
+
|
159
|
+
async def run(self):
|
160
|
+
result = False
|
161
|
+
if not self._task:
|
162
|
+
return False
|
163
|
+
try:
|
164
|
+
result = await self._task.run()
|
165
|
+
except (DataNotFound, NoDataFound, FileNotFound):
|
166
|
+
raise
|
167
|
+
except NotSupported as err:
|
168
|
+
raise NotSupported(
|
169
|
+
f"Error running Task {self.task}, error: {err}"
|
170
|
+
) from err
|
171
|
+
except ComponentError:
|
172
|
+
raise
|
173
|
+
except Exception as err:
|
174
|
+
print("TYPE ", err, type(err))
|
175
|
+
raise ComponentError(
|
176
|
+
f"Error on Task {self.task}: {err}"
|
177
|
+
) from err
|
178
|
+
if check_empty(result):
|
179
|
+
return False
|
180
|
+
else:
|
181
|
+
self._result = self
|
182
|
+
return result
|
@@ -0,0 +1,48 @@
|
|
1
|
+
from typing import Dict
|
2
|
+
from navconfig.logging import logging
|
3
|
+
from querysource.exceptions import DataNotFound as QSNotFound
|
4
|
+
from ..exceptions import ComponentError, DataNotFound
|
5
|
+
from .QSBase import QSBase
|
6
|
+
|
7
|
+
|
8
|
+
class SuiteCRM(QSBase):
|
9
|
+
"""SuiteCRM
|
10
|
+
|
11
|
+
Overview
|
12
|
+
|
13
|
+
This component captures the data from the SuiteCRM API to be
|
14
|
+
processed and stored in Navigator.
|
15
|
+
|
16
|
+
.. table:: Properties
|
17
|
+
:widths: auto
|
18
|
+
|
19
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
20
|
+
| Name | Required | Summary |
|
21
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
22
|
+
| type | Yes | Type of query |
|
23
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
24
|
+
| username | Yes | Credential Username |
|
25
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
26
|
+
| password | Yes | Credential Password |
|
27
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
28
|
+
| main_url | Yes | URL Base of the API |
|
29
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
30
|
+
| module_name | Yes | Module to list |
|
31
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
32
|
+
|
33
|
+
Return the entry list of module
|
34
|
+
|
35
|
+
"""
|
36
|
+
|
37
|
+
type = "entry_list"
|
38
|
+
_driver = "suitecrm"
|
39
|
+
|
40
|
+
async def entry_list(self):
|
41
|
+
try:
|
42
|
+
resultset = await self._qs.entry_list()
|
43
|
+
return resultset
|
44
|
+
except QSNotFound as err:
|
45
|
+
raise DataNotFound(f"CourseMerchant Not Found: {err}") from err
|
46
|
+
except Exception as err:
|
47
|
+
logging.exception(err)
|
48
|
+
raise ComponentError(f"CourseMerchant ERROR: {err!s}") from err
|
@@ -0,0 +1,175 @@
|
|
1
|
+
from collections.abc import Callable
|
2
|
+
from jsonpath_ng import parse
|
3
|
+
import asyncio
|
4
|
+
import pandas as pd
|
5
|
+
from ..exceptions import (
|
6
|
+
ComponentError,
|
7
|
+
)
|
8
|
+
from .BaseLoop import BaseLoop
|
9
|
+
|
10
|
+
|
11
|
+
class Switch(BaseLoop):
|
12
|
+
"""
|
13
|
+
Switch Component
|
14
|
+
|
15
|
+
Routes execution to a specific component based on user-defined conditions.
|
16
|
+
|
17
|
+
cases: Defines a list of conditions and their corresponding components.
|
18
|
+
Each condition is a Python-style logical expression evaluated against self.data.
|
19
|
+
default: Specifies the fallback component if none of the conditions match.
|
20
|
+
|
21
|
+
"""
|
22
|
+
def __init__(
|
23
|
+
self,
|
24
|
+
loop: asyncio.AbstractEventLoop = None,
|
25
|
+
job: Callable = None,
|
26
|
+
stat: Callable = None,
|
27
|
+
**kwargs,
|
28
|
+
):
|
29
|
+
self._cases = kwargs.get("cases", [])
|
30
|
+
super(Switch, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
|
31
|
+
|
32
|
+
async def start(self, **kwargs):
|
33
|
+
"""
|
34
|
+
start.
|
35
|
+
|
36
|
+
Initialize (if needed) a task
|
37
|
+
"""
|
38
|
+
await super(Switch, self).start(**kwargs)
|
39
|
+
# Add all case components to the tracker
|
40
|
+
self._define_tracking_components(*self._cases)
|
41
|
+
return True
|
42
|
+
|
43
|
+
def _evaluate_condition(self, condition: str) -> bool:
|
44
|
+
"""
|
45
|
+
Evaluate a condition based on the type of self.data.
|
46
|
+
|
47
|
+
Args:
|
48
|
+
condition (str): A condition in the format "<jsonpath> <operator> <value>".
|
49
|
+
|
50
|
+
Returns:
|
51
|
+
bool: True if the condition is satisfied, else False.
|
52
|
+
"""
|
53
|
+
if isinstance(self.data, dict):
|
54
|
+
# Parse the condition: split JSONPath and comparison
|
55
|
+
try:
|
56
|
+
# Split the condition into JSONPath and comparison
|
57
|
+
jsonpath_expr, operator, expected_value = self._parse_condition(condition)
|
58
|
+
|
59
|
+
# Evaluate the JSONPath
|
60
|
+
jsonpath = parse(jsonpath_expr)
|
61
|
+
matches = jsonpath.find(self.data)
|
62
|
+
|
63
|
+
# Get the first match (if any)
|
64
|
+
actual_value = matches[0].value if matches else None
|
65
|
+
|
66
|
+
# Evaluate the operator
|
67
|
+
return self._evaluate_operator(actual_value, operator, expected_value)
|
68
|
+
|
69
|
+
except Exception as err:
|
70
|
+
raise ComponentError(f"Error evaluating condition '{condition}': {err}")
|
71
|
+
|
72
|
+
elif isinstance(self.data, pd.DataFrame):
|
73
|
+
# For DataFrame, condition should be a valid query string
|
74
|
+
try:
|
75
|
+
filtered = self.data.query(condition)
|
76
|
+
return not filtered.empty
|
77
|
+
except Exception as err:
|
78
|
+
raise ComponentError(
|
79
|
+
f"Error evaluating DataFrame condition '{condition}': {err}"
|
80
|
+
) from err
|
81
|
+
|
82
|
+
elif isinstance(self.data, str):
|
83
|
+
# For string data, check if condition is a substring
|
84
|
+
return condition in self.data
|
85
|
+
|
86
|
+
else:
|
87
|
+
raise ComponentError(
|
88
|
+
f"Unsupported data type for condition evaluation: {type(self.data)}"
|
89
|
+
)
|
90
|
+
|
91
|
+
def _parse_condition(self, condition: str):
|
92
|
+
"""
|
93
|
+
Parse the condition into JSONPath, operator, and expected value.
|
94
|
+
|
95
|
+
Args:
|
96
|
+
condition (str): A condition string, e.g., "$.metadata.type == 'recapDefinition'".
|
97
|
+
|
98
|
+
Returns:
|
99
|
+
tuple: (jsonpath_expr, operator, expected_value)
|
100
|
+
"""
|
101
|
+
operators = ["==", "!=", ">", "<", ">=", "<="]
|
102
|
+
for op in operators:
|
103
|
+
if op in condition:
|
104
|
+
parts = condition.split(op)
|
105
|
+
if len(parts) != 2:
|
106
|
+
raise ValueError(f"Invalid condition format: {condition}")
|
107
|
+
jsonpath_expr, expected_value = parts
|
108
|
+
expected_value = expected_value.strip().strip("'\"") # Remove quotes
|
109
|
+
return jsonpath_expr.strip(), op, expected_value
|
110
|
+
raise ValueError(f"No valid operator found in condition: {condition}")
|
111
|
+
|
112
|
+
def _evaluate_operator(self, actual_value, operator, expected_value):
|
113
|
+
"""
|
114
|
+
Evaluate the comparison operator.
|
115
|
+
|
116
|
+
Args:
|
117
|
+
actual_value: The value extracted from JSONPath.
|
118
|
+
operator: The comparison operator as a string.
|
119
|
+
expected_value: The value to compare against.
|
120
|
+
|
121
|
+
Returns:
|
122
|
+
bool: True if the comparison is satisfied, else False.
|
123
|
+
"""
|
124
|
+
if operator == "==":
|
125
|
+
return actual_value == expected_value
|
126
|
+
elif operator == "!=":
|
127
|
+
return actual_value != expected_value
|
128
|
+
elif operator == ">":
|
129
|
+
return actual_value > expected_value
|
130
|
+
elif operator == "<":
|
131
|
+
return actual_value < expected_value
|
132
|
+
elif operator == ">=":
|
133
|
+
return actual_value >= expected_value
|
134
|
+
elif operator == "<=":
|
135
|
+
return actual_value <= expected_value
|
136
|
+
else:
|
137
|
+
raise ValueError(f"Unsupported operator: {operator}")
|
138
|
+
|
139
|
+
async def run(self):
|
140
|
+
"""
|
141
|
+
Executes the appropriate component based on the conditions.
|
142
|
+
"""
|
143
|
+
# Determine the component to execute
|
144
|
+
selected_component = None
|
145
|
+
for case in self._cases:
|
146
|
+
if self._evaluate_condition(case["condition"]):
|
147
|
+
selected_component = case["component"]
|
148
|
+
break
|
149
|
+
|
150
|
+
if not selected_component:
|
151
|
+
# Use the default component if no case matches
|
152
|
+
if not self._default:
|
153
|
+
raise ComponentError(
|
154
|
+
"No matching case and no default component provided."
|
155
|
+
)
|
156
|
+
selected_component = self._default
|
157
|
+
|
158
|
+
# Execute the selected component
|
159
|
+
step, idx = self._TaskPile.getStepByName(selected_component)
|
160
|
+
if step is None:
|
161
|
+
raise ComponentError(
|
162
|
+
f"Component '{selected_component}' not found in Task Definition."
|
163
|
+
)
|
164
|
+
target, params, stat = self.get_component(step)
|
165
|
+
component_instance = self.create_component(
|
166
|
+
target,
|
167
|
+
value=self.data,
|
168
|
+
stat=stat,
|
169
|
+
**params
|
170
|
+
)
|
171
|
+
self._result = await self.exec_component(component_instance, step.name)
|
172
|
+
# at the end, remove all tracked components from TaskPile to prevent future execution
|
173
|
+
for component_name in self._tracked_components:
|
174
|
+
self._TaskPile.delStepByName(component_name)
|
175
|
+
return self._result
|
@@ -0,0 +1,148 @@
|
|
1
|
+
import asyncio
|
2
|
+
from collections.abc import Callable
|
3
|
+
from pathlib import PurePath
|
4
|
+
import aiofiles
|
5
|
+
from sqlalchemy.orm import Session
|
6
|
+
from sqlalchemy import create_engine, text
|
7
|
+
from sqlalchemy.pool import NullPool
|
8
|
+
from querysource.conf import sqlalchemy_url
|
9
|
+
from ..conf import TASK_PATH
|
10
|
+
from ..exceptions import FileNotFound, FileError
|
11
|
+
from ..parsers.maps import open_map, open_model
|
12
|
+
from .flow import FlowComponent
|
13
|
+
from ..interfaces import TemplateSupport
|
14
|
+
|
15
|
+
|
16
|
+
class TableBase(FlowComponent, TemplateSupport):
|
17
|
+
"""
|
18
|
+
TableBase.
|
19
|
+
|
20
|
+
Abstract class for Using Pandas SQL features to manipulate data from databases.
|
21
|
+
"""
|
22
|
+
|
23
|
+
flavor: str = "postgres"
|
24
|
+
|
25
|
+
def __init__(
|
26
|
+
self,
|
27
|
+
loop: asyncio.AbstractEventLoop = None,
|
28
|
+
job: Callable = None,
|
29
|
+
stat: Callable = None,
|
30
|
+
**kwargs,
|
31
|
+
):
|
32
|
+
self._engine: Callable = None
|
33
|
+
self.params: dict = {}
|
34
|
+
self.use_template: bool = bool(kwargs.get('use_template', False))
|
35
|
+
super(TableBase, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
|
36
|
+
|
37
|
+
async def get_connection(self, dsn: str = None):
|
38
|
+
if not dsn:
|
39
|
+
dsn = sqlalchemy_url
|
40
|
+
self._engine = create_engine(dsn, echo=False, poolclass=NullPool)
|
41
|
+
self._session = Session(self._engine)
|
42
|
+
|
43
|
+
async def close(self):
|
44
|
+
"""Closing Operations."""
|
45
|
+
if self._engine:
|
46
|
+
try:
|
47
|
+
self._engine.dispose()
|
48
|
+
except Exception as err: # pylint: disable=W0703
|
49
|
+
print(err)
|
50
|
+
|
51
|
+
async def open_sqlfile(self, file: PurePath, **kwargs) -> str:
|
52
|
+
if file.exists() and file.is_file():
|
53
|
+
content = None
|
54
|
+
# open SQL File:
|
55
|
+
async with aiofiles.open(file, "r+") as afp:
|
56
|
+
content = await afp.read()
|
57
|
+
# check if we need to replace masks
|
58
|
+
content = self.mask_replacement(content)
|
59
|
+
if self.use_template is True:
|
60
|
+
content = self._templateparser.from_string(content, kwargs)
|
61
|
+
return content
|
62
|
+
else:
|
63
|
+
raise FileError(f"Table: Missing SQL File: {file}")
|
64
|
+
|
65
|
+
def column_info(self, tablename):
|
66
|
+
if self.flavor == "postgres":
|
67
|
+
discover = f"""SELECT attname AS column_name, atttypid::regtype AS data_type, attnotnull::boolean as notnull
|
68
|
+
FROM pg_attribute WHERE attrelid = '{tablename}'::regclass AND attnum > 0
|
69
|
+
AND NOT attisdropped ORDER BY attnum;
|
70
|
+
"""
|
71
|
+
else:
|
72
|
+
raise ValueError(
|
73
|
+
f"Column Info: DB Flavor not supported yet: {self.flavor}"
|
74
|
+
)
|
75
|
+
discover = text(discover)
|
76
|
+
result = self._session.execute(discover)
|
77
|
+
if result:
|
78
|
+
# rows = result.fetchall()
|
79
|
+
rows = result.mappings()
|
80
|
+
# return {item['column_name']: item['data_type'] for item in rows}
|
81
|
+
return {row["column_name"]: row["data_type"] for row in rows}
|
82
|
+
else:
|
83
|
+
model = open_model(self.tablename, self.program)
|
84
|
+
if model:
|
85
|
+
fields = model["fields"]
|
86
|
+
return {field: fields[field]["data_type"] for field in fields}
|
87
|
+
else:
|
88
|
+
print(f"Table: table or Model {tablename} does not exists")
|
89
|
+
return None
|
90
|
+
|
91
|
+
async def start(self, **kwargs):
|
92
|
+
if self.previous:
|
93
|
+
self.data = self.input
|
94
|
+
await self.get_connection()
|
95
|
+
if hasattr(self, "tablename"):
|
96
|
+
# Using a Table:
|
97
|
+
if not hasattr(self, "schema"):
|
98
|
+
self.schema = self._program
|
99
|
+
# check for Table structure
|
100
|
+
try:
|
101
|
+
tablename = self.tablename
|
102
|
+
schema = self.schema
|
103
|
+
if self.flavor == "postgres":
|
104
|
+
tablename = f"{schema}.{tablename}"
|
105
|
+
colinfo = self.column_info(tablename)
|
106
|
+
except KeyError:
|
107
|
+
if hasattr(self, "map"):
|
108
|
+
mapping = self.map["map"]
|
109
|
+
colinfo = open_map(mapping, self.program)
|
110
|
+
if not colinfo:
|
111
|
+
colinfo = open_map(tablename, self.program)
|
112
|
+
if colinfo:
|
113
|
+
try:
|
114
|
+
ignore = self.map["ignore"]
|
115
|
+
colinfo = {k: v for k, v in colinfo.items() if k not in ignore}
|
116
|
+
except (KeyError, AttributeError):
|
117
|
+
pass
|
118
|
+
self.params["columns"] = colinfo.keys()
|
119
|
+
parse_dates = []
|
120
|
+
for column, dtype in colinfo.items():
|
121
|
+
if (
|
122
|
+
dtype == "timestamp without time zone"
|
123
|
+
or dtype == "timestamp with time zone"
|
124
|
+
or dtype == "date"
|
125
|
+
):
|
126
|
+
parse_dates.append(column)
|
127
|
+
if parse_dates:
|
128
|
+
self.params["parse_dates"] = parse_dates
|
129
|
+
elif hasattr(self, "file_sql"):
|
130
|
+
file_path = TASK_PATH.joinpath(self.program, "sql", self.file_sql)
|
131
|
+
if not file_path.exists():
|
132
|
+
raise FileNotFound(f"Table: SQL File {file_path} was not found.")
|
133
|
+
self.query = await self.open_sqlfile(file_path)
|
134
|
+
elif hasattr(self, "query"):
|
135
|
+
## passing query for mask conversion:
|
136
|
+
if hasattr(self, "masks"):
|
137
|
+
self.query = self.mask_replacement(self.query)
|
138
|
+
for val in self._variables:
|
139
|
+
if isinstance(self._variables[val], list):
|
140
|
+
if isinstance(self._variables[val], int):
|
141
|
+
self._variables[val] = ", ".join(self._variables[val])
|
142
|
+
else:
|
143
|
+
self._variables[val] = ", ".join(
|
144
|
+
"'{}'".format(v) for v in self._variables[val]
|
145
|
+
)
|
146
|
+
self.query = self.query.replace(
|
147
|
+
"{{{}}}".format(str(val)), str(self._variables[val])
|
148
|
+
)
|