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,199 @@
|
|
1
|
+
import os
|
2
|
+
import logging
|
3
|
+
import asyncio
|
4
|
+
from pathlib import PosixPath, PurePath
|
5
|
+
from collections.abc import Callable
|
6
|
+
import aiofiles
|
7
|
+
import pgpy
|
8
|
+
from pgpy.errors import (
|
9
|
+
PGPDecryptionError,
|
10
|
+
PGPOpenSSLCipherNotSupportedError,
|
11
|
+
PGPInsecureCipherError,
|
12
|
+
PGPError,
|
13
|
+
)
|
14
|
+
from ..exceptions import ComponentError, FileError
|
15
|
+
from ..conf import PGP_KEY_PATH, PGP_PASSPHRASE
|
16
|
+
from .flow import FlowComponent
|
17
|
+
|
18
|
+
|
19
|
+
class PGPDecrypt(FlowComponent):
|
20
|
+
"""
|
21
|
+
PGPDecrypt
|
22
|
+
|
23
|
+
Overview
|
24
|
+
|
25
|
+
Decrypt a file encrypted with PGP.
|
26
|
+
TODO: Works with several files (not only one).
|
27
|
+
|
28
|
+
.. table:: Properties
|
29
|
+
:widths: auto
|
30
|
+
|
31
|
+
|
32
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
33
|
+
| Name | Required | Summary |
|
34
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
35
|
+
| apply_mask | Yes | This component uses a mask to identify specific bit patterns in a |
|
36
|
+
| | | byte of data |
|
37
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
38
|
+
| start | Yes | We initialize the component obtaining the data through the |
|
39
|
+
| | | parameter type |
|
40
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
41
|
+
| close | Yes | The close method of a file object flushes any unwritten data |
|
42
|
+
| | | and closes the file object |
|
43
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
Return the list of arbitrary days
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
Example:
|
52
|
+
|
53
|
+
```yaml
|
54
|
+
PGPDecrypt:
|
55
|
+
filename: LETSTALKMOBILE_NDW_TRANSACTIONS_INFOQUEST_{today}.zip.gpg
|
56
|
+
directory: /home/ubuntu/symbits/xfinity/files/ltm/transactions/
|
57
|
+
decrypt:
|
58
|
+
filename: LETSTALKMOBILE_NDW_TRANSACTIONS_INFOQUEST_{today}.zip
|
59
|
+
directory: /home/ubuntu/symbits/xfinity/files/ltm/transactions/
|
60
|
+
masks:
|
61
|
+
'{today}':
|
62
|
+
- today
|
63
|
+
- mask: '%Y%m%d'
|
64
|
+
delete_source: true
|
65
|
+
```
|
66
|
+
|
67
|
+
"""
|
68
|
+
"""
|
69
|
+
PGPDecrypt
|
70
|
+
|
71
|
+
|
72
|
+
Overview
|
73
|
+
|
74
|
+
This component decrypts a PGP encrypted file and saves the decrypted content to a specified location.
|
75
|
+
|
76
|
+
.. table:: Properties
|
77
|
+
:widths: auto
|
78
|
+
|
79
|
+
|
80
|
+
+------------------------+----------+-----------+--------------------------------------------------------------------+
|
81
|
+
| Name | Required | Summary |
|
82
|
+
+------------------------+----------+-----------+--------------------------------------------------------------------+
|
83
|
+
| filename | No | The name of the file to decrypt. |
|
84
|
+
+------------------------+----------+-----------+--------------------------------------------------------------------+
|
85
|
+
| directory | No | The directory where the encrypted file is located. |
|
86
|
+
+------------------------+----------+-----------+--------------------------------------------------------------------+
|
87
|
+
| decrypt | No | Dictionary with "filename" and "directory" keys for output settings. |
|
88
|
+
+------------------------+----------+-----------+--------------------------------------------------------------------+
|
89
|
+
| delete_source | No | If True, deletes the source encrypted file after decryption. Default is False. |
|
90
|
+
+------------------------+----------+-----------+--------------------------------------------------------------------+
|
91
|
+
|
92
|
+
Returns
|
93
|
+
|
94
|
+
This component returns the path to the decrypted output file.
|
95
|
+
"""
|
96
|
+
|
97
|
+
def __init__(
|
98
|
+
self,
|
99
|
+
loop: asyncio.AbstractEventLoop = None,
|
100
|
+
job: Callable = None,
|
101
|
+
stat: Callable = None,
|
102
|
+
**kwargs,
|
103
|
+
):
|
104
|
+
"""Init Method."""
|
105
|
+
self.filename: str = None
|
106
|
+
self.directory: PurePath = None
|
107
|
+
self._path: PurePath = None
|
108
|
+
self._output: PurePath = None
|
109
|
+
self.encrypted = None
|
110
|
+
self.key = None
|
111
|
+
self.delete_source: bool = False
|
112
|
+
super(PGPDecrypt, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
|
113
|
+
|
114
|
+
async def start(self, **kwargs):
|
115
|
+
if isinstance(self.directory, str):
|
116
|
+
self.directory = PosixPath(self.directory).resolve()
|
117
|
+
self._path = PosixPath(self.directory, self.filename)
|
118
|
+
if self.filename is not None:
|
119
|
+
if hasattr(self, "masks"):
|
120
|
+
self.filename = self.mask_replacement(self.filename)
|
121
|
+
self._path = PosixPath(self.directory, self.filename)
|
122
|
+
elif self.previous:
|
123
|
+
if isinstance(self.input, PosixPath):
|
124
|
+
self.filename = self.input
|
125
|
+
elif isinstance(self.input, list):
|
126
|
+
self.filename = self.input[0]
|
127
|
+
elif isinstance(self.input, str):
|
128
|
+
self.filename = PosixPath(self.input)
|
129
|
+
else:
|
130
|
+
filenames = list(self.input.keys())
|
131
|
+
if filenames:
|
132
|
+
try:
|
133
|
+
self.filename = filenames[0]
|
134
|
+
except IndexError as err:
|
135
|
+
raise FileError("File is empty or doesnt exists") from err
|
136
|
+
self._variables["__FILEPATH__"] = self.filename
|
137
|
+
self._variables["__FILENAME__"] = os.path.basename(self.filename)
|
138
|
+
self._path = self.filename
|
139
|
+
else:
|
140
|
+
raise FileError("File is empty or doesnt exists")
|
141
|
+
if hasattr(self, "decrypt"):
|
142
|
+
if hasattr(self, "masks"):
|
143
|
+
self.decrypt["filename"] = self.mask_replacement(
|
144
|
+
self.decrypt["filename"]
|
145
|
+
)
|
146
|
+
if "directory" in self.decrypt:
|
147
|
+
PosixPath(self.decrypt["directory"]).mkdir(parents=True, exist_ok=True)
|
148
|
+
self._output = PosixPath(
|
149
|
+
self.decrypt["directory"], self.decrypt["filename"]
|
150
|
+
)
|
151
|
+
else:
|
152
|
+
self._output = PosixPath(self.directory, self.decrypt["filename"])
|
153
|
+
else:
|
154
|
+
self._output = PosixPath(
|
155
|
+
PosixPath(self._path).parents[0], PosixPath(self._path).stem
|
156
|
+
)
|
157
|
+
self.add_metric("OUTPUT_FILE", self._output)
|
158
|
+
# Encrypted Key
|
159
|
+
try:
|
160
|
+
self.encrypted = pgpy.PGPMessage.from_file(self._path)
|
161
|
+
if PGP_KEY_PATH:
|
162
|
+
self.key, _ = pgpy.PGPKey.from_file(PGP_KEY_PATH)
|
163
|
+
else:
|
164
|
+
raise ComponentError(
|
165
|
+
"Key path **PGP_KEY_PATH** not defined at environment"
|
166
|
+
)
|
167
|
+
except Exception as err:
|
168
|
+
raise ComponentError(f"{self.__name__} Error: {err}") from err
|
169
|
+
return True
|
170
|
+
|
171
|
+
async def close(self):
|
172
|
+
pass
|
173
|
+
|
174
|
+
async def run(self):
|
175
|
+
output = None
|
176
|
+
try:
|
177
|
+
with self.key.unlock(PGP_PASSPHRASE):
|
178
|
+
output = self.key.decrypt(self.encrypted).message
|
179
|
+
except (
|
180
|
+
PGPDecryptionError,
|
181
|
+
PGPOpenSSLCipherNotSupportedError,
|
182
|
+
PGPInsecureCipherError,
|
183
|
+
PGPError,
|
184
|
+
) as err:
|
185
|
+
# Raised when fails
|
186
|
+
logging.exception(err, stack_info=True)
|
187
|
+
raise ComponentError(
|
188
|
+
f"{err.__class__.__name__}: Error Decripting file: {err}"
|
189
|
+
) from err
|
190
|
+
|
191
|
+
try:
|
192
|
+
async with aiofiles.open(self._output, "wb") as fp:
|
193
|
+
await fp.write(bytes(output))
|
194
|
+
if self.delete_source is True:
|
195
|
+
self._path.unlink()
|
196
|
+
self._result = self._output
|
197
|
+
return self._result
|
198
|
+
except Exception as err:
|
199
|
+
raise ComponentError(f"{self.__name__} Error: {err}") from err
|
@@ -0,0 +1,187 @@
|
|
1
|
+
import asyncio
|
2
|
+
from threading import Semaphore
|
3
|
+
from decimal import Decimal
|
4
|
+
from typing import Any
|
5
|
+
from collections.abc import Callable
|
6
|
+
import pandas
|
7
|
+
import numpy as np
|
8
|
+
from navconfig.logging import logging
|
9
|
+
from asyncdb.exceptions import NoDataFound, ProviderError
|
10
|
+
from ..exceptions import ComponentError, NotSupported, DataNotFound
|
11
|
+
from .IteratorBase import IteratorBase, ThreadJob
|
12
|
+
|
13
|
+
|
14
|
+
class PandasIterator(IteratorBase):
|
15
|
+
"""
|
16
|
+
PandasIterator
|
17
|
+
|
18
|
+
Overview
|
19
|
+
|
20
|
+
This component converts data to a pandas DataFrame in an iterator and processes each row.
|
21
|
+
|
22
|
+
.. table:: Properties
|
23
|
+
:widths: auto
|
24
|
+
|
25
|
+
|
26
|
+
+--------------+----------+-----------+------------------------------------------------------------+
|
27
|
+
| Name | Required | Summary |
|
28
|
+
+--------------+----------+-----------+------------------------------------------------------------+
|
29
|
+
| columns | Yes | Names of the columns that we are going to extract. |
|
30
|
+
+--------------+----------+-----------+------------------------------------------------------------+
|
31
|
+
| vars | Yes | This attribute organizes names of the columns organized by id. |
|
32
|
+
+--------------+----------+-----------+------------------------------------------------------------+
|
33
|
+
| parallelize | No | If True, the iterator will process rows in parallel. Default is False. |
|
34
|
+
+--------------+----------+-----------+------------------------------------------------------------+
|
35
|
+
| num_threads | No | Number of threads to use if parallelize is True. Default is 10. |
|
36
|
+
+--------------+----------+-----------+------------------------------------------------------------+
|
37
|
+
|
38
|
+
Returns
|
39
|
+
-------
|
40
|
+
This component returns the processed pandas DataFrame after iterating
|
41
|
+
through the rows and applying the specified jobs.
|
42
|
+
|
43
|
+
|
44
|
+
Example:
|
45
|
+
|
46
|
+
```yaml
|
47
|
+
PandasIterator:
|
48
|
+
columns:
|
49
|
+
- formid
|
50
|
+
- orgid
|
51
|
+
vars:
|
52
|
+
form: '{orgid}/{formid}'
|
53
|
+
```
|
54
|
+
|
55
|
+
"""
|
56
|
+
|
57
|
+
def __init__(
|
58
|
+
self,
|
59
|
+
loop: asyncio.AbstractEventLoop = None,
|
60
|
+
job: Callable = None,
|
61
|
+
stat: Callable = None,
|
62
|
+
**kwargs,
|
63
|
+
):
|
64
|
+
self.pk = []
|
65
|
+
self.data = None
|
66
|
+
self._iterator: Any = None
|
67
|
+
self._variables = {}
|
68
|
+
self.vars = {}
|
69
|
+
self._columns = []
|
70
|
+
self._result = None
|
71
|
+
self._num_threads: int = kwargs.pop("num_threads", 10)
|
72
|
+
self._parallelize: bool = kwargs.pop("parallelize", False)
|
73
|
+
super(PandasIterator, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
|
74
|
+
|
75
|
+
async def start(self, **kwargs):
|
76
|
+
"""Obtain Pandas Dataframe."""
|
77
|
+
if self.previous:
|
78
|
+
self.data = self.input
|
79
|
+
if isinstance(self.data, pandas.core.frame.DataFrame):
|
80
|
+
if not hasattr(self, "columns"):
|
81
|
+
# iterate over the total columns of dataframe
|
82
|
+
self._columns = self.data.columns
|
83
|
+
else:
|
84
|
+
self._columns = self.columns
|
85
|
+
self._iterator = self.data.iterrows()
|
86
|
+
else:
|
87
|
+
raise ComponentError(
|
88
|
+
"PandasIterator: Invalid type of Data input (requires a Pandas Dataframe)"
|
89
|
+
)
|
90
|
+
return True
|
91
|
+
|
92
|
+
async def close(self, job=None):
|
93
|
+
close = getattr(job, "close", None)
|
94
|
+
if job:
|
95
|
+
if asyncio.iscoroutinefunction(close):
|
96
|
+
await job.close()
|
97
|
+
else:
|
98
|
+
job.close()
|
99
|
+
|
100
|
+
def createJob(self, target, params, row):
|
101
|
+
"""Create the Job Component."""
|
102
|
+
self._result = self.data
|
103
|
+
dt = {}
|
104
|
+
for column in self._columns:
|
105
|
+
value = row[column]
|
106
|
+
if isinstance(value, (int, np.int64, np.integer)):
|
107
|
+
value = int(value)
|
108
|
+
elif isinstance(value, (float, Decimal)):
|
109
|
+
value = float(value)
|
110
|
+
self.setVar(column, value)
|
111
|
+
params[column] = value
|
112
|
+
dt[column] = value
|
113
|
+
args = params["params"]
|
114
|
+
for name, value in self.vars.items():
|
115
|
+
if isinstance(value, list):
|
116
|
+
# TODO: logic to use functions with dataframes
|
117
|
+
# need to calculate the value
|
118
|
+
if name in args:
|
119
|
+
# replace value with args:
|
120
|
+
value = args[name]
|
121
|
+
elif name in dt:
|
122
|
+
value = dt[name]
|
123
|
+
else:
|
124
|
+
if "{" in str(value):
|
125
|
+
try:
|
126
|
+
value = value.format(**args)
|
127
|
+
except KeyError:
|
128
|
+
value = value.format(**dt)
|
129
|
+
params[name] = value
|
130
|
+
self.setVar(name, value)
|
131
|
+
return self.get_job(target, **params)
|
132
|
+
|
133
|
+
async def run(self):
|
134
|
+
"""Async Run Method."""
|
135
|
+
# iterate over next task
|
136
|
+
step, target, params = self.get_step()
|
137
|
+
step_name = step.name
|
138
|
+
i = 0
|
139
|
+
if self._parallelize is True:
|
140
|
+
# parallelized execution
|
141
|
+
threads = []
|
142
|
+
# Limit the number of concurrent threads to 10
|
143
|
+
semaphore = Semaphore(self._num_threads)
|
144
|
+
for _, row in self._iterator:
|
145
|
+
job = self.createJob(target, params, row)
|
146
|
+
if job:
|
147
|
+
thread = ThreadJob(job, step_name, semaphore)
|
148
|
+
threads.append(thread)
|
149
|
+
thread.start()
|
150
|
+
# wait for all threads to finish
|
151
|
+
for thread in threads:
|
152
|
+
thread.join()
|
153
|
+
|
154
|
+
# check if thread raised any exceptions
|
155
|
+
if thread.exc:
|
156
|
+
raise thread.exc
|
157
|
+
else:
|
158
|
+
for _, row in self._iterator:
|
159
|
+
i += 1
|
160
|
+
# iterate over every row
|
161
|
+
# get I got all values, create a job:
|
162
|
+
job = self.createJob(target, params, row)
|
163
|
+
if job:
|
164
|
+
try:
|
165
|
+
self._result = await self.async_job(job, step_name)
|
166
|
+
except (NoDataFound, DataNotFound) as err:
|
167
|
+
# its a data component a no data was found
|
168
|
+
self._logger.notice(
|
169
|
+
f"Data not Found for Task {step_name}, got: {err}"
|
170
|
+
)
|
171
|
+
continue
|
172
|
+
except (ProviderError, ComponentError) as err:
|
173
|
+
raise ComponentError(
|
174
|
+
f"Error on {step_name}, error: {err}"
|
175
|
+
) from err
|
176
|
+
except NotSupported as err:
|
177
|
+
raise NotSupported(f"Not Supported: {err}") from err
|
178
|
+
except Exception as err:
|
179
|
+
raise ComponentError(
|
180
|
+
f"Component Error {step_name}, error: {err}"
|
181
|
+
) from err
|
182
|
+
finally:
|
183
|
+
await self.close(job)
|
184
|
+
self._logger.debug(f"Iterations: {i}")
|
185
|
+
self.add_metric("ITERATIONS", i)
|
186
|
+
# returning last value generated by iteration
|
187
|
+
return self._result
|
@@ -0,0 +1,189 @@
|
|
1
|
+
import asyncio
|
2
|
+
from typing import Dict
|
3
|
+
from collections.abc import Callable
|
4
|
+
from pathlib import Path
|
5
|
+
import csv
|
6
|
+
import numpy as np
|
7
|
+
import pandas as pd
|
8
|
+
from ..exceptions import ComponentError, DataNotFound
|
9
|
+
from .flow import FlowComponent
|
10
|
+
from ..utils.constants import excel_based
|
11
|
+
|
12
|
+
|
13
|
+
class PandasToFile(FlowComponent):
|
14
|
+
"""
|
15
|
+
PandasToFile
|
16
|
+
|
17
|
+
Overview
|
18
|
+
|
19
|
+
This component exports a pandas DataFrame to a file in CSV, Excel, or JSON format.
|
20
|
+
|
21
|
+
.. table:: Properties
|
22
|
+
:widths: auto
|
23
|
+
|
24
|
+
|
25
|
+
+------------------------+----------+-----------+-----------------------------------------------------------------+
|
26
|
+
| Name | Required | Summary |
|
27
|
+
+------------------------+----------+-----------+-----------------------------------------------------------------+
|
28
|
+
| filename | Yes | The name of the file to save the DataFrame to. |
|
29
|
+
+------------------------+----------+-----------+-----------------------------------------------------------------+
|
30
|
+
| directory | No | The directory where the file will be saved. If not specified, |
|
31
|
+
| | | it will be derived from the filename. |
|
32
|
+
+------------------------+----------+-----------+-----------------------------------------------------------------+
|
33
|
+
| mime | No | The MIME type of the file. Supported types are "text/csv", |
|
34
|
+
| | | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", |
|
35
|
+
| | | "application/vnd.ms-excel", "application/json". Default is "text/csv". |
|
36
|
+
+------------------------+----------+-----------+-----------------------------------------------------------------+
|
37
|
+
| zerofill | No | If True, fills NaN values with "0" in string columns. Default is False. |
|
38
|
+
+------------------------+----------+-----------+-----------------------------------------------------------------+
|
39
|
+
| quoting | No | Specifies the quoting behavior for CSV files. Options are "all" (QUOTE_ALL),|
|
40
|
+
| | | "string" (QUOTE_NONNUMERIC), and None (QUOTE_NONE). Default is None. |
|
41
|
+
+------------------------+----------+-----------+-----------------------------------------------------------------+
|
42
|
+
| pd_args | No | Additional arguments for pandas' to_csv, to_excel, or to_json methods. |
|
43
|
+
| | | Default is an empty dictionary. |
|
44
|
+
+------------------------+----------+-----------+-----------------------------------------------------------------+
|
45
|
+
| sep | Yes | Make a separation of the file name with this sign |
|
46
|
+
+------------------------+----------+-----------+-----------------------------------------------------------------+
|
47
|
+
|
48
|
+
Returns
|
49
|
+
|
50
|
+
This component returns the filename of the saved file.
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
Example:
|
55
|
+
|
56
|
+
```yaml
|
57
|
+
PandasToFile:
|
58
|
+
filename: /home/ubuntu/symbits/bose/files/report/troc_open_tickets_{today}.csv
|
59
|
+
masks:
|
60
|
+
'{today}':
|
61
|
+
- today
|
62
|
+
- mask: '%Y-%m-%d'
|
63
|
+
mime: text/csv
|
64
|
+
quoting: string
|
65
|
+
pd_args:
|
66
|
+
sep: ','
|
67
|
+
```
|
68
|
+
|
69
|
+
""" # noqa
|
70
|
+
def __init__(
|
71
|
+
self,
|
72
|
+
loop: asyncio.AbstractEventLoop = None,
|
73
|
+
job: Callable = None,
|
74
|
+
stat: Callable = None,
|
75
|
+
**kwargs,
|
76
|
+
):
|
77
|
+
"""Init Method."""
|
78
|
+
self.zerofill: bool = False
|
79
|
+
self.quoting = None
|
80
|
+
self.params: Dict = {}
|
81
|
+
self.args: Dict = {}
|
82
|
+
self.filename: str = None
|
83
|
+
self.directory: str = None
|
84
|
+
self.mime: str = "text/csv"
|
85
|
+
super(PandasToFile, self).__init__(
|
86
|
+
loop=loop,
|
87
|
+
job=job,
|
88
|
+
stat=stat,
|
89
|
+
**kwargs
|
90
|
+
)
|
91
|
+
if hasattr(self, "pd_args"):
|
92
|
+
self.args = getattr(self, "pd_args", {})
|
93
|
+
|
94
|
+
async def start(self, **kwargs):
|
95
|
+
# Si lo que llega no es un DataFrame de Pandas se cancela la tarea
|
96
|
+
if self.previous:
|
97
|
+
self.data = self.input
|
98
|
+
else:
|
99
|
+
raise ComponentError("Data Not Found")
|
100
|
+
if not isinstance(self.data, pd.DataFrame):
|
101
|
+
raise ComponentError(
|
102
|
+
'Incompatible Pandas Dataframe: hint> add "export_dataframe"\
|
103
|
+
:true to tMap component'
|
104
|
+
)
|
105
|
+
if hasattr(self, "masks"):
|
106
|
+
self.filename = self.mask_replacement(self.filename)
|
107
|
+
# Create directory if not exists
|
108
|
+
try:
|
109
|
+
if not self.directory:
|
110
|
+
self.directory = Path(self.filename).parents[0]
|
111
|
+
self.directory.mkdir(parents=True, exist_ok=True)
|
112
|
+
except Exception as err:
|
113
|
+
self._logger.error(
|
114
|
+
f"Error creating directory {self.directory}: {err}"
|
115
|
+
)
|
116
|
+
raise ComponentError(
|
117
|
+
f"Error creating directory {self.directory}: {err}"
|
118
|
+
) from err
|
119
|
+
|
120
|
+
async def close(self):
|
121
|
+
pass
|
122
|
+
|
123
|
+
async def run(self):
|
124
|
+
self._result = {}
|
125
|
+
if self.zerofill:
|
126
|
+
cols = self.data.select_dtypes(include=["object", "string"])
|
127
|
+
self.data[cols.columns] = cols.fillna("0")
|
128
|
+
# self.data.fillna('0', inplace=True)
|
129
|
+
self.data.replace(np.nan, 0)
|
130
|
+
intcols = self.data.select_dtypes(include=["Int64"])
|
131
|
+
self.data[intcols.columns] = intcols.fillna(0)
|
132
|
+
try:
|
133
|
+
# filename, file_extension = os.path.splitext(self.filename)
|
134
|
+
if self.mime == "text/csv" or self.mime == "text/plain":
|
135
|
+
if self.quoting == "all":
|
136
|
+
quoting = csv.QUOTE_ALL
|
137
|
+
elif self.quoting == "string":
|
138
|
+
quoting = csv.QUOTE_NONNUMERIC
|
139
|
+
else:
|
140
|
+
quoting = csv.QUOTE_NONE
|
141
|
+
# if file_extension == '.csv':
|
142
|
+
# Los parametros se deben colocar en un diccionario en el JSON
|
143
|
+
# donde las llaves van a ser el nombre de los parametros que se
|
144
|
+
# muestran en la siguiente dirección
|
145
|
+
# https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_csv.html
|
146
|
+
if self.data.empty:
|
147
|
+
raise DataNotFound("PandasToFile: Cannot save an Empty Dataframe.")
|
148
|
+
self._logger.debug(
|
149
|
+
f"PandasToFile: Export to CSV: {self.filename}"
|
150
|
+
)
|
151
|
+
self.data.to_csv(
|
152
|
+
self.filename,
|
153
|
+
index=False,
|
154
|
+
quoting=quoting,
|
155
|
+
quotechar='"',
|
156
|
+
escapechar="\\",
|
157
|
+
**self.args,
|
158
|
+
)
|
159
|
+
elif self.mime in excel_based:
|
160
|
+
# elif file_extension == '.xlsx':
|
161
|
+
# Los parametros se deben colocar en un diccionario en el JSON
|
162
|
+
# donde las llaves van a ser el nombre de los parametros que se
|
163
|
+
# muestran en la siguiente dirección
|
164
|
+
# https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_excel.html
|
165
|
+
self._logger.debug(
|
166
|
+
f"PandasToFile: Export to EXCEL: {self.filename}"
|
167
|
+
)
|
168
|
+
self.data.to_excel(self.filename, index=False, **self.args)
|
169
|
+
elif self.mime == "application/json":
|
170
|
+
# elif file_extension == '.json':
|
171
|
+
# Los parametros se deben colocar en un diccionario en el JSON
|
172
|
+
# donde las llaves van a ser el nombre de los parametros que se
|
173
|
+
# muestran en la siguiente dirección
|
174
|
+
# https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_json.html
|
175
|
+
self._logger.debug(
|
176
|
+
f"PandasToFile: Export to JSON: {self.filename}"
|
177
|
+
)
|
178
|
+
self.data.to_json(self.filename, index=False, **self.args)
|
179
|
+
else:
|
180
|
+
raise ComponentError(
|
181
|
+
"Error: Only extension supported: csv, xlsx and json are supported"
|
182
|
+
)
|
183
|
+
# getting filename:
|
184
|
+
self._result[self.filename] = True
|
185
|
+
self.setTaskVar("FILENAME", self.filename)
|
186
|
+
self.add_metric("FILENAME", self.filename)
|
187
|
+
return self._result
|
188
|
+
except Exception as err:
|
189
|
+
raise ComponentError(f"Error in PandasToFile: {err}") from err
|