flowtask 5.8.4__cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flowtask/__init__.py +93 -0
- flowtask/__main__.py +38 -0
- flowtask/bots/__init__.py +6 -0
- flowtask/bots/check.py +93 -0
- flowtask/bots/codebot.py +51 -0
- flowtask/components/ASPX.py +148 -0
- flowtask/components/AddDataset.py +352 -0
- flowtask/components/Amazon.py +523 -0
- flowtask/components/AutoTask.py +314 -0
- flowtask/components/Azure.py +80 -0
- flowtask/components/AzureUsers.py +106 -0
- flowtask/components/BaseAction.py +91 -0
- flowtask/components/BaseLoop.py +198 -0
- flowtask/components/BestBuy.py +800 -0
- flowtask/components/CSVToGCS.py +120 -0
- flowtask/components/CompanyScraper/__init__.py +1 -0
- flowtask/components/CompanyScraper/parsers/__init__.py +6 -0
- flowtask/components/CompanyScraper/parsers/base.py +102 -0
- flowtask/components/CompanyScraper/parsers/explorium.py +192 -0
- flowtask/components/CompanyScraper/parsers/leadiq.py +206 -0
- flowtask/components/CompanyScraper/parsers/rocket.py +133 -0
- flowtask/components/CompanyScraper/parsers/siccode.py +109 -0
- flowtask/components/CompanyScraper/parsers/visualvisitor.py +130 -0
- flowtask/components/CompanyScraper/parsers/zoominfo.py +118 -0
- flowtask/components/CompanyScraper/scrapper.py +1054 -0
- flowtask/components/CopyTo.py +177 -0
- flowtask/components/CopyToBigQuery.py +243 -0
- flowtask/components/CopyToMongoDB.py +291 -0
- flowtask/components/CopyToPg.py +609 -0
- flowtask/components/CopyToRethink.py +207 -0
- flowtask/components/CreateGCSBucket.py +102 -0
- flowtask/components/CreateReport/CreateReport.py +228 -0
- flowtask/components/CreateReport/__init__.py +9 -0
- flowtask/components/CreateReport/charts/__init__.py +15 -0
- flowtask/components/CreateReport/charts/bar.py +51 -0
- flowtask/components/CreateReport/charts/base.py +66 -0
- flowtask/components/CreateReport/charts/pie.py +64 -0
- flowtask/components/CreateReport/utils.py +9 -0
- flowtask/components/CustomerSatisfaction.py +196 -0
- flowtask/components/DataInput.py +200 -0
- flowtask/components/DateList.py +255 -0
- flowtask/components/DbClient.py +163 -0
- flowtask/components/DialPad.py +146 -0
- flowtask/components/DocumentDBQuery.py +200 -0
- flowtask/components/DownloadFrom.py +371 -0
- flowtask/components/DownloadFromD2L.py +113 -0
- flowtask/components/DownloadFromFTP.py +181 -0
- flowtask/components/DownloadFromIMAP.py +315 -0
- flowtask/components/DownloadFromS3.py +198 -0
- flowtask/components/DownloadFromSFTP.py +265 -0
- flowtask/components/DownloadFromSharepoint.py +110 -0
- flowtask/components/DownloadFromSmartSheet.py +114 -0
- flowtask/components/DownloadS3File.py +229 -0
- flowtask/components/Dummy.py +59 -0
- flowtask/components/DuplicatePhoto.py +411 -0
- flowtask/components/EmployeeEvaluation.py +237 -0
- flowtask/components/ExecuteSQL.py +323 -0
- flowtask/components/ExtractHTML.py +178 -0
- flowtask/components/FileBase.py +178 -0
- flowtask/components/FileCopy.py +181 -0
- flowtask/components/FileDelete.py +82 -0
- flowtask/components/FileExists.py +146 -0
- flowtask/components/FileIteratorDelete.py +112 -0
- flowtask/components/FileList.py +194 -0
- flowtask/components/FileOpen.py +75 -0
- flowtask/components/FileRead.py +120 -0
- flowtask/components/FileRename.py +106 -0
- flowtask/components/FilterIf.py +284 -0
- flowtask/components/FilterRows/FilterRows.py +200 -0
- flowtask/components/FilterRows/__init__.py +10 -0
- flowtask/components/FilterRows/functions.py +4 -0
- flowtask/components/GCSToBigQuery.py +103 -0
- flowtask/components/GoogleA4.py +150 -0
- flowtask/components/GoogleGeoCoding.py +344 -0
- flowtask/components/GooglePlaces.py +315 -0
- flowtask/components/GoogleSearch.py +539 -0
- flowtask/components/HTTPClient.py +268 -0
- flowtask/components/ICIMS.py +146 -0
- flowtask/components/IF.py +179 -0
- flowtask/components/IcimsFolderCopy.py +173 -0
- flowtask/components/ImageFeatures/__init__.py +5 -0
- flowtask/components/ImageFeatures/process.py +233 -0
- flowtask/components/IteratorBase.py +251 -0
- flowtask/components/LangchainLoader/__init__.py +5 -0
- flowtask/components/LangchainLoader/loader.py +194 -0
- flowtask/components/LangchainLoader/loaders/__init__.py +22 -0
- flowtask/components/LangchainLoader/loaders/abstract.py +362 -0
- flowtask/components/LangchainLoader/loaders/basepdf.py +50 -0
- flowtask/components/LangchainLoader/loaders/docx.py +91 -0
- flowtask/components/LangchainLoader/loaders/html.py +119 -0
- flowtask/components/LangchainLoader/loaders/pdfblocks.py +146 -0
- flowtask/components/LangchainLoader/loaders/pdfmark.py +79 -0
- flowtask/components/LangchainLoader/loaders/pdftables.py +135 -0
- flowtask/components/LangchainLoader/loaders/qa.py +67 -0
- flowtask/components/LangchainLoader/loaders/txt.py +55 -0
- flowtask/components/LeadIQ.py +650 -0
- flowtask/components/Loop.py +253 -0
- flowtask/components/Lowes.py +334 -0
- flowtask/components/MS365Usage.py +156 -0
- flowtask/components/MSTeamsMessages.py +320 -0
- flowtask/components/MarketClustering.py +1051 -0
- flowtask/components/MergeFiles.py +362 -0
- flowtask/components/MilvusOutput.py +87 -0
- flowtask/components/NearByStores.py +175 -0
- flowtask/components/NetworkNinja/__init__.py +6 -0
- flowtask/components/NetworkNinja/models/__init__.py +52 -0
- flowtask/components/NetworkNinja/models/abstract.py +177 -0
- flowtask/components/NetworkNinja/models/account.py +39 -0
- flowtask/components/NetworkNinja/models/client.py +19 -0
- flowtask/components/NetworkNinja/models/district.py +14 -0
- flowtask/components/NetworkNinja/models/events.py +101 -0
- flowtask/components/NetworkNinja/models/forms.py +499 -0
- flowtask/components/NetworkNinja/models/market.py +16 -0
- flowtask/components/NetworkNinja/models/organization.py +34 -0
- flowtask/components/NetworkNinja/models/photos.py +125 -0
- flowtask/components/NetworkNinja/models/project.py +44 -0
- flowtask/components/NetworkNinja/models/region.py +28 -0
- flowtask/components/NetworkNinja/models/store.py +203 -0
- flowtask/components/NetworkNinja/models/user.py +151 -0
- flowtask/components/NetworkNinja/router.py +854 -0
- flowtask/components/Odoo.py +175 -0
- flowtask/components/OdooInjector.py +192 -0
- flowtask/components/OpenFromXML.py +126 -0
- flowtask/components/OpenWeather.py +41 -0
- flowtask/components/OpenWithBase.py +616 -0
- flowtask/components/OpenWithPandas.py +715 -0
- flowtask/components/PGPDecrypt.py +199 -0
- flowtask/components/PandasIterator.py +187 -0
- flowtask/components/PandasToFile.py +189 -0
- flowtask/components/Paradox.py +339 -0
- flowtask/components/ParamIterator.py +117 -0
- flowtask/components/ParseHTML.py +84 -0
- flowtask/components/PlacerStores.py +249 -0
- flowtask/components/Pokemon.py +507 -0
- flowtask/components/PositiveBot.py +62 -0
- flowtask/components/PowerPointSlide.py +400 -0
- flowtask/components/PrintMessage.py +127 -0
- flowtask/components/ProductCompetitors/__init__.py +5 -0
- flowtask/components/ProductCompetitors/parsers/__init__.py +7 -0
- flowtask/components/ProductCompetitors/parsers/base.py +72 -0
- flowtask/components/ProductCompetitors/parsers/bestbuy.py +86 -0
- flowtask/components/ProductCompetitors/parsers/lowes.py +103 -0
- flowtask/components/ProductCompetitors/scrapper.py +155 -0
- flowtask/components/ProductCompliant.py +169 -0
- flowtask/components/ProductInfo/__init__.py +1 -0
- flowtask/components/ProductInfo/parsers/__init__.py +5 -0
- flowtask/components/ProductInfo/parsers/base.py +83 -0
- flowtask/components/ProductInfo/parsers/brother.py +97 -0
- flowtask/components/ProductInfo/parsers/canon.py +167 -0
- flowtask/components/ProductInfo/parsers/epson.py +118 -0
- flowtask/components/ProductInfo/parsers/hp.py +131 -0
- flowtask/components/ProductInfo/parsers/samsung.py +97 -0
- flowtask/components/ProductInfo/scraper.py +319 -0
- flowtask/components/ProductPricing.py +118 -0
- flowtask/components/QS.py +261 -0
- flowtask/components/QSBase.py +201 -0
- flowtask/components/QueryIterator.py +273 -0
- flowtask/components/QueryToInsert.py +327 -0
- flowtask/components/QueryToPandas.py +432 -0
- flowtask/components/RESTClient.py +195 -0
- flowtask/components/RethinkDBQuery.py +189 -0
- flowtask/components/Rsync.py +74 -0
- flowtask/components/RunSSH.py +59 -0
- flowtask/components/RunShell.py +71 -0
- flowtask/components/SalesForce.py +20 -0
- flowtask/components/SaveImageBank/__init__.py +257 -0
- flowtask/components/SchedulingVisits.py +592 -0
- flowtask/components/ScrapPage.py +216 -0
- flowtask/components/ScrapSearch.py +79 -0
- flowtask/components/SendNotify.py +257 -0
- flowtask/components/SentimentAnalysis.py +694 -0
- flowtask/components/ServiceScrapper/__init__.py +5 -0
- flowtask/components/ServiceScrapper/parsers/__init__.py +1 -0
- flowtask/components/ServiceScrapper/parsers/base.py +94 -0
- flowtask/components/ServiceScrapper/parsers/costco.py +93 -0
- flowtask/components/ServiceScrapper/scrapper.py +199 -0
- flowtask/components/SetVariables.py +156 -0
- flowtask/components/SubTask.py +182 -0
- flowtask/components/SuiteCRM.py +48 -0
- flowtask/components/Switch.py +175 -0
- flowtask/components/TableBase.py +148 -0
- flowtask/components/TableDelete.py +312 -0
- flowtask/components/TableInput.py +143 -0
- flowtask/components/TableOutput/TableOutput.py +384 -0
- flowtask/components/TableOutput/__init__.py +3 -0
- flowtask/components/TableSchema.py +534 -0
- flowtask/components/Target.py +223 -0
- flowtask/components/ThumbnailGenerator.py +156 -0
- flowtask/components/ToPandas.py +67 -0
- flowtask/components/TransformRows/TransformRows.py +507 -0
- flowtask/components/TransformRows/__init__.py +9 -0
- flowtask/components/TransformRows/functions.py +559 -0
- flowtask/components/TransposeRows.py +176 -0
- flowtask/components/UPCDatabase.py +86 -0
- flowtask/components/UnGzip.py +171 -0
- flowtask/components/Uncompress.py +172 -0
- flowtask/components/UniqueRows.py +126 -0
- flowtask/components/Unzip.py +107 -0
- flowtask/components/UpdateOperationalVars.py +147 -0
- flowtask/components/UploadTo.py +299 -0
- flowtask/components/UploadToS3.py +136 -0
- flowtask/components/UploadToSFTP.py +160 -0
- flowtask/components/UploadToSharepoint.py +205 -0
- flowtask/components/UserFunc.py +122 -0
- flowtask/components/VivaTracker.py +140 -0
- flowtask/components/WSDLClient.py +123 -0
- flowtask/components/Wait.py +18 -0
- flowtask/components/Walmart.py +199 -0
- flowtask/components/Workplace.py +134 -0
- flowtask/components/XMLToPandas.py +267 -0
- flowtask/components/Zammad/__init__.py +41 -0
- flowtask/components/Zammad/models.py +0 -0
- flowtask/components/ZoomInfoScraper.py +409 -0
- flowtask/components/__init__.py +104 -0
- flowtask/components/abstract.py +18 -0
- flowtask/components/flow.py +530 -0
- flowtask/components/google.py +335 -0
- flowtask/components/group.py +221 -0
- flowtask/components/py.typed +0 -0
- flowtask/components/reviewscrap.py +132 -0
- flowtask/components/tAutoincrement.py +117 -0
- flowtask/components/tConcat.py +109 -0
- flowtask/components/tExplode.py +119 -0
- flowtask/components/tFilter.py +184 -0
- flowtask/components/tGroup.py +236 -0
- flowtask/components/tJoin.py +270 -0
- flowtask/components/tMap/__init__.py +9 -0
- flowtask/components/tMap/functions.py +54 -0
- flowtask/components/tMap/tMap.py +450 -0
- flowtask/components/tMelt.py +112 -0
- flowtask/components/tMerge.py +114 -0
- flowtask/components/tOrder.py +93 -0
- flowtask/components/tPandas.py +94 -0
- flowtask/components/tPivot.py +71 -0
- flowtask/components/tPluckCols.py +76 -0
- flowtask/components/tUnnest.py +82 -0
- flowtask/components/user.py +401 -0
- flowtask/conf.py +457 -0
- flowtask/download.py +102 -0
- flowtask/events/__init__.py +11 -0
- flowtask/events/events/__init__.py +20 -0
- flowtask/events/events/abstract.py +95 -0
- flowtask/events/events/alerts/__init__.py +362 -0
- flowtask/events/events/alerts/colfunctions.py +131 -0
- flowtask/events/events/alerts/functions.py +158 -0
- flowtask/events/events/dummy.py +12 -0
- flowtask/events/events/exec.py +124 -0
- flowtask/events/events/file/__init__.py +7 -0
- flowtask/events/events/file/base.py +51 -0
- flowtask/events/events/file/copy.py +23 -0
- flowtask/events/events/file/delete.py +16 -0
- flowtask/events/events/interfaces/__init__.py +9 -0
- flowtask/events/events/interfaces/client.py +67 -0
- flowtask/events/events/interfaces/credentials.py +28 -0
- flowtask/events/events/interfaces/notifications.py +58 -0
- flowtask/events/events/jira.py +122 -0
- flowtask/events/events/log.py +26 -0
- flowtask/events/events/logerr.py +52 -0
- flowtask/events/events/notify.py +59 -0
- flowtask/events/events/notify_event.py +160 -0
- flowtask/events/events/publish.py +54 -0
- flowtask/events/events/sendfile.py +104 -0
- flowtask/events/events/task.py +97 -0
- flowtask/events/events/teams.py +98 -0
- flowtask/events/events/webhook.py +58 -0
- flowtask/events/manager.py +287 -0
- flowtask/exceptions.c +39393 -0
- flowtask/exceptions.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/extensions/__init__.py +3 -0
- flowtask/extensions/abstract.py +82 -0
- flowtask/extensions/logging/__init__.py +65 -0
- flowtask/hooks/__init__.py +9 -0
- flowtask/hooks/actions/__init__.py +22 -0
- flowtask/hooks/actions/abstract.py +66 -0
- flowtask/hooks/actions/dummy.py +23 -0
- flowtask/hooks/actions/jira.py +74 -0
- flowtask/hooks/actions/rest.py +320 -0
- flowtask/hooks/actions/sampledata.py +37 -0
- flowtask/hooks/actions/sensor.py +23 -0
- flowtask/hooks/actions/task.py +9 -0
- flowtask/hooks/actions/ticket.py +37 -0
- flowtask/hooks/actions/zammad.py +55 -0
- flowtask/hooks/hook.py +62 -0
- flowtask/hooks/models.py +17 -0
- flowtask/hooks/service.py +187 -0
- flowtask/hooks/step.py +91 -0
- flowtask/hooks/types/__init__.py +23 -0
- flowtask/hooks/types/base.py +129 -0
- flowtask/hooks/types/brokers/__init__.py +11 -0
- flowtask/hooks/types/brokers/base.py +54 -0
- flowtask/hooks/types/brokers/mqtt.py +35 -0
- flowtask/hooks/types/brokers/rabbitmq.py +82 -0
- flowtask/hooks/types/brokers/redis.py +83 -0
- flowtask/hooks/types/brokers/sqs.py +44 -0
- flowtask/hooks/types/fs.py +232 -0
- flowtask/hooks/types/http.py +49 -0
- flowtask/hooks/types/imap.py +200 -0
- flowtask/hooks/types/jira.py +279 -0
- flowtask/hooks/types/mail.py +205 -0
- flowtask/hooks/types/postgres.py +98 -0
- flowtask/hooks/types/responses/__init__.py +8 -0
- flowtask/hooks/types/responses/base.py +5 -0
- flowtask/hooks/types/sharepoint.py +288 -0
- flowtask/hooks/types/ssh.py +141 -0
- flowtask/hooks/types/tagged.py +59 -0
- flowtask/hooks/types/upload.py +85 -0
- flowtask/hooks/types/watch.py +71 -0
- flowtask/hooks/types/web.py +36 -0
- flowtask/interfaces/AzureClient.py +137 -0
- flowtask/interfaces/AzureGraph.py +839 -0
- flowtask/interfaces/Boto3Client.py +326 -0
- flowtask/interfaces/DropboxClient.py +173 -0
- flowtask/interfaces/ExcelHandler.py +94 -0
- flowtask/interfaces/FTPClient.py +131 -0
- flowtask/interfaces/GoogleCalendar.py +201 -0
- flowtask/interfaces/GoogleClient.py +133 -0
- flowtask/interfaces/GoogleDrive.py +127 -0
- flowtask/interfaces/GoogleGCS.py +89 -0
- flowtask/interfaces/GoogleGeocoding.py +93 -0
- flowtask/interfaces/GoogleLang.py +114 -0
- flowtask/interfaces/GooglePub.py +61 -0
- flowtask/interfaces/GoogleSheet.py +68 -0
- flowtask/interfaces/IMAPClient.py +137 -0
- flowtask/interfaces/O365Calendar.py +113 -0
- flowtask/interfaces/O365Client.py +220 -0
- flowtask/interfaces/OneDrive.py +284 -0
- flowtask/interfaces/Outlook.py +155 -0
- flowtask/interfaces/ParrotBot.py +130 -0
- flowtask/interfaces/SSHClient.py +378 -0
- flowtask/interfaces/Sharepoint.py +496 -0
- flowtask/interfaces/__init__.py +36 -0
- flowtask/interfaces/azureauth.py +119 -0
- flowtask/interfaces/cache.py +201 -0
- flowtask/interfaces/client.py +82 -0
- flowtask/interfaces/compress.py +525 -0
- flowtask/interfaces/credentials.py +124 -0
- flowtask/interfaces/d2l.py +239 -0
- flowtask/interfaces/databases/__init__.py +5 -0
- flowtask/interfaces/databases/db.py +223 -0
- flowtask/interfaces/databases/documentdb.py +55 -0
- flowtask/interfaces/databases/rethink.py +39 -0
- flowtask/interfaces/dataframes/__init__.py +11 -0
- flowtask/interfaces/dataframes/abstract.py +21 -0
- flowtask/interfaces/dataframes/arrow.py +71 -0
- flowtask/interfaces/dataframes/dt.py +69 -0
- flowtask/interfaces/dataframes/pandas.py +167 -0
- flowtask/interfaces/dataframes/polars.py +60 -0
- flowtask/interfaces/db.py +263 -0
- flowtask/interfaces/env.py +46 -0
- flowtask/interfaces/func.py +137 -0
- flowtask/interfaces/http.py +1780 -0
- flowtask/interfaces/locale.py +40 -0
- flowtask/interfaces/log.py +75 -0
- flowtask/interfaces/mask.py +143 -0
- flowtask/interfaces/notification.py +154 -0
- flowtask/interfaces/playwright.py +339 -0
- flowtask/interfaces/powerpoint.py +368 -0
- flowtask/interfaces/py.typed +0 -0
- flowtask/interfaces/qs.py +376 -0
- flowtask/interfaces/result.py +87 -0
- flowtask/interfaces/selenium_service.py +779 -0
- flowtask/interfaces/smartsheet.py +154 -0
- flowtask/interfaces/stat.py +39 -0
- flowtask/interfaces/task.py +96 -0
- flowtask/interfaces/template.py +118 -0
- flowtask/interfaces/vectorstores/__init__.py +1 -0
- flowtask/interfaces/vectorstores/abstract.py +133 -0
- flowtask/interfaces/vectorstores/milvus.py +669 -0
- flowtask/interfaces/zammad.py +107 -0
- flowtask/models.py +193 -0
- flowtask/parsers/__init__.py +15 -0
- flowtask/parsers/_yaml.c +11978 -0
- flowtask/parsers/_yaml.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/argparser.py +235 -0
- flowtask/parsers/base.c +15155 -0
- flowtask/parsers/base.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/json.c +11968 -0
- flowtask/parsers/json.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/maps.py +49 -0
- flowtask/parsers/toml.c +11968 -0
- flowtask/parsers/toml.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/plugins/__init__.py +16 -0
- flowtask/plugins/components/__init__.py +0 -0
- flowtask/plugins/handler/__init__.py +45 -0
- flowtask/plugins/importer.py +31 -0
- flowtask/plugins/sources/__init__.py +0 -0
- flowtask/runner.py +283 -0
- flowtask/scheduler/__init__.py +9 -0
- flowtask/scheduler/functions.py +493 -0
- flowtask/scheduler/handlers/__init__.py +8 -0
- flowtask/scheduler/handlers/manager.py +504 -0
- flowtask/scheduler/handlers/models.py +58 -0
- flowtask/scheduler/handlers/service.py +72 -0
- flowtask/scheduler/notifications.py +65 -0
- flowtask/scheduler/scheduler.py +993 -0
- flowtask/services/__init__.py +0 -0
- flowtask/services/bots/__init__.py +0 -0
- flowtask/services/bots/telegram.py +264 -0
- flowtask/services/files/__init__.py +11 -0
- flowtask/services/files/manager.py +522 -0
- flowtask/services/files/model.py +37 -0
- flowtask/services/files/service.py +767 -0
- flowtask/services/jira/__init__.py +3 -0
- flowtask/services/jira/jira_actions.py +191 -0
- flowtask/services/tasks/__init__.py +13 -0
- flowtask/services/tasks/launcher.py +213 -0
- flowtask/services/tasks/manager.py +323 -0
- flowtask/services/tasks/service.py +275 -0
- flowtask/services/tasks/task_manager.py +376 -0
- flowtask/services/tasks/tasks.py +155 -0
- flowtask/storages/__init__.py +16 -0
- flowtask/storages/exceptions.py +12 -0
- flowtask/storages/files/__init__.py +8 -0
- flowtask/storages/files/abstract.py +29 -0
- flowtask/storages/files/filesystem.py +66 -0
- flowtask/storages/tasks/__init__.py +19 -0
- flowtask/storages/tasks/abstract.py +26 -0
- flowtask/storages/tasks/database.py +33 -0
- flowtask/storages/tasks/filesystem.py +108 -0
- flowtask/storages/tasks/github.py +119 -0
- flowtask/storages/tasks/memory.py +45 -0
- flowtask/storages/tasks/row.py +25 -0
- flowtask/tasks/__init__.py +0 -0
- flowtask/tasks/abstract.py +526 -0
- flowtask/tasks/command.py +118 -0
- flowtask/tasks/pile.py +486 -0
- flowtask/tasks/py.typed +0 -0
- flowtask/tasks/task.py +778 -0
- flowtask/template/__init__.py +161 -0
- flowtask/tests.py +257 -0
- flowtask/types/__init__.py +8 -0
- flowtask/types/typedefs.c +11347 -0
- flowtask/types/typedefs.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/utils/__init__.py +24 -0
- flowtask/utils/constants.py +117 -0
- flowtask/utils/encoders.py +21 -0
- flowtask/utils/executor.py +112 -0
- flowtask/utils/functions.cpp +14280 -0
- flowtask/utils/functions.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/utils/json.cpp +13349 -0
- flowtask/utils/json.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/utils/mail.py +63 -0
- flowtask/utils/parseqs.c +13324 -0
- flowtask/utils/parserqs.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/utils/stats.py +308 -0
- flowtask/utils/transformations.py +74 -0
- flowtask/utils/uv.py +12 -0
- flowtask/utils/validators.py +97 -0
- flowtask/version.py +11 -0
- flowtask-5.8.4.dist-info/LICENSE +201 -0
- flowtask-5.8.4.dist-info/METADATA +209 -0
- flowtask-5.8.4.dist-info/RECORD +470 -0
- flowtask-5.8.4.dist-info/WHEEL +6 -0
- flowtask-5.8.4.dist-info/entry_points.txt +3 -0
- flowtask-5.8.4.dist-info/top_level.txt +2 -0
- plugins/components/CreateQR.py +39 -0
- plugins/components/TestComponent.py +28 -0
- plugins/components/Use1.py +13 -0
- plugins/components/Workplace.py +117 -0
- plugins/components/__init__.py +3 -0
- plugins/sources/__init__.py +0 -0
- plugins/sources/get_populartimes.py +78 -0
- plugins/sources/google.py +150 -0
- plugins/sources/hubspot.py +679 -0
- plugins/sources/icims.py +679 -0
- plugins/sources/mobileinsight.py +501 -0
- plugins/sources/newrelic.py +262 -0
- plugins/sources/uap.py +268 -0
- plugins/sources/venu.py +244 -0
- plugins/sources/vocinity.py +314 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
import asyncio
|
2
|
+
from collections.abc import Callable
|
3
|
+
import pandas as pd
|
4
|
+
from ..exceptions import ComponentError, DataNotFound, TaskError
|
5
|
+
from .flow import FlowComponent
|
6
|
+
from ..interfaces import DBSupport
|
7
|
+
|
8
|
+
|
9
|
+
class tAutoincrement(DBSupport, FlowComponent):
|
10
|
+
"""
|
11
|
+
tAutoincrement
|
12
|
+
|
13
|
+
Overview
|
14
|
+
|
15
|
+
The `tAutoincrement` component is designed to automatically increment values in a specific column of a dataset.
|
16
|
+
This is particularly useful when you need to fill in missing (null) values in a column with unique, sequential
|
17
|
+
integers starting from the maximum value currently present in the column.
|
18
|
+
|
19
|
+
Properties
|
20
|
+
|
21
|
+
.. table:: Properties
|
22
|
+
:widths: auto
|
23
|
+
|
24
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
25
|
+
| Name | Required | Type | Description |
|
26
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
27
|
+
| datasource | Yes | str | The datasource name (e.g., schema name) where the dataset is located. |
|
28
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
29
|
+
| dataset | Yes | str | The name of the dataset (e.g., table name) to work on. |
|
30
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
31
|
+
| column | Yes | str | The name of the column in which values will be auto-incremented. |
|
32
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
33
|
+
|
34
|
+
Return
|
35
|
+
|
36
|
+
Returns the dataframe with the given column and its auto-incremented sequence.
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
Example:
|
41
|
+
|
42
|
+
```yaml
|
43
|
+
tAutoincrement:
|
44
|
+
skipError: skip
|
45
|
+
datasource: pokemon
|
46
|
+
dataset: districts
|
47
|
+
column: district_id
|
48
|
+
description: Auto-increment district_id for new districts
|
49
|
+
```
|
50
|
+
|
51
|
+
""" # noqa
|
52
|
+
|
53
|
+
def __init__(
|
54
|
+
self,
|
55
|
+
loop: asyncio.AbstractEventLoop = None,
|
56
|
+
job: Callable = None,
|
57
|
+
stat: Callable = None,
|
58
|
+
**kwargs,
|
59
|
+
) -> None:
|
60
|
+
"""Init Method."""
|
61
|
+
self.datasource: str = None
|
62
|
+
self.dataset: str = None
|
63
|
+
self.column: str = None
|
64
|
+
self.pd_args = kwargs.pop("pd_args", {})
|
65
|
+
super(tAutoincrement, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
|
66
|
+
|
67
|
+
async def start(self, **kwargs):
|
68
|
+
"""Start method."""
|
69
|
+
if not self.datasource:
|
70
|
+
raise TaskError("Missing *datasource* parameter.")
|
71
|
+
if not self.dataset:
|
72
|
+
raise TaskError("Missing *dataset* parameter.")
|
73
|
+
if not self.column:
|
74
|
+
raise TaskError("Missing *column* parameter.")
|
75
|
+
|
76
|
+
# Set the DataFrame if provided via kwargs
|
77
|
+
self.data = kwargs.get('data', None)
|
78
|
+
if self.data is None and hasattr(self, 'previous'):
|
79
|
+
self.data = self.previous.output()
|
80
|
+
|
81
|
+
if self.data is None:
|
82
|
+
raise ComponentError(
|
83
|
+
"No input DataFrame provided to tAutoincrement component."
|
84
|
+
)
|
85
|
+
await super().start(**kwargs)
|
86
|
+
self.processing_credentials()
|
87
|
+
return True
|
88
|
+
|
89
|
+
async def run(self):
|
90
|
+
"""Run method to fetch the max value and auto-increment."""
|
91
|
+
# Establishing the connection
|
92
|
+
self.connection = self.pg_connection()
|
93
|
+
try:
|
94
|
+
async with await self.connection.connection() as conn:
|
95
|
+
query = f"SELECT MAX({self.column}) as alias_column FROM {self.datasource}.{self.dataset};"
|
96
|
+
result = await conn.fetchval(query)
|
97
|
+
if result is None:
|
98
|
+
result = 0
|
99
|
+
self._logger.info(f"Executing query: {query} MAX: {result}")
|
100
|
+
# Incrementing and assigning the values to null columns
|
101
|
+
if self.data.empty:
|
102
|
+
raise DataNotFound("Input DataFrame is empty.")
|
103
|
+
|
104
|
+
mask = self.data[self.column].isnull()
|
105
|
+
self.data.loc[mask, self.column] = range(result + 1, result + 1 + mask.sum())
|
106
|
+
self._result = self.data
|
107
|
+
|
108
|
+
except Exception as ex:
|
109
|
+
raise ComponentError(f"Error in tAutoincrement: {str(ex)}") from ex
|
110
|
+
|
111
|
+
finally:
|
112
|
+
self.connection = None
|
113
|
+
|
114
|
+
return True
|
115
|
+
|
116
|
+
async def close(self):
|
117
|
+
pass
|
@@ -0,0 +1,109 @@
|
|
1
|
+
import asyncio
|
2
|
+
from typing import Any
|
3
|
+
from collections.abc import Callable
|
4
|
+
import pandas
|
5
|
+
from ..exceptions import ComponentError, DataNotFound
|
6
|
+
from .flow import FlowComponent
|
7
|
+
|
8
|
+
|
9
|
+
class tConcat(FlowComponent):
|
10
|
+
"""
|
11
|
+
tConcat
|
12
|
+
|
13
|
+
Overview
|
14
|
+
|
15
|
+
The tConcat class is a component for merging (concatenating) two DataFrames along a specified axis.
|
16
|
+
It supports handling multiple DataFrames and configurable options for the concatenation, with metrics
|
17
|
+
tracking for input and output row counts.
|
18
|
+
|
19
|
+
.. table:: Properties
|
20
|
+
:widths: auto
|
21
|
+
|
22
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
23
|
+
| Name | Required | Summary |
|
24
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
25
|
+
| df1 | Yes | The first DataFrame to concatenate. |
|
26
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
27
|
+
| df2 | Yes | The second DataFrame to concatenate. |
|
28
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
29
|
+
| args | No | Dictionary of arguments to pass to `pandas.concat`, such as `axis`. |
|
30
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
31
|
+
|
32
|
+
Returns
|
33
|
+
|
34
|
+
This component returns a concatenated DataFrame based on the specified axis and additional arguments.
|
35
|
+
Metrics are recorded for the row counts of both input DataFrames and the final concatenated DataFrame.
|
36
|
+
If either DataFrame is missing or empty, an error is raised with a descriptive message.
|
37
|
+
|
38
|
+
|
39
|
+
Example:
|
40
|
+
|
41
|
+
```yaml
|
42
|
+
tConcat:
|
43
|
+
depends:
|
44
|
+
- TransformRows_8
|
45
|
+
- TransformRows_15
|
46
|
+
args:
|
47
|
+
axis: 0
|
48
|
+
```
|
49
|
+
|
50
|
+
""" # noqa
|
51
|
+
|
52
|
+
def __init__(
|
53
|
+
self,
|
54
|
+
loop: asyncio.AbstractEventLoop = None,
|
55
|
+
job: Callable = None,
|
56
|
+
stat: Callable = None,
|
57
|
+
**kwargs,
|
58
|
+
):
|
59
|
+
"""Init Method."""
|
60
|
+
self.df1: Any = None
|
61
|
+
self.df2: Any = None
|
62
|
+
self.type = None
|
63
|
+
super(tConcat, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
|
64
|
+
|
65
|
+
async def start(self, **kwargs):
|
66
|
+
"""Obtain Pandas Dataframe.
|
67
|
+
TODO: iterate over all dataframes.
|
68
|
+
"""
|
69
|
+
if self._multi:
|
70
|
+
self.df1 = self.previous[0].output()
|
71
|
+
self.df2 = self.previous[1].output()
|
72
|
+
return True
|
73
|
+
|
74
|
+
async def run(self):
|
75
|
+
args = {}
|
76
|
+
if self.df1.empty:
|
77
|
+
raise DataNotFound("Data Was Not Found on Dataframe 1")
|
78
|
+
elif self.df2 is None or self.df2.empty:
|
79
|
+
raise DataNotFound("Data Was Not Found on Dataframe 2")
|
80
|
+
if hasattr(self, "args") and isinstance(self.args, dict):
|
81
|
+
args = {**args, **self.args}
|
82
|
+
if "axis" not in args:
|
83
|
+
args["axis"] = 1
|
84
|
+
# Adding Metrics:
|
85
|
+
_left = len(self.df1.index)
|
86
|
+
self.add_metric("LEFT: ", _left)
|
87
|
+
_right = len(self.df2.index)
|
88
|
+
self.add_metric("RIGHT: ", _right)
|
89
|
+
# Concat two dataframes
|
90
|
+
try:
|
91
|
+
df = pandas.concat([self.df1, self.df2], **args)
|
92
|
+
except Exception as err:
|
93
|
+
raise ComponentError(
|
94
|
+
f"Error Merging Dataframes: {err}"
|
95
|
+
) from err
|
96
|
+
numrows = len(df.index)
|
97
|
+
if numrows == 0:
|
98
|
+
raise DataNotFound(
|
99
|
+
"Concat: Cannot make any Merge"
|
100
|
+
)
|
101
|
+
self._variables[f"{self.StepName}_NUMROWS"] = numrows
|
102
|
+
self.add_metric("JOINED: ", numrows)
|
103
|
+
df.is_copy = None
|
104
|
+
print(df)
|
105
|
+
self._result = df
|
106
|
+
return self._result
|
107
|
+
|
108
|
+
async def close(self):
|
109
|
+
pass
|
@@ -0,0 +1,119 @@
|
|
1
|
+
import asyncio
|
2
|
+
from typing import Any
|
3
|
+
from collections.abc import Callable
|
4
|
+
import pandas
|
5
|
+
from pandas import json_normalize
|
6
|
+
from ..exceptions import ComponentError, DataNotFound
|
7
|
+
from .flow import FlowComponent
|
8
|
+
|
9
|
+
|
10
|
+
class tExplode(FlowComponent):
|
11
|
+
"""
|
12
|
+
tExplode
|
13
|
+
|
14
|
+
Overview
|
15
|
+
|
16
|
+
The tExplode class is a component for transforming a DataFrame by converting a column of lists or dictionaries
|
17
|
+
into multiple rows. It supports options for dropping the original column after exploding, and for expanding
|
18
|
+
nested dictionary structures into separate columns.
|
19
|
+
|
20
|
+
.. table:: Properties
|
21
|
+
:widths: auto
|
22
|
+
|
23
|
+
+----------------+----------+-----------+-------------------------------------------------------------------------------+
|
24
|
+
| Name | Required | Summary |
|
25
|
+
+----------------+----------+-----------+-------------------------------------------------------------------------------+
|
26
|
+
| column | Yes | The name of the column to explode into multiple rows. |
|
27
|
+
+----------------+----------+-----------+-------------------------------------------------------------------------------+
|
28
|
+
| drop_original | No | Boolean indicating if the original column should be dropped after exploding. |
|
29
|
+
+----------------+----------+-----------+-------------------------------------------------------------------------------+
|
30
|
+
| explode_dataset| No | Boolean specifying if nested dictionaries in the column should be expanded as new columns.|
|
31
|
+
+----------------+----------+-----------+-------------------------------------------------------------------------------+
|
32
|
+
|
33
|
+
Returns
|
34
|
+
|
35
|
+
This component returns a DataFrame with the specified column exploded into multiple rows. If `explode_dataset` is
|
36
|
+
set to True and the column contains dictionaries, these are expanded into new columns. Metrics on the row count
|
37
|
+
after explosion are recorded, and any errors encountered during processing are logged and raised as exceptions.
|
38
|
+
|
39
|
+
|
40
|
+
Example:
|
41
|
+
|
42
|
+
```yaml
|
43
|
+
tExplode:
|
44
|
+
column: reviews
|
45
|
+
drop_original: false
|
46
|
+
```
|
47
|
+
|
48
|
+
""" # noqa
|
49
|
+
|
50
|
+
def __init__(
|
51
|
+
self,
|
52
|
+
loop: asyncio.AbstractEventLoop = None,
|
53
|
+
job: Callable = None,
|
54
|
+
stat: Callable = None,
|
55
|
+
**kwargs,
|
56
|
+
):
|
57
|
+
"""Init Method."""
|
58
|
+
self.data: Any = None
|
59
|
+
# Column to be exploded
|
60
|
+
self.column: str = kwargs.pop("column", None)
|
61
|
+
self.drop_original: bool = kwargs.pop("drop_original", False)
|
62
|
+
# Useful when exploded column is also composed of dictionary, the dictionary
|
63
|
+
# is also exploded as columns
|
64
|
+
self.explode_dataset: bool = kwargs.pop("explode_dataset", True)
|
65
|
+
super(tExplode, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
|
66
|
+
|
67
|
+
async def start(self, **kwargs):
|
68
|
+
# Si lo que llega no es un DataFrame de Pandas se cancela la tarea
|
69
|
+
if self.previous:
|
70
|
+
self.data = self.input
|
71
|
+
else:
|
72
|
+
raise ComponentError("Data Not Found", status=404)
|
73
|
+
if not isinstance(self.data, pandas.DataFrame):
|
74
|
+
raise ComponentError("Incompatible Pandas Dataframe", status=404)
|
75
|
+
return True
|
76
|
+
|
77
|
+
async def run(self):
|
78
|
+
args = {}
|
79
|
+
if self.data.empty:
|
80
|
+
raise DataNotFound("Data Was Not Found on Dataframe 1")
|
81
|
+
|
82
|
+
# Explode the Rows:
|
83
|
+
try:
|
84
|
+
# Step 1: Explode the 'field' column
|
85
|
+
exploded_df = self.data.explode(self.column)
|
86
|
+
# Reset index to ensure it's unique
|
87
|
+
exploded_df = exploded_df.reset_index(drop=True)
|
88
|
+
if self.explode_dataset is True:
|
89
|
+
# Step 2: Normalize the JSON data in 'exploded' col
|
90
|
+
# This will create a new DataFrame where each dictionary key becomes a column
|
91
|
+
data_df = json_normalize(exploded_df[self.column])
|
92
|
+
# Step 3: Concatenate with the original DataFrame
|
93
|
+
# Drop the original column from exploded_df and join with data_df
|
94
|
+
if self.drop_original is True:
|
95
|
+
exploded_df.drop(self.column, axis=1)
|
96
|
+
df = pandas.concat([exploded_df, data_df], axis=1)
|
97
|
+
else:
|
98
|
+
df = exploded_df
|
99
|
+
except Exception as err:
|
100
|
+
raise ComponentError(f"Error Merging Dataframes: {err}") from err
|
101
|
+
numrows = len(df.index)
|
102
|
+
if numrows == 0:
|
103
|
+
raise DataNotFound("Concat: Cannot make any Explode")
|
104
|
+
if hasattr(self, "index"):
|
105
|
+
df[self.index] = df["id"]
|
106
|
+
df.drop("id", axis="columns", inplace=True)
|
107
|
+
self._variables[f"{self.StepName}_NUMROWS"] = numrows
|
108
|
+
self.add_metric("EXPLODE: ", numrows)
|
109
|
+
df.is_copy = None
|
110
|
+
print(df)
|
111
|
+
self._result = df
|
112
|
+
if self._debug is True:
|
113
|
+
print("::: Printing Column Information === ")
|
114
|
+
for column, t in df.dtypes.items():
|
115
|
+
print(column, "->", t, "->", df[column].iloc[0])
|
116
|
+
return self._result
|
117
|
+
|
118
|
+
async def close(self):
|
119
|
+
pass
|
@@ -0,0 +1,184 @@
|
|
1
|
+
import asyncio
|
2
|
+
from collections.abc import Callable
|
3
|
+
import re
|
4
|
+
import pandas as pd
|
5
|
+
import numpy as np
|
6
|
+
from querysource.types.dt import filters as qsffunctions
|
7
|
+
from querysource.queries.multi.operators.filter.flt import (
|
8
|
+
create_filter,
|
9
|
+
valid_operators
|
10
|
+
)
|
11
|
+
from .FilterRows import functions as dffunctions
|
12
|
+
# create_filter
|
13
|
+
from ..exceptions import (
|
14
|
+
ConfigError,
|
15
|
+
ComponentError,
|
16
|
+
DataNotFound
|
17
|
+
)
|
18
|
+
from .flow import FlowComponent
|
19
|
+
|
20
|
+
|
21
|
+
class tFilter(FlowComponent):
|
22
|
+
"""
|
23
|
+
tFilter
|
24
|
+
|
25
|
+
Overview
|
26
|
+
|
27
|
+
The tFilter class is a component that applies specified filters to a Pandas DataFrame.
|
28
|
+
It allows filtering rows based on multiple conditions and expressions, enabling targeted
|
29
|
+
data extraction within a task flow.
|
30
|
+
|
31
|
+
.. table:: Properties
|
32
|
+
:widths: auto
|
33
|
+
|
34
|
+
+--------------+----------+-----------+---------------------------------------------------------------+
|
35
|
+
| Name | Required | Summary |
|
36
|
+
+--------------+----------+-----------+---------------------------------------------------------------+
|
37
|
+
| operator | Yes | Logical operator (e.g., `and`, `or`) used to combine filter conditions. |
|
38
|
+
+--------------+----------+-----------+---------------------------------------------------------------+
|
39
|
+
| conditions | Yes | List of conditions with columns, values, and expressions for filtering. |
|
40
|
+
| | | Format: `{ "column": <col_name>, "value": <val>, "expression": <expr> }` |
|
41
|
+
+--------------+----------+-----------+---------------------------------------------------------------+
|
42
|
+
|
43
|
+
Returns
|
44
|
+
|
45
|
+
This component returns a filtered Pandas DataFrame based on the provided conditions.
|
46
|
+
The component tracks metrics
|
47
|
+
such as the initial and filtered row counts, and optionally limits the returned columns if specified.
|
48
|
+
Additional debugging information can be outputted based on configuration.
|
49
|
+
|
50
|
+
|
51
|
+
Example:
|
52
|
+
|
53
|
+
```yaml
|
54
|
+
tFilter:
|
55
|
+
operator: '&'
|
56
|
+
filter:
|
57
|
+
- column: ClientId
|
58
|
+
value:
|
59
|
+
- 11076
|
60
|
+
expression: ==
|
61
|
+
```
|
62
|
+
|
63
|
+
""" # noqa
|
64
|
+
|
65
|
+
def __init__(
|
66
|
+
self,
|
67
|
+
loop: asyncio.AbstractEventLoop = None,
|
68
|
+
job: Callable = None,
|
69
|
+
stat: Callable = None,
|
70
|
+
**kwargs,
|
71
|
+
):
|
72
|
+
"""Init Method."""
|
73
|
+
self.condition: str = ""
|
74
|
+
self.fields: dict = kwargs.pop('fields', {})
|
75
|
+
self.operator = kwargs.pop('operator', '&')
|
76
|
+
self.filter = kwargs.pop('filter', [])
|
77
|
+
self.filter_conditions: dict = {}
|
78
|
+
super(tFilter, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
|
79
|
+
|
80
|
+
async def start(self, **kwargs):
|
81
|
+
# Si lo que llega no es un DataFrame de Pandas se cancela la tarea
|
82
|
+
if self.previous:
|
83
|
+
self.data = self.input
|
84
|
+
else:
|
85
|
+
raise ComponentError("Data Not Found")
|
86
|
+
if not isinstance(self.data, pd.DataFrame):
|
87
|
+
raise ComponentError("Incompatible Pandas Dataframe")
|
88
|
+
return True
|
89
|
+
|
90
|
+
async def close(self):
|
91
|
+
pass
|
92
|
+
|
93
|
+
def _filter_conditions(self, df: pd.DataFrame) -> pd.DataFrame:
|
94
|
+
it = df.copy()
|
95
|
+
for ft, args in self.filter_conditions.items():
|
96
|
+
self._applied.append(f"Filter: {ft!s} args: {args}")
|
97
|
+
try:
|
98
|
+
try:
|
99
|
+
func = getattr(qsffunctions, ft)
|
100
|
+
except AttributeError:
|
101
|
+
try:
|
102
|
+
func = getattr(dffunctions, ft)
|
103
|
+
except AttributeError:
|
104
|
+
func = globals()[ft]
|
105
|
+
if callable(func):
|
106
|
+
it = func(it, **args)
|
107
|
+
except Exception as err:
|
108
|
+
print(f"Error on {ft}: {err}")
|
109
|
+
df = it
|
110
|
+
if df is None or df.empty:
|
111
|
+
raise DataNotFound(
|
112
|
+
"No Data was Found after Filtering."
|
113
|
+
)
|
114
|
+
return df
|
115
|
+
|
116
|
+
def _filter_fields(self, df: pd.DataFrame) -> pd.DataFrame:
|
117
|
+
for column, value in self.fields.items():
|
118
|
+
if column in df.columns:
|
119
|
+
if isinstance(value, list):
|
120
|
+
for v in value:
|
121
|
+
df = df[df[column] == v]
|
122
|
+
else:
|
123
|
+
df = df[df[column] == value]
|
124
|
+
return df
|
125
|
+
|
126
|
+
async def run(self):
|
127
|
+
self.add_metric("STARTED_ROWS", len(self.data.index))
|
128
|
+
df = self.data.copy()
|
129
|
+
# iterate over all filtering conditions:
|
130
|
+
df = self._filter_conditions(df)
|
131
|
+
# Applying filter expressions by Column:
|
132
|
+
if self.fields:
|
133
|
+
df = self._filter_fields()
|
134
|
+
if self.filter:
|
135
|
+
# conditions = self._create_filter()
|
136
|
+
conditions = create_filter(self.filter, df)
|
137
|
+
# Joining all conditions
|
138
|
+
self.condition = f" {self.operator} ".join(conditions)
|
139
|
+
self._logger.notice(
|
140
|
+
f"Filter conditions >> {self.condition}"
|
141
|
+
)
|
142
|
+
df = df.loc[
|
143
|
+
eval(self.condition)
|
144
|
+
] # pylint: disable=W0123
|
145
|
+
if df is None or df.empty:
|
146
|
+
raise DataNotFound(
|
147
|
+
"No Data was Found after Filtering."
|
148
|
+
)
|
149
|
+
self._result = df
|
150
|
+
# print(": Filtered : ")
|
151
|
+
# print(self._result)
|
152
|
+
self.add_metric(
|
153
|
+
"FILTERED_ROWS", len(self._result.index)
|
154
|
+
)
|
155
|
+
# Calculate the rejected rows between self.data and df dataframe:
|
156
|
+
self.add_metric(
|
157
|
+
"REJECTED_ROWS", len(self.data.index) - len(self._result.index)
|
158
|
+
)
|
159
|
+
if hasattr(self, "save_rejected"):
|
160
|
+
# Identify the indices of the rows that were removed
|
161
|
+
removed_indices = set(self.data.index) - set(self._result.index)
|
162
|
+
# Select these rows from the original DataFrame
|
163
|
+
rejected = self.data.loc[list(removed_indices)]
|
164
|
+
filename = self.mask_replacement(
|
165
|
+
self.save_rejected.get("filename", "rejected_rows.csv")
|
166
|
+
)
|
167
|
+
try:
|
168
|
+
rejected.to_csv(filename, sep="|")
|
169
|
+
except IOError:
|
170
|
+
self._logger.warning(f"Error writing Rejectd File: {filename}")
|
171
|
+
self.add_metric(
|
172
|
+
"rejected_file", filename
|
173
|
+
)
|
174
|
+
if hasattr(self, "columns"):
|
175
|
+
# returning only a subset of data
|
176
|
+
self._result = self._result[self.columns]
|
177
|
+
if self._debug is True:
|
178
|
+
print("::: Printing Column Information === ")
|
179
|
+
for column, t in self._result.dtypes.items():
|
180
|
+
print(column, "->", t, "->", self._result[column].iloc[0])
|
181
|
+
self.add_metric(
|
182
|
+
"FILTERED_COLS", len(self._result.columns)
|
183
|
+
)
|
184
|
+
return self._result
|