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,198 @@
|
|
1
|
+
import os
|
2
|
+
import asyncio
|
3
|
+
import re
|
4
|
+
from typing import List
|
5
|
+
from collections.abc import Callable
|
6
|
+
import aiofiles
|
7
|
+
from botocore.exceptions import ClientError
|
8
|
+
from ..exceptions import FileError, ComponentError, FileNotFound
|
9
|
+
from .DownloadFrom import DownloadFromBase
|
10
|
+
from ..interfaces.Boto3Client import Boto3Client
|
11
|
+
|
12
|
+
|
13
|
+
class DownloadFromS3(Boto3Client, DownloadFromBase):
|
14
|
+
"""
|
15
|
+
DownloadFromS3.
|
16
|
+
|
17
|
+
**Overview**
|
18
|
+
|
19
|
+
Download a file from an Amazon S3 bucket using the functionality from DownloadFrom.
|
20
|
+
|
21
|
+
**Properties**
|
22
|
+
|
23
|
+
.. table:: Properties
|
24
|
+
:widths: auto
|
25
|
+
|
26
|
+
+--------------------+----------+-----------+-----------------------------------------------------------------+
|
27
|
+
| Name | Required | Summary |
|
28
|
+
+--------------------+----------+-----------+-----------------------------------------------------------------+
|
29
|
+
| credentials | Yes | Credentials to establish connection with S3 service (username and password) |
|
30
|
+
+--------------------+----------+-----------+-----------------------------------------------------------------+
|
31
|
+
| bucket | Yes | The name of the S3 bucket to download files from. |
|
32
|
+
+--------------------+----------+-----------+-----------------------------------------------------------------+
|
33
|
+
| source_dir | No | The directory path within the S3 bucket to download files from. |
|
34
|
+
| | | Defaults to the root directory (`/`). |
|
35
|
+
+--------------------+----------+-----------+-----------------------------------------------------------------+
|
36
|
+
| source | No | A dictionary specifying the filename to download. |
|
37
|
+
| | | If provided, takes precedence over `source_dir` and `_srcfiles`. |
|
38
|
+
+--------------------+----------+-----------+-----------------------------------------------------------------+
|
39
|
+
| _srcfiles | No | A list of filenames to download from the S3 bucket. |
|
40
|
+
| | | Used in conjunction with `source_dir`. |
|
41
|
+
+--------------------+----------+-----------+-----------------------------------------------------------------+
|
42
|
+
| rename | No | A new filename to use for the downloaded file. |
|
43
|
+
+--------------------+----------+-----------+-----------------------------------------------------------------+
|
44
|
+
| directory | Yes | The local directory path to save the downloaded files. |
|
45
|
+
+--------------------+----------+-----------+-----------------------------------------------------------------+
|
46
|
+
| create_destination | No | A boolean flag indicating whether to create the destination directory |
|
47
|
+
| | | if it doesn't exist. Defaults to `True`. |
|
48
|
+
+--------------------+----------+-----------+-----------------------------------------------------------------+
|
49
|
+
|
50
|
+
save the file on the new destination.
|
51
|
+
|
52
|
+
**Methods**
|
53
|
+
|
54
|
+
* start()
|
55
|
+
* close()
|
56
|
+
* run()
|
57
|
+
* s3_list(s3_client, suffix="")
|
58
|
+
* save_attachment(self, filepath, content)
|
59
|
+
* download_file(self, filename, obj)
|
60
|
+
|
61
|
+
|
62
|
+
Example:
|
63
|
+
|
64
|
+
```yaml
|
65
|
+
DownloadFromS3:
|
66
|
+
credentials:
|
67
|
+
use_credentials: false
|
68
|
+
region_name: us-east-2
|
69
|
+
bucket: placer-navigator-data
|
70
|
+
source_dir: placer-analytics/bulk-export/monthly-weekly/2025-03-06/metadata/
|
71
|
+
destination:
|
72
|
+
directory: /nfs/symbits/placerai/2025-03-06/metadata/
|
73
|
+
create_destination: true
|
74
|
+
```
|
75
|
+
|
76
|
+
"""
|
77
|
+
|
78
|
+
def __init__(
|
79
|
+
self,
|
80
|
+
loop: asyncio.AbstractEventLoop = None,
|
81
|
+
job: Callable = None,
|
82
|
+
stat: Callable = None,
|
83
|
+
**kwargs,
|
84
|
+
):
|
85
|
+
self.url: str = None
|
86
|
+
self.folder = None
|
87
|
+
self.rename: str = None
|
88
|
+
self.context = None
|
89
|
+
super().__init__(
|
90
|
+
loop=loop, job=job, stat=stat, **kwargs
|
91
|
+
)
|
92
|
+
|
93
|
+
async def start(self, **kwargs):
|
94
|
+
await super(DownloadFromS3, self).start(**kwargs)
|
95
|
+
if isinstance(self.directory, str) and "{" in self.directory:
|
96
|
+
self.directory = self.mask_replacement(self.directory)
|
97
|
+
print(f"Directory after mask replacement: {self.directory}")
|
98
|
+
if hasattr(self, 'source_dir') and self.source_dir and isinstance(self.source_dir, str) and "{" in self.source_dir:
|
99
|
+
self.source_dir = self.mask_replacement(self.source_dir)
|
100
|
+
print(f"Source directory after mask replacement: {self.source_dir}")
|
101
|
+
if self.source_dir and not self.source_dir.endswith("/"):
|
102
|
+
self.source_dir = self.source_dir + "/"
|
103
|
+
return True
|
104
|
+
|
105
|
+
async def run(self):
|
106
|
+
try:
|
107
|
+
if not self.directory.exists():
|
108
|
+
if self.create_destination is True:
|
109
|
+
try:
|
110
|
+
self.directory.mkdir(parents=True, exist_ok=True)
|
111
|
+
except Exception as e:
|
112
|
+
raise ComponentError(
|
113
|
+
f"S3: Error creating destination directory: {e}"
|
114
|
+
) from e
|
115
|
+
else:
|
116
|
+
raise ComponentError(
|
117
|
+
f"S3: destination directory doesn't exists: {self.directory}"
|
118
|
+
)
|
119
|
+
except Exception as err:
|
120
|
+
self._logger.error(f"S3: Error creating destination directory: {err}")
|
121
|
+
raise ComponentError(
|
122
|
+
f"S3: Error creating destination directory: {err}"
|
123
|
+
) from err
|
124
|
+
errors = {}
|
125
|
+
files = {}
|
126
|
+
if not self._connection:
|
127
|
+
await self.open(credentials=self.credentials)
|
128
|
+
if hasattr(self, "file"):
|
129
|
+
# find src files using get_list:
|
130
|
+
s3_files = await self.s3_list(self._connection)
|
131
|
+
for obj in s3_files:
|
132
|
+
try:
|
133
|
+
file = obj["Key"]
|
134
|
+
try:
|
135
|
+
obj = await self._connection.get_object(
|
136
|
+
Bucket=self.bucket, Key=file
|
137
|
+
)
|
138
|
+
except Exception as e:
|
139
|
+
raise ComponentError(
|
140
|
+
f"S3: Error getting object from Bucket: {e}"
|
141
|
+
) from e
|
142
|
+
result = await self.download_file(os.path.basename(file), obj)
|
143
|
+
if isinstance(result, BaseException):
|
144
|
+
errors[file] = result
|
145
|
+
else:
|
146
|
+
files[file] = result
|
147
|
+
except Exception as e:
|
148
|
+
raise ComponentError(f"{e!s}") from e
|
149
|
+
else:
|
150
|
+
if not self._srcfiles:
|
151
|
+
# Download all files from source_dir
|
152
|
+
s3_files = await self.s3_list()
|
153
|
+
files = {}
|
154
|
+
for file in s3_files:
|
155
|
+
try:
|
156
|
+
# Extraer la Key del objeto S3
|
157
|
+
file_key = file["Key"] if isinstance(file, dict) else file
|
158
|
+
obj = await self.get_s3_object(
|
159
|
+
bucket=self.bucket, filename=file_key
|
160
|
+
)
|
161
|
+
except FileNotFound:
|
162
|
+
raise
|
163
|
+
except Exception as e:
|
164
|
+
raise ComponentError(
|
165
|
+
f"S3: Error getting object from Bucket: {e}"
|
166
|
+
) from e
|
167
|
+
result = await self.download_file(os.path.basename(file_key), obj)
|
168
|
+
if isinstance(result, BaseException):
|
169
|
+
errors[file_key] = result
|
170
|
+
else:
|
171
|
+
files[file_key] = result
|
172
|
+
else:
|
173
|
+
for file in self._srcfiles:
|
174
|
+
if self.source_dir:
|
175
|
+
filename = f"{self.source_dir}{file}"
|
176
|
+
else:
|
177
|
+
filename = file
|
178
|
+
print(f"Downloading file: {filename}")
|
179
|
+
try:
|
180
|
+
self._logger.debug(f"S3: Downloading File {filename}")
|
181
|
+
obj = await self.get_s3_object(
|
182
|
+
bucket=self.bucket, filename=filename
|
183
|
+
)
|
184
|
+
except FileNotFound:
|
185
|
+
raise
|
186
|
+
except Exception as e:
|
187
|
+
raise ComponentError(
|
188
|
+
f"S3: Error getting object from Bucket: {e}"
|
189
|
+
) from e
|
190
|
+
result = await self.download_file(file, obj)
|
191
|
+
if isinstance(result, BaseException):
|
192
|
+
errors[file] = result
|
193
|
+
else:
|
194
|
+
files[file] = result
|
195
|
+
# at end, create the result:
|
196
|
+
self._result = {"files": files, "errors": errors}
|
197
|
+
self.add_metric("S3_FILES", files)
|
198
|
+
return self._result
|
@@ -0,0 +1,265 @@
|
|
1
|
+
import asyncio
|
2
|
+
from collections.abc import Callable
|
3
|
+
from pathlib import Path, PurePath
|
4
|
+
import asyncssh
|
5
|
+
from navconfig.logging import logging
|
6
|
+
from ..exceptions import FileError, ComponentError, FileNotFound
|
7
|
+
from .DownloadFrom import DownloadFromBase
|
8
|
+
from ..interfaces.SSHClient import SSHClient
|
9
|
+
|
10
|
+
|
11
|
+
class DownloadFromSFTP(SSHClient, DownloadFromBase):
|
12
|
+
"""
|
13
|
+
DownloadFromSFTP.
|
14
|
+
|
15
|
+
**Overview**
|
16
|
+
|
17
|
+
Download a file or directory from an SFTP server using the functionality from DownloadFrom.
|
18
|
+
|
19
|
+
**Properties** (inherited from DownloadFromBase and SSHClient)
|
20
|
+
|
21
|
+
.. table:: Properties
|
22
|
+
:widths: auto
|
23
|
+
|
24
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
25
|
+
| Name | Required | Summary |
|
26
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
27
|
+
| credentials | Yes | Credentials to establish connection with SFTP server (username and password) |
|
28
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
29
|
+
| host | Yes | The hostname or IP address of the SFTP server. |
|
30
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
31
|
+
| port | No | The port number of the SFTP server (default: 22). |
|
32
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
33
|
+
| tunnel | No | Dictionary defining a tunnel to use for the connection. |
|
34
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
35
|
+
| block_size | No | Block size for file transfer (default: 4096 bytes). |
|
36
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
37
|
+
| max_requests | No | Maximum number of concurrent file transfers (default: 5). |
|
38
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
39
|
+
| create_destination | No | Boolean flag indicating whether to create the destination directory |
|
40
|
+
| | | if it doesn't exist (default: True). |
|
41
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
42
|
+
| source | Yes | A dictionary specifying the source file or directory on the SFTP server. |
|
43
|
+
| | | Can include: |
|
44
|
+
| | | whole_dir (Optional, bool): Whether to download the entire directory (default: False).|
|
45
|
+
| | | recursive (Optional, bool): Whether to download subdirectories recursively when |
|
46
|
+
| | | `whole_dir` is True (default: False). |
|
47
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
48
|
+
| filename | No | The filename to download from the SFTP server (if not using `source`). |
|
49
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
50
|
+
| mdate | No | Modification date of the file to download (for filtering based on modification time). |
|
51
|
+
+--------------------+----------+-----------------------+----------------------------------------------------------------+
|
52
|
+
| rename | No | A new filename to use for the downloaded file. |
|
53
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
54
|
+
| masks | No | A dictionary mapping mask strings to replacement strings used for renaming files and |
|
55
|
+
| | | modification dates. |
|
56
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
57
|
+
| overwrite | No | Whether to overwrite existing files in the destination directory (default: False). |
|
58
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
59
|
+
| remove | No | Whether to remove the downloaded files from the SFTP server after |
|
60
|
+
| | | successful download (default: False). |
|
61
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------------+
|
62
|
+
|
63
|
+
Save the downloaded files on the new destination.
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
Example:
|
68
|
+
|
69
|
+
```yaml
|
70
|
+
DownloadFromSFTP:
|
71
|
+
file:
|
72
|
+
pattern: Performance_Tracker/*
|
73
|
+
mdate: '{today}'
|
74
|
+
host: altice_ltm_sftp_host
|
75
|
+
port: altice_ltm_sftp_port
|
76
|
+
credentials:
|
77
|
+
username: altice_ltm_sftp_username
|
78
|
+
password: altice_ltm_sftp_password
|
79
|
+
known_hosts: null
|
80
|
+
directory: /home/ubuntu/altice/files/
|
81
|
+
overwrite: true
|
82
|
+
masks:
|
83
|
+
'{today}':
|
84
|
+
- yesterday
|
85
|
+
- mask: '%Y-%m-%d'
|
86
|
+
```
|
87
|
+
|
88
|
+
""" # noqa
|
89
|
+
|
90
|
+
to_remove = (
|
91
|
+
"file",
|
92
|
+
"filename",
|
93
|
+
"directory",
|
94
|
+
"source",
|
95
|
+
"destination",
|
96
|
+
"create_destination",
|
97
|
+
"overwrite",
|
98
|
+
"rename",
|
99
|
+
)
|
100
|
+
|
101
|
+
def __init__(
|
102
|
+
self,
|
103
|
+
loop: asyncio.AbstractEventLoop = None,
|
104
|
+
job: Callable = None,
|
105
|
+
stat: Callable = None,
|
106
|
+
**kwargs,
|
107
|
+
):
|
108
|
+
self.mdate = None
|
109
|
+
self.local_name = None
|
110
|
+
self.rename: str = None
|
111
|
+
self.filename: str = ""
|
112
|
+
self.whole_dir: bool = False
|
113
|
+
super().__init__(loop=loop, job=job, stat=stat, **kwargs)
|
114
|
+
|
115
|
+
async def start(self, **kwargs):
|
116
|
+
await super(DownloadFromSFTP, self).start(**kwargs)
|
117
|
+
if hasattr(self, "source"):
|
118
|
+
self.whole_dir = (
|
119
|
+
self.source["whole_dir"] if "whole_dir" in self.source else False
|
120
|
+
)
|
121
|
+
if hasattr(self, "file"):
|
122
|
+
if "mdate" in self.file:
|
123
|
+
self.mdate = self.file["mdate"]
|
124
|
+
# Mask in rename file
|
125
|
+
if hasattr(self, "masks"):
|
126
|
+
try:
|
127
|
+
for mask, replace in self._mask.items():
|
128
|
+
if self.rename is not None:
|
129
|
+
self.rename = self.rename.replace(mask, str(replace))
|
130
|
+
if self.mdate is not None:
|
131
|
+
self.mdate = self.mdate.replace(mask, replace)
|
132
|
+
except Exception as e:
|
133
|
+
raise ComponentError(f"{e!s}") from e
|
134
|
+
self.rename = Path("{}/{}".format(self.directory, self.rename))
|
135
|
+
if self.rename is not None:
|
136
|
+
self.local_name = self.rename
|
137
|
+
else:
|
138
|
+
self.local_name = Path(
|
139
|
+
"{}/{}".format(self.directory, PurePath(self.filename).name)
|
140
|
+
)
|
141
|
+
return True
|
142
|
+
|
143
|
+
def download_progress(self, srcpath, dstpath, bytes_copied, total_bytes):
|
144
|
+
self._filenames[dstpath] = srcpath
|
145
|
+
self._pb.reset(total=total_bytes)
|
146
|
+
self._pb.update(bytes_copied)
|
147
|
+
self._pb.refresh()
|
148
|
+
|
149
|
+
async def download(self):
|
150
|
+
try:
|
151
|
+
await self.open(
|
152
|
+
host=self.host,
|
153
|
+
port=self.port,
|
154
|
+
tunnel=self.tunnel,
|
155
|
+
credentials=self.credentials,
|
156
|
+
)
|
157
|
+
except asyncio.CancelledError:
|
158
|
+
self._logger.info(f"{self.host} CANCELED~")
|
159
|
+
# break
|
160
|
+
except (asyncio.TimeoutError, ComponentError) as err:
|
161
|
+
raise ComponentError(f"Error: {err}") from err
|
162
|
+
except Exception as err:
|
163
|
+
raise ComponentError(f"Error: {err}") from err
|
164
|
+
async with self._connection.start_sftp_client() as sftp:
|
165
|
+
# check all versions of functionalities
|
166
|
+
args = {
|
167
|
+
"block_size": self.block_size,
|
168
|
+
"max_requests": self.max_requests,
|
169
|
+
"progress_handler": self.download_progress,
|
170
|
+
"error_handler": self.err_handler,
|
171
|
+
}
|
172
|
+
if self.whole_dir is True:
|
173
|
+
if hasattr(self, "source"): # using the source/destination filosophy
|
174
|
+
args["remotepaths"] = self.source_dir
|
175
|
+
args["localpath"] = self.directory
|
176
|
+
args["recurse"] = True if "recursive" in self.source else False
|
177
|
+
else:
|
178
|
+
raise ComponentError(
|
179
|
+
"*Whole Dir* and self.source are mutually inclusive, \
|
180
|
+
missing self.source"
|
181
|
+
)
|
182
|
+
# getting the stats of the remote path:
|
183
|
+
stats = await sftp.listdir(path=self.source_dir)
|
184
|
+
self.start_progress(total=len(stats))
|
185
|
+
else:
|
186
|
+
filelist = []
|
187
|
+
if self._srcfiles:
|
188
|
+
logging.debug(f"FILES::: {self._srcfiles}")
|
189
|
+
for file in self._srcfiles:
|
190
|
+
if self.mdate is not None:
|
191
|
+
flist = await self.get_mtime_files(sftp, file, self.mdate)
|
192
|
+
filelist += flist
|
193
|
+
if not flist:
|
194
|
+
raise FileNotFound(
|
195
|
+
f"File Not Found for modification date {self.mdate}"
|
196
|
+
)
|
197
|
+
else:
|
198
|
+
filelist.append(file)
|
199
|
+
else:
|
200
|
+
filelist = self.filename
|
201
|
+
args["remotepaths"] = filelist
|
202
|
+
args["localpath"] = self.directory
|
203
|
+
args["preserve"] = True
|
204
|
+
self.start_progress(total=len(filelist))
|
205
|
+
try:
|
206
|
+
await sftp.mget(**args)
|
207
|
+
self.close_progress()
|
208
|
+
# get all the files downloaded
|
209
|
+
result = list(self._filenames.keys())
|
210
|
+
self._result = [v.decode("utf8") for v in result]
|
211
|
+
# Rename file if only one
|
212
|
+
if len(self._result) == 1 and self.rename is not None:
|
213
|
+
f = Path(self._result[0])
|
214
|
+
f.rename(self.local_name)
|
215
|
+
self._result[0] = self.local_name
|
216
|
+
if hasattr(self, "remove") and self.remove is True:
|
217
|
+
try:
|
218
|
+
for _, filename in self._filenames.items():
|
219
|
+
logging.debug(f"Removing remote file: {filename}")
|
220
|
+
await sftp.remove(filename)
|
221
|
+
except asyncssh.sftp.SFTPError as err:
|
222
|
+
logging.error(f"SFTP error: {err}")
|
223
|
+
return True
|
224
|
+
except OSError as err:
|
225
|
+
self._logger.error(err)
|
226
|
+
raise ComponentError(f"SFTP Local error: {err}") from err
|
227
|
+
except asyncssh.sftp.SFTPNoSuchFile as err:
|
228
|
+
raise FileNotFound(f"File Not Found: {err}") from err
|
229
|
+
except asyncssh.sftp.SFTPError as err:
|
230
|
+
self._logger.error(err)
|
231
|
+
raise FileError(f"SFTP server error: {err}") from err
|
232
|
+
except asyncssh.Error as err:
|
233
|
+
self._logger.error(err)
|
234
|
+
raise ComponentError(f"SFTP connection failed: {err}") from err
|
235
|
+
except FileNotFound:
|
236
|
+
raise
|
237
|
+
except Exception as err:
|
238
|
+
self._logger.exception(err, stack_info=True)
|
239
|
+
raise ComponentError(f"SFTP Error: {err}") from err
|
240
|
+
|
241
|
+
async def run(self):
|
242
|
+
"""Running Download file."""
|
243
|
+
self._result = None
|
244
|
+
status = False
|
245
|
+
if self.overwrite is False and self.local_name.is_file():
|
246
|
+
# file already exists and can be skipped
|
247
|
+
self._filenames = [str(self.local_name)]
|
248
|
+
self._result = [str(self.local_name)]
|
249
|
+
status = True
|
250
|
+
else:
|
251
|
+
try:
|
252
|
+
status = await self.download()
|
253
|
+
except FileNotFound:
|
254
|
+
raise
|
255
|
+
except FileError:
|
256
|
+
raise
|
257
|
+
except ComponentError:
|
258
|
+
raise
|
259
|
+
except Exception as exc:
|
260
|
+
raise ComponentError(f"{exc}") from exc
|
261
|
+
if status is False:
|
262
|
+
return False
|
263
|
+
else:
|
264
|
+
self.add_metric("SFTP_FILES", self._result)
|
265
|
+
return self._result
|
@@ -0,0 +1,110 @@
|
|
1
|
+
import asyncio
|
2
|
+
from collections.abc import Callable
|
3
|
+
from navconfig.logging import logging
|
4
|
+
from ..exceptions import FileNotFound, FileError
|
5
|
+
from .DownloadFrom import DownloadFromBase
|
6
|
+
from ..interfaces.Sharepoint import SharepointClient
|
7
|
+
|
8
|
+
|
9
|
+
class DownloadFromSharepoint(SharepointClient, DownloadFromBase):
|
10
|
+
"""
|
11
|
+
DownloadFromSharepoint.
|
12
|
+
|
13
|
+
**Overview**
|
14
|
+
|
15
|
+
This Sharepoint component downloads a file or uploads it to the Microsoft Sharepoint service
|
16
|
+
|
17
|
+
**Properties** (inherited from DownloadFromBase and Sharepoint)
|
18
|
+
|
19
|
+
.. table:: Properties
|
20
|
+
:widths: auto
|
21
|
+
|
22
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------+
|
23
|
+
| Name | Required | Summary |
|
24
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------+
|
25
|
+
| credentials | Yes | Credentials to establish connection with SharePoint site (username and password) |
|
26
|
+
| | | get credentials from environment if null. |
|
27
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------+
|
28
|
+
| site | Yes | The URL of the SharePoint site. |
|
29
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------+
|
30
|
+
| verify | No | Whether to verify the SSL certificate of the SharePoint site (default: True). |
|
31
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------+
|
32
|
+
| timeout | No | The timeout value for SharePoint operations (default: 30 seconds). |
|
33
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------+
|
34
|
+
| create_destination | No | Boolean flag indicating whether to create the destination directory if it |
|
35
|
+
| | | doesn't exist (default: True). |
|
36
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------+
|
37
|
+
| tenant | Yes | Is the set of site collections of SharePoint |
|
38
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------+
|
39
|
+
| file_id | Yes | Identificador del archivo en sharepoint |
|
40
|
+
+--------------------+----------+-----------+----------------------------------------------------------------------+
|
41
|
+
|
42
|
+
Save the downloaded files on the new destination.
|
43
|
+
|
44
|
+
|
45
|
+
Example:
|
46
|
+
|
47
|
+
```yaml
|
48
|
+
DownloadFromSharepoint:
|
49
|
+
credentials:
|
50
|
+
username: SHAREPOINT_TROCADV_USERNAME
|
51
|
+
password: SHAREPOINT_TROCADV_PASSWORD
|
52
|
+
tenant: symbits
|
53
|
+
site: FlexRoc
|
54
|
+
file:
|
55
|
+
filename: Bose Schedule.xlsx
|
56
|
+
directory: Shared Documents/General/Monthly Schedule & Reporting
|
57
|
+
destination:
|
58
|
+
directory: /home/ubuntu/symbits/bose/stores/
|
59
|
+
filename: Bose Schedule - {today}.xlsx
|
60
|
+
masks:
|
61
|
+
'{today}':
|
62
|
+
- today
|
63
|
+
- mask: '%Y-%m-%d'
|
64
|
+
```
|
65
|
+
|
66
|
+
""" # noqa
|
67
|
+
def __init__(
|
68
|
+
self,
|
69
|
+
loop: asyncio.AbstractEventLoop = None,
|
70
|
+
job: Callable = None,
|
71
|
+
stat: Callable = None,
|
72
|
+
**kwargs,
|
73
|
+
):
|
74
|
+
self.url: str = None
|
75
|
+
self.folder = None
|
76
|
+
self.rename: str = None
|
77
|
+
self.context = None
|
78
|
+
super().__init__(loop=loop, job=job, stat=stat, **kwargs)
|
79
|
+
|
80
|
+
async def start(self, **kwargs):
|
81
|
+
# Call the start method from the base classes
|
82
|
+
await super(DownloadFromSharepoint, self).start(**kwargs)
|
83
|
+
self._started = True
|
84
|
+
return True
|
85
|
+
|
86
|
+
async def close(self):
|
87
|
+
pass
|
88
|
+
|
89
|
+
async def run(self):
|
90
|
+
async with self.connection():
|
91
|
+
if not self.context:
|
92
|
+
self.context = self.get_context(self.url)
|
93
|
+
try:
|
94
|
+
if hasattr(self, 'file') and "pattern" in self.file: # search-like context
|
95
|
+
filenames = await self.file_search()
|
96
|
+
else:
|
97
|
+
filenames = await self.file_download()
|
98
|
+
self._result = filenames
|
99
|
+
self.add_metric(
|
100
|
+
"SHAREPOINT_FILES",
|
101
|
+
self._result
|
102
|
+
)
|
103
|
+
return self._result
|
104
|
+
except (FileError, FileNotFound):
|
105
|
+
raise
|
106
|
+
except Exception as err:
|
107
|
+
logging.error(f"Error downloading File: {err}")
|
108
|
+
raise FileError(
|
109
|
+
f"Error downloading File: {err}"
|
110
|
+
) from err
|