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.
- 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-39-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-39-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/argparser.py +235 -0
- flowtask/parsers/base.c +15155 -0
- flowtask/parsers/base.cpython-39-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/json.c +11968 -0
- flowtask/parsers/json.cpython-39-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/maps.py +49 -0
- flowtask/parsers/toml.c +11968 -0
- flowtask/parsers/toml.cpython-39-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-39-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-39-x86_64-linux-gnu.so +0 -0
- flowtask/utils/json.cpp +13349 -0
- flowtask/utils/json.cpython-39-x86_64-linux-gnu.so +0 -0
- flowtask/utils/mail.py +63 -0
- flowtask/utils/parseqs.c +13324 -0
- flowtask/utils/parserqs.cpython-39-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,175 @@
|
|
1
|
+
import asyncio
|
2
|
+
import pandas as pd
|
3
|
+
from urllib.parse import urljoin
|
4
|
+
from xmlrpc.client import ServerProxy
|
5
|
+
from .flow import FlowComponent
|
6
|
+
from ..interfaces.http import HTTPService
|
7
|
+
from ..exceptions import ComponentError
|
8
|
+
|
9
|
+
|
10
|
+
class Odoo(HTTPService, FlowComponent):
|
11
|
+
"""
|
12
|
+
Odoo
|
13
|
+
|
14
|
+
Overview
|
15
|
+
|
16
|
+
This component interacts with an Odoo server to perform various operations like `search_read` and `create`.
|
17
|
+
|
18
|
+
.. table:: Properties
|
19
|
+
:widths: auto
|
20
|
+
|
21
|
+
|
22
|
+
+------------------------------+----------+-----------+---------------------------------------------------------+
|
23
|
+
| Name | Required | Summary |
|
24
|
+
+------------------------------+----------+-----------+---------------------------------------------------------+
|
25
|
+
| credentials | Yes | A dictionary containing connection details to the Odoo server: |
|
26
|
+
| | | "HOST", "PORT", "DB", "USERNAME", "PASSWORD". |
|
27
|
+
+------------------------------+----------+-----------+---------------------------------------------------------+
|
28
|
+
| method | Yes | The Odoo method to be called (e.g., "search_read", "create"). |
|
29
|
+
+------------------------------+----------+-----------+---------------------------------------------------------+
|
30
|
+
| model | Yes | The Odoo model to be used for the method call (e.g., "res.partner").|
|
31
|
+
+------------------------------+----------+-----------+---------------------------------------------------------+
|
32
|
+
| domain | No | Domain filter for searching records, applicable for "search_read". |
|
33
|
+
+------------------------------+----------+-----------+---------------------------------------------------------+
|
34
|
+
| fields | No | Fields to be retrieved, applicable for "search_read". |
|
35
|
+
+------------------------------+----------+-----------+---------------------------------------------------------+
|
36
|
+
| values | No | Values to be used for creating records, applicable for "create". |
|
37
|
+
+------------------------------+----------+-----------+---------------------------------------------------------+
|
38
|
+
| use_field_from_previous_step | No | Field from previous step to filter records in "search_read". |
|
39
|
+
+------------------------------+----------+-----------+---------------------------------------------------------+
|
40
|
+
|
41
|
+
Returns
|
42
|
+
|
43
|
+
This component returns a pandas DataFrame containing the results of the Odoo operation.
|
44
|
+
|
45
|
+
|
46
|
+
Example:
|
47
|
+
|
48
|
+
```yaml
|
49
|
+
Odoo:
|
50
|
+
credentials:
|
51
|
+
HOST: ODOO_HOST
|
52
|
+
PORT: ODOO_PORT
|
53
|
+
DB: ODOO_DB
|
54
|
+
USERNAME: ODOO_USERNAME
|
55
|
+
PASSWORD: ODOO_PASSWORD
|
56
|
+
model: stock.warehouse
|
57
|
+
method: search_read
|
58
|
+
domain:
|
59
|
+
- - - company_id.name
|
60
|
+
- '='
|
61
|
+
- Pokemon
|
62
|
+
fields:
|
63
|
+
- id
|
64
|
+
```
|
65
|
+
|
66
|
+
""" # noqa
|
67
|
+
_credentials: dict = {
|
68
|
+
"HOST": str,
|
69
|
+
"PORT": int,
|
70
|
+
"DB": str,
|
71
|
+
"USERNAME": str,
|
72
|
+
"PASSWORD": str,
|
73
|
+
}
|
74
|
+
|
75
|
+
async def start(self, **kwargs):
|
76
|
+
if self.previous:
|
77
|
+
self.data = self.input
|
78
|
+
|
79
|
+
self.processing_credentials()
|
80
|
+
|
81
|
+
self.common = self.get_server_proxy("common")
|
82
|
+
self.uid = self.common.authenticate(
|
83
|
+
self.credentials["DB"],
|
84
|
+
self.credentials["USERNAME"],
|
85
|
+
self.credentials["PASSWORD"],
|
86
|
+
{},
|
87
|
+
)
|
88
|
+
|
89
|
+
self.models = self.get_server_proxy("object")
|
90
|
+
|
91
|
+
return True
|
92
|
+
|
93
|
+
async def run(self):
|
94
|
+
method_call = getattr(self, f"odoo_{self.method}")
|
95
|
+
|
96
|
+
if not method_call:
|
97
|
+
raise ComponentError("incorrect method or method not provided")
|
98
|
+
|
99
|
+
method_call_task = asyncio.to_thread(method_call)
|
100
|
+
|
101
|
+
method_call_result = await method_call_task
|
102
|
+
|
103
|
+
df = pd.DataFrame(method_call_result)
|
104
|
+
if df.empty:
|
105
|
+
self._logger.warning("Empty DataFrame")
|
106
|
+
|
107
|
+
self.add_metric("NUMROWS", len(df.index))
|
108
|
+
self.add_metric("NUMCOLS", len(df.columns))
|
109
|
+
|
110
|
+
self._result = df
|
111
|
+
|
112
|
+
if self._debug is True:
|
113
|
+
print("::: Printing Result Data === ")
|
114
|
+
print("Data: ", self._result)
|
115
|
+
for column, t in df.dtypes.items():
|
116
|
+
print(column, "->", t, "->", df[column].iloc[0])
|
117
|
+
|
118
|
+
return self._result
|
119
|
+
|
120
|
+
async def close(self):
|
121
|
+
return True
|
122
|
+
|
123
|
+
def get_server_proxy(self, endpoint):
|
124
|
+
port = (
|
125
|
+
f":{self.credentials['PORT']}" if self.credentials["PORT"] != 80 else ""
|
126
|
+
)
|
127
|
+
base_url = f"{self.credentials['HOST']}{port}/xmlrpc/2/"
|
128
|
+
url = urljoin(base_url, endpoint)
|
129
|
+
return ServerProxy(url)
|
130
|
+
|
131
|
+
def model_call(self, method, *args, **kwargs):
|
132
|
+
return self.models.execute_kw(
|
133
|
+
self.credentials["DB"],
|
134
|
+
self.uid,
|
135
|
+
self.credentials["PASSWORD"],
|
136
|
+
self.model,
|
137
|
+
method,
|
138
|
+
*args,
|
139
|
+
**kwargs,
|
140
|
+
)
|
141
|
+
|
142
|
+
def get_values_from_previous_data(self, field=None):
|
143
|
+
if isinstance(self.data, pd.DataFrame) and not self.data.empty:
|
144
|
+
if not field:
|
145
|
+
return [self.data.to_dict("records")]
|
146
|
+
|
147
|
+
return [[(field, "in", self.data[field].to_list())]] or [[]]
|
148
|
+
|
149
|
+
def odoo_search_read(self):
|
150
|
+
prev_step_field = getattr(self, "use_field_from_previous_step", None)
|
151
|
+
|
152
|
+
domain = getattr(
|
153
|
+
self,
|
154
|
+
"domain",
|
155
|
+
self.get_values_from_previous_data(prev_step_field),
|
156
|
+
)
|
157
|
+
fields = getattr(self, "fields", {})
|
158
|
+
|
159
|
+
self._logger.debug(f"Search Read with domain: {domain} and fields: {fields}")
|
160
|
+
return self.model_call(
|
161
|
+
"search_read", domain or [], fields and {"fields": fields}
|
162
|
+
)
|
163
|
+
|
164
|
+
def odoo_create(self):
|
165
|
+
try:
|
166
|
+
# values on step arguments have precedence
|
167
|
+
values = getattr(self, "values", self.get_values_from_previous_data())
|
168
|
+
assert values
|
169
|
+
|
170
|
+
return self.model_call("create", values)
|
171
|
+
|
172
|
+
except AssertionError:
|
173
|
+
raise ComponentError(
|
174
|
+
'"values" required for "create" method'
|
175
|
+
)
|
@@ -0,0 +1,192 @@
|
|
1
|
+
import asyncio
|
2
|
+
import math
|
3
|
+
from collections.abc import Callable
|
4
|
+
from urllib.parse import urljoin
|
5
|
+
import numpy as np
|
6
|
+
import pandas as pd
|
7
|
+
from .flow import FlowComponent
|
8
|
+
from ..interfaces.http import HTTPService
|
9
|
+
from ..exceptions import ComponentError, TaskError
|
10
|
+
|
11
|
+
|
12
|
+
class OdooInjector(HTTPService, FlowComponent):
|
13
|
+
"""
|
14
|
+
OdooInjector
|
15
|
+
|
16
|
+
Overview
|
17
|
+
|
18
|
+
The OdooInjector class is a component for injecting data into an Odoo server using a provided API key.
|
19
|
+
This component takes data from a Pandas DataFrame, formats it as payload, and sends it to an Odoo endpoint
|
20
|
+
specified in the credentials, facilitating seamless integration with Odoo’s API.
|
21
|
+
|
22
|
+
.. table:: Properties
|
23
|
+
:widths: auto
|
24
|
+
|
25
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
26
|
+
| Name | Required | Summary |
|
27
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
28
|
+
| credentials | Yes | A dictionary containing connection details for the Odoo server: |
|
29
|
+
| | | "HOST", "PORT", "APIKEY", and "INJECTOR_URL". |
|
30
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
31
|
+
| model | Yes | The Odoo model into which data will be injected. |
|
32
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
33
|
+
| headers | No | Optional headers to include with the API request. Defaults to API key. |
|
34
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
35
|
+
| data | Yes | The data to inject, formatted as a list of dictionaries from DataFrame. |
|
36
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
37
|
+
|
38
|
+
Returns
|
39
|
+
|
40
|
+
This component returns a Boolean indicating whether the data injection was successful.
|
41
|
+
In case of errors, detailed logging is provided, and an exception is raised with the error message.
|
42
|
+
Additionally, the component tracks successful API interactions and logs any unsuccessful payload deliveries
|
43
|
+
for debugging and tracking.
|
44
|
+
|
45
|
+
|
46
|
+
Example:
|
47
|
+
|
48
|
+
```yaml
|
49
|
+
OdooInjector:
|
50
|
+
credentials:
|
51
|
+
APIKEY: ODOO_APIKEY
|
52
|
+
HOST: ODOO_HOST
|
53
|
+
PORT: ODOO_PORT
|
54
|
+
INJECTOR_URL: ODOO_INJECTOR_URL
|
55
|
+
model: fsm.location
|
56
|
+
chunk_size: 10
|
57
|
+
```
|
58
|
+
|
59
|
+
""" #noqa
|
60
|
+
|
61
|
+
accept: str = "application/json"
|
62
|
+
auth_type: str = "api_key"
|
63
|
+
download = None
|
64
|
+
chunk_size: int = 2000
|
65
|
+
_credentials: dict = {
|
66
|
+
"HOST": str,
|
67
|
+
"PORT": str,
|
68
|
+
"APIKEY": str,
|
69
|
+
"INJECTOR_URL": str,
|
70
|
+
}
|
71
|
+
|
72
|
+
def __init__(
|
73
|
+
self,
|
74
|
+
loop: asyncio.AbstractEventLoop = None,
|
75
|
+
job: Callable = None,
|
76
|
+
stat: Callable = None,
|
77
|
+
**kwargs,
|
78
|
+
):
|
79
|
+
super().__init__(
|
80
|
+
loop=loop,
|
81
|
+
job=job,
|
82
|
+
stat=stat,
|
83
|
+
**kwargs
|
84
|
+
)
|
85
|
+
|
86
|
+
async def start(self, **kwargs):
|
87
|
+
if self.previous and isinstance(self.input, pd.DataFrame):
|
88
|
+
self.data = self.split_chunk_df(self.input, self.chunk_size)
|
89
|
+
|
90
|
+
self.processing_credentials()
|
91
|
+
|
92
|
+
self.headers = {"api-key": self.credentials["APIKEY"]}
|
93
|
+
|
94
|
+
self.url = self.get_url()
|
95
|
+
|
96
|
+
return True
|
97
|
+
|
98
|
+
async def run(self):
|
99
|
+
total_rows = 0
|
100
|
+
error_count = 0
|
101
|
+
errors = []
|
102
|
+
|
103
|
+
for idx, chunk in enumerate(self.data):
|
104
|
+
payload = self.get_payload(chunk.to_dict(orient="records"))
|
105
|
+
|
106
|
+
try:
|
107
|
+
self._logger.info(f"Sending chunk {idx} ...")
|
108
|
+
result, error = await self.session(
|
109
|
+
url=self.url, method="post", data=payload, use_json=True
|
110
|
+
)
|
111
|
+
|
112
|
+
if isinstance(result, dict) and result.get("ids"):
|
113
|
+
self._logger.debug(result)
|
114
|
+
total_rows += len(result["ids"])
|
115
|
+
else:
|
116
|
+
self._logger.error(f"Chunk {idx} failed: result: {result} :: error: {error}")
|
117
|
+
error_count += len(chunk) # Assuming the whole chunk failed
|
118
|
+
errors.append(f"Chunk {idx} failed with error: {error}")
|
119
|
+
|
120
|
+
except Exception as e:
|
121
|
+
self._logger.error(f"Error while sending chunk {idx}: {str(e)}. Continuing with next chunk...")
|
122
|
+
error_count += len(chunk) # Assuming the whole chunk failed
|
123
|
+
errors.append(f"Chunk {idx} exception: {str(e)}")
|
124
|
+
|
125
|
+
# Register metrics
|
126
|
+
self.add_metric("PROCESSED ROWS", total_rows)
|
127
|
+
self.add_metric("FAILED ROWS", error_count)
|
128
|
+
|
129
|
+
# Raise error if there were any failures
|
130
|
+
if errors:
|
131
|
+
errors.append(f"PROCESSED ROWS: {total_rows}, FAILED ROWS: {error_count}")
|
132
|
+
raise TaskError("\n".join(errors))
|
133
|
+
|
134
|
+
return True
|
135
|
+
|
136
|
+
|
137
|
+
async def close(self):
|
138
|
+
return True
|
139
|
+
|
140
|
+
def get_url(self):
|
141
|
+
port = (
|
142
|
+
f":{self.credentials['PORT']}" if self.credentials["PORT"] != "80" else ""
|
143
|
+
)
|
144
|
+
base_url = f"{self.credentials['HOST']}{port}"
|
145
|
+
url = urljoin(base_url, self.credentials["INJECTOR_URL"])
|
146
|
+
return url
|
147
|
+
|
148
|
+
def get_payload(self, chunk_data):
|
149
|
+
return {
|
150
|
+
"model": self.model,
|
151
|
+
"options": {
|
152
|
+
# 'has_headers': True,
|
153
|
+
"advanced": False,
|
154
|
+
"keep_matches": False,
|
155
|
+
"name_create_enabled_fields": getattr(self, "name_create_enabled_fields", {}),
|
156
|
+
"import_set_empty_fields": [],
|
157
|
+
"import_skip_records": [],
|
158
|
+
"fallback_values": {},
|
159
|
+
"skip": 0,
|
160
|
+
"limit": self.chunk_size,
|
161
|
+
# 'encoding': '',
|
162
|
+
# 'separator': '',
|
163
|
+
"quoting": '"',
|
164
|
+
# 'sheet': 'Sheet1',
|
165
|
+
"date_format": "",
|
166
|
+
"datetime_format": "",
|
167
|
+
"float_thousand_separator": ",",
|
168
|
+
"float_decimal_separator": ".",
|
169
|
+
"fields": [],
|
170
|
+
},
|
171
|
+
"data": chunk_data,
|
172
|
+
}
|
173
|
+
|
174
|
+
def split_chunk_df(self, df: pd.DataFrame, chunk_size: int):
|
175
|
+
"""
|
176
|
+
Splits a DataFrame into chunks of a specified size.
|
177
|
+
|
178
|
+
Parameters:
|
179
|
+
df (pd.DataFrame): The DataFrame to be split.
|
180
|
+
chunk_size (int): The maximum number of rows per chunk.
|
181
|
+
|
182
|
+
Returns:
|
183
|
+
list: A list of DataFrame chunks.
|
184
|
+
If the DataFrame is empty, returns an empty list.
|
185
|
+
"""
|
186
|
+
if df.empty:
|
187
|
+
return []
|
188
|
+
|
189
|
+
split_n = math.ceil(len(df) / chunk_size)
|
190
|
+
|
191
|
+
# Split into chunks of n rows
|
192
|
+
return np.array_split(df, split_n) # Returns list of DataFrames
|
@@ -0,0 +1,126 @@
|
|
1
|
+
import io
|
2
|
+
from pathlib import Path
|
3
|
+
from lxml import etree
|
4
|
+
from ..exceptions import ComponentError, FileError
|
5
|
+
from .OpenWithBase import FlowComponent
|
6
|
+
|
7
|
+
|
8
|
+
class OpenFromXML(FlowComponent):
|
9
|
+
"""
|
10
|
+
OpenFromXML
|
11
|
+
|
12
|
+
|
13
|
+
Overview
|
14
|
+
|
15
|
+
This component opens an XML file and returns it as an XML etree Object.
|
16
|
+
|
17
|
+
.. table:: Properties
|
18
|
+
:widths: auto
|
19
|
+
|
20
|
+
|
21
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
22
|
+
| Name | Required | Summary |
|
23
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
24
|
+
| directory | No | The directory where the XML file is located. |
|
25
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
26
|
+
| filename | Yes | The name of the XML file to be opened. |
|
27
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
28
|
+
| use_strings | No | If True, the component will treat the input as a string containing|
|
29
|
+
| | | XML data. |
|
30
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
31
|
+
| as_nodes | No | If set, specifies the node to be extracted from the XML tree. |
|
32
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
33
|
+
|
34
|
+
Returns:
|
35
|
+
- An `lxml.etree.ElementTree` object if the entire XML tree is parsed.
|
36
|
+
- A list of nodes (`lxml.etree.Element`) if `as_nodes` is set.
|
37
|
+
"""
|
38
|
+
async def start(self, **kwargs):
|
39
|
+
"""
|
40
|
+
start.
|
41
|
+
|
42
|
+
Get if directory exists
|
43
|
+
"""
|
44
|
+
if self.previous:
|
45
|
+
print("PREVIOUS FILE >", self.previous, type(self.input))
|
46
|
+
if isinstance(self.input, dict):
|
47
|
+
try:
|
48
|
+
filenames = list(self.input.keys())
|
49
|
+
if filenames:
|
50
|
+
self.filename = filenames[0]
|
51
|
+
except (TypeError, IndexError) as exc:
|
52
|
+
raise FileError("File is empty or doesn't exists") from exc
|
53
|
+
else:
|
54
|
+
self.data = self.input
|
55
|
+
if hasattr(self, "directory"):
|
56
|
+
self.path = Path(self.directory).resolve()
|
57
|
+
if not self.path.exists() or not self.path.is_dir():
|
58
|
+
raise ComponentError(
|
59
|
+
f"Directory not found: {self.directory}", status=404
|
60
|
+
)
|
61
|
+
# TODO: all logic for opening from File, pattern, etc
|
62
|
+
if not self.filename:
|
63
|
+
raise ComponentError("Filename empty", status=404)
|
64
|
+
|
65
|
+
async def close(self):
|
66
|
+
"""
|
67
|
+
close.
|
68
|
+
close method
|
69
|
+
"""
|
70
|
+
pass
|
71
|
+
|
72
|
+
async def run(self):
|
73
|
+
"""
|
74
|
+
run.
|
75
|
+
|
76
|
+
Open the XML file and return the object
|
77
|
+
"""
|
78
|
+
root = None
|
79
|
+
if hasattr(self, "use_strings") and self.use_strings is True:
|
80
|
+
fp = open(self.filename, "r")
|
81
|
+
self.data = fp.read()
|
82
|
+
self.filename = None
|
83
|
+
if self.filename:
|
84
|
+
print(f"Opening XML filename {self.filename}")
|
85
|
+
# Create a parser object
|
86
|
+
parser = etree.XMLParser(encoding="utf-8")
|
87
|
+
# open XML from File
|
88
|
+
tree = etree.parse(str(self.filename), parser)
|
89
|
+
try:
|
90
|
+
root = tree.getroot()
|
91
|
+
if etree.iselement(root):
|
92
|
+
self._result = tree
|
93
|
+
numrows = int(tree.xpath("count(/*)"))
|
94
|
+
self.add_metric("NUMROWS", numrows)
|
95
|
+
self.add_metric("OPENED_FILE", self.filename)
|
96
|
+
if hasattr(self, "as_nodes"):
|
97
|
+
objs = root.findall(self.node)
|
98
|
+
if objs:
|
99
|
+
self._result = objs
|
100
|
+
return self._result
|
101
|
+
except Exception as err:
|
102
|
+
print(err)
|
103
|
+
return False
|
104
|
+
elif self.data:
|
105
|
+
if isinstance(self.data, str):
|
106
|
+
# open XML from string
|
107
|
+
xml = io.BytesIO(self.data.encode("utf-8"))
|
108
|
+
parser = etree.XMLParser(recover=True, encoding="utf-8")
|
109
|
+
root = etree.parse(xml, parser)
|
110
|
+
try:
|
111
|
+
if etree.iselement(root.getroot()):
|
112
|
+
self._result = root
|
113
|
+
except Exception as err:
|
114
|
+
print("Error on parsing XML Tree: ", err)
|
115
|
+
return False
|
116
|
+
else:
|
117
|
+
# TODO: check if data is already an XML element
|
118
|
+
try:
|
119
|
+
print(etree.iselement(self.data.getroot()))
|
120
|
+
except Exception as err:
|
121
|
+
raise ComponentError(f"Invalid Object lxml, Error: {err}") from err
|
122
|
+
root = self.data
|
123
|
+
self._result = root
|
124
|
+
return self._result
|
125
|
+
else:
|
126
|
+
return False
|
@@ -0,0 +1,41 @@
|
|
1
|
+
from querysource.exceptions import DataNotFound as QSNotFound
|
2
|
+
from ..exceptions import ComponentError, DataNotFound
|
3
|
+
from .QSBase import QSBase
|
4
|
+
|
5
|
+
class OpenWeather(QSBase):
|
6
|
+
type = "weather"
|
7
|
+
_driver = "openweather"
|
8
|
+
_mapping: dict = {
|
9
|
+
"dt": "timestamp",
|
10
|
+
"main": "temperature",
|
11
|
+
"coord": "coordinates",
|
12
|
+
"name": "city",
|
13
|
+
"id": "city_id"
|
14
|
+
}
|
15
|
+
_from_conditions: list = [
|
16
|
+
"country",
|
17
|
+
"store_id",
|
18
|
+
"store_name"
|
19
|
+
]
|
20
|
+
|
21
|
+
async def weather(self):
|
22
|
+
try:
|
23
|
+
rst = []
|
24
|
+
resultset = await self._qs.weather()
|
25
|
+
print('CONDITIONS > ', self._qs._conditions)
|
26
|
+
data = resultset.copy()
|
27
|
+
for key, value in data.items():
|
28
|
+
if key in self._mapping:
|
29
|
+
resultset[self._mapping[key]] = value
|
30
|
+
del resultset[key]
|
31
|
+
if self._from_conditions:
|
32
|
+
for key in self._from_conditions:
|
33
|
+
if key in self._qs._conditions:
|
34
|
+
resultset[key] = self._qs._conditions[key]
|
35
|
+
rst.append(resultset)
|
36
|
+
return rst
|
37
|
+
except QSNotFound as err:
|
38
|
+
raise DataNotFound(f"Coordinates Not Found: {err}") from err
|
39
|
+
except Exception as err:
|
40
|
+
self._logger.exception(err)
|
41
|
+
raise ComponentError(f"OpenWeather ERROR: {err!s}") from err
|