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 @@
|
|
1
|
+
from .costco import CostcoScrapper
|
@@ -0,0 +1,94 @@
|
|
1
|
+
import asyncio
|
2
|
+
from typing import Any, List, Dict
|
3
|
+
from abc import abstractmethod
|
4
|
+
import pandas as pd
|
5
|
+
from bs4 import BeautifulSoup as bs
|
6
|
+
from selenium.webdriver.common.by import By
|
7
|
+
from selenium.webdriver.support import expected_conditions as EC
|
8
|
+
from selenium.webdriver.support.ui import WebDriverWait
|
9
|
+
from selenium.common.exceptions import (
|
10
|
+
TimeoutException,
|
11
|
+
NoSuchElementException,
|
12
|
+
WebDriverException
|
13
|
+
)
|
14
|
+
from ....interfaces import SeleniumService, HTTPService
|
15
|
+
import re
|
16
|
+
import logging
|
17
|
+
|
18
|
+
class ScrapperBase(SeleniumService, HTTPService):
|
19
|
+
"""
|
20
|
+
ScrapperBase Model.
|
21
|
+
|
22
|
+
|
23
|
+
Define how scrappers should be work.-
|
24
|
+
"""
|
25
|
+
url: str = ''
|
26
|
+
domain: str = ''
|
27
|
+
cookies: Any
|
28
|
+
expected_columns: List[str] = []
|
29
|
+
|
30
|
+
def __init__(self, *args, **kwargs):
|
31
|
+
self._driver = None
|
32
|
+
self.cookies = kwargs.get('cookies', None)
|
33
|
+
self._logger = logging.getLogger(self.__class__.__name__)
|
34
|
+
self._counter: int = 0
|
35
|
+
self.search_term_used: str = ''
|
36
|
+
self.url = kwargs.get('url', self.url)
|
37
|
+
self.use_proxy = True
|
38
|
+
self._free_proxy = False
|
39
|
+
super().__init__(*args, **kwargs)
|
40
|
+
|
41
|
+
def get_bs(self, response: object) -> Any:
|
42
|
+
if isinstance(response, str):
|
43
|
+
return bs(response, 'html.parser')
|
44
|
+
return bs(response.text, 'html.parser')
|
45
|
+
|
46
|
+
async def get(self, url: str, headers: dict = None):
|
47
|
+
try:
|
48
|
+
try:
|
49
|
+
await asyncio.sleep(1)
|
50
|
+
await self.get_page(url=url)
|
51
|
+
# Driver Wait until body is available:
|
52
|
+
# WebDriverWait(self._driver, 10).until(
|
53
|
+
# EC.presence_of_element_located((By.TAG_NAME, 'body'))
|
54
|
+
# )
|
55
|
+
return self._driver.page_source
|
56
|
+
except TimeoutException:
|
57
|
+
return None
|
58
|
+
except Exception as err:
|
59
|
+
self._logger.error(f'Error getting page: {err}')
|
60
|
+
return None
|
61
|
+
|
62
|
+
async def get_http(self, url, headers: dict = None):
|
63
|
+
return await self._get(url, headers=headers, use_proxy=True)
|
64
|
+
|
65
|
+
async def start(self):
|
66
|
+
"""Starts de Navigation to Main Site.
|
67
|
+
"""
|
68
|
+
if self.url:
|
69
|
+
response = await self.get(self.url)
|
70
|
+
return response
|
71
|
+
return True
|
72
|
+
|
73
|
+
def set_columns(self, df: pd.DataFrame) -> None:
|
74
|
+
for col in self.expected_columns:
|
75
|
+
if col not in df.columns:
|
76
|
+
df[col] = None
|
77
|
+
|
78
|
+
@abstractmethod
|
79
|
+
async def connect(self):
|
80
|
+
"""Creates the Driver and Connects to the Site.
|
81
|
+
"""
|
82
|
+
|
83
|
+
@abstractmethod
|
84
|
+
async def disconnect(self):
|
85
|
+
"""Disconnects the Driver and closes the Connection.
|
86
|
+
"""
|
87
|
+
|
88
|
+
# Context Manager:
|
89
|
+
async def __aenter__(self):
|
90
|
+
await self.connect()
|
91
|
+
return self
|
92
|
+
|
93
|
+
async def __aexit__(self, exc_type, exc_value, traceback):
|
94
|
+
await self.disconnect()
|
@@ -0,0 +1,93 @@
|
|
1
|
+
from .base import ScrapperBase
|
2
|
+
|
3
|
+
|
4
|
+
class CostcoScrapper(ScrapperBase):
|
5
|
+
domain: str = 'costco.com'
|
6
|
+
|
7
|
+
def __init__(self, *args, **kwargs):
|
8
|
+
super().__init__(*args, **kwargs)
|
9
|
+
self.expected_columns = [
|
10
|
+
'brand_name',
|
11
|
+
'brand_image',
|
12
|
+
'short_name',
|
13
|
+
'brand_description',
|
14
|
+
]
|
15
|
+
# self.url: str = 'https://www.costco.com/special-events.html'
|
16
|
+
self.url: str = None
|
17
|
+
self.use_proxy = True
|
18
|
+
self.us_proxy = True
|
19
|
+
self._free_proxy = False
|
20
|
+
# self.use_edge = True
|
21
|
+
# self.use_firefox = True
|
22
|
+
self.headless = False
|
23
|
+
self.use_wire = False
|
24
|
+
# self._browser_binary = '/opt/google/chrome/chrome'
|
25
|
+
# self._driver_binary = '/home/jesuslara/.cache/selenium/geckodriver/linux64/0.33.0/geckodriver'
|
26
|
+
|
27
|
+
async def connect(self):
|
28
|
+
"""Creates the Driver and Connects to the Site.
|
29
|
+
"""
|
30
|
+
self._driver = await self.get_driver()
|
31
|
+
await self.start()
|
32
|
+
|
33
|
+
async def disconnect(self):
|
34
|
+
"""Disconnects the Driver and closes the Connection.
|
35
|
+
"""
|
36
|
+
if self._driver:
|
37
|
+
self.close_driver()
|
38
|
+
|
39
|
+
async def special_events(self, response: object, idx: int, row: dict) -> tuple:
|
40
|
+
"""
|
41
|
+
Get the special events from Costco.
|
42
|
+
"""
|
43
|
+
try:
|
44
|
+
document = self.get_bs(response)
|
45
|
+
category_header = document.find('div', {'id': 'category-name-header'})
|
46
|
+
print('category_header > ', category_header)
|
47
|
+
return idx, row
|
48
|
+
except Exception as err:
|
49
|
+
self._logger.error(f'Error getting special events from Costco: {err}')
|
50
|
+
return None
|
51
|
+
|
52
|
+
async def product_information(self, response: object, idx: int, row: dict) -> tuple:
|
53
|
+
"""
|
54
|
+
Get the product information from Costco.
|
55
|
+
"""
|
56
|
+
try:
|
57
|
+
document = self.get_bs(response)
|
58
|
+
search_results_div = document.find('div', {'id': 'search-results'})
|
59
|
+
if search_results_div:
|
60
|
+
# 1. Get the brand name: find the <div> with class "search-results-tile", then the first <h1>
|
61
|
+
search_results_tile = search_results_div.find('div', class_="search-results-tile")
|
62
|
+
brand_name = None
|
63
|
+
if search_results_tile:
|
64
|
+
h1_tag = search_results_tile.find('h1')
|
65
|
+
if h1_tag:
|
66
|
+
brand_name = h1_tag.get_text(strip=True)
|
67
|
+
row['brand_name'] = brand_name
|
68
|
+
# 2. Get the brand image: find the <div> with class "dual-row", then find the <img> with class "img-responsive"
|
69
|
+
dual_row_div = search_results_div.find('div', class_="dual-row")
|
70
|
+
brand_image = None
|
71
|
+
if dual_row_div:
|
72
|
+
img_tag = dual_row_div.find('img', class_="img-responsive")
|
73
|
+
if img_tag and img_tag.has_attr('src'):
|
74
|
+
brand_image = img_tag['src']
|
75
|
+
row['brand_image'] = brand_image
|
76
|
+
# 3. Get the brand description: find the <div> with class "sp-event-product-copy" then its first <p>
|
77
|
+
copy_div = search_results_div.find('div', class_="sp-event-product-copy")
|
78
|
+
brand_description = None
|
79
|
+
if copy_div:
|
80
|
+
p_tag = copy_div.find('p')
|
81
|
+
if p_tag:
|
82
|
+
brand_description = p_tag.get_text(strip=True)
|
83
|
+
row['brand_description'] = brand_description
|
84
|
+
# 4. Get the short name: find the <div> with class "search-results-tile",
|
85
|
+
_div = search_results_div.find('div', class_="sp-event-product-title")
|
86
|
+
short_name = None
|
87
|
+
if _div:
|
88
|
+
short_name = _div.get_text(strip=True)
|
89
|
+
row['short_name'] = short_name
|
90
|
+
return idx, row
|
91
|
+
except Exception as err:
|
92
|
+
self._logger.error(f'Error getting product information from Costco: {err}')
|
93
|
+
return None
|
@@ -0,0 +1,199 @@
|
|
1
|
+
from collections.abc import Callable
|
2
|
+
import asyncio
|
3
|
+
import random
|
4
|
+
import httpx
|
5
|
+
import pandas as pd
|
6
|
+
from tqdm.asyncio import tqdm
|
7
|
+
from bs4 import BeautifulSoup
|
8
|
+
from ...exceptions import ComponentError, ConfigError
|
9
|
+
from ...interfaces import HTTPService, SeleniumService
|
10
|
+
from ...interfaces.http import ua
|
11
|
+
from ..flow import FlowComponent
|
12
|
+
from .parsers import (
|
13
|
+
CostcoScrapper,
|
14
|
+
)
|
15
|
+
|
16
|
+
|
17
|
+
class ServiceScrapper(FlowComponent, SeleniumService, HTTPService):
|
18
|
+
"""
|
19
|
+
Service Scraper Component
|
20
|
+
|
21
|
+
Overview:
|
22
|
+
|
23
|
+
Pluggable component for scrapping several services and sites using different scrapers.
|
24
|
+
|
25
|
+
.. table:: Properties
|
26
|
+
:widths: auto
|
27
|
+
|
28
|
+
+-----------------------+----------+------------------------------------------------------------------------------------------------------+
|
29
|
+
| Name | Required | Description |
|
30
|
+
+-----------------------+----------+------------------------------------------------------------------------------------------------------+
|
31
|
+
| url_column (str) | Yes | Name of the column containing URLs to scrape (default: 'search_url') |
|
32
|
+
+-----------------------+----------+------------------------------------------------------------------------------------------------------+
|
33
|
+
| wait_for (tuple) | No | Element to wait for before scraping (default: ('class', 'company-overview')) |
|
34
|
+
+-----------------------+----------+------------------------------------------------------------------------------------------------------+
|
35
|
+
|
36
|
+
Return:
|
37
|
+
- DataFrame with company information
|
38
|
+
""" # noqa: E501
|
39
|
+
|
40
|
+
def __init__(
|
41
|
+
self,
|
42
|
+
loop: asyncio.AbstractEventLoop = None,
|
43
|
+
job: Callable = None,
|
44
|
+
stat: Callable = None,
|
45
|
+
**kwargs,
|
46
|
+
) -> None:
|
47
|
+
self.info_column: str = kwargs.get('column_name', 'url')
|
48
|
+
self.scrapper_name: str = kwargs.get('scrapper', ['costco'])
|
49
|
+
self.scrapper_class: Callable = None
|
50
|
+
self._scrapper_func: str = kwargs.get('function', 'special_events')
|
51
|
+
self.wait_for: tuple = kwargs.get('wait_for', ('class', 'company-overview'))
|
52
|
+
self._counter: int = 0
|
53
|
+
self.use_proxy: bool = True
|
54
|
+
self._free_proxy: bool = False
|
55
|
+
self.paid_proxy: bool = True
|
56
|
+
self.chunk_size: int = kwargs.get('chunk_size', 100)
|
57
|
+
self.concurrently: bool = kwargs.get('concurrently', False)
|
58
|
+
self.task_parts: int = kwargs.get('task_parts', 10)
|
59
|
+
super().__init__(loop=loop, job=job, stat=stat, **kwargs)
|
60
|
+
# Headers configuration
|
61
|
+
self.headers: dict = {
|
62
|
+
"Accept": self.accept,
|
63
|
+
"TE": "trailers",
|
64
|
+
"Accept-Encoding": "gzip, deflate",
|
65
|
+
"DNT": "1",
|
66
|
+
"Connection": "keep-alive",
|
67
|
+
"Upgrade-Insecure-Requests": "1",
|
68
|
+
"User-Agent": random.choice(ua),
|
69
|
+
**kwargs.get('headers', {})
|
70
|
+
}
|
71
|
+
self._free_proxy = False
|
72
|
+
|
73
|
+
def split_parts(self, task_list, num_parts: int = 5) -> list:
|
74
|
+
part_size, remainder = divmod(len(task_list), num_parts)
|
75
|
+
parts = []
|
76
|
+
start = 0
|
77
|
+
for i in range(num_parts):
|
78
|
+
# Distribute the remainder across the first `remainder` parts
|
79
|
+
end = start + part_size + (1 if i < remainder else 0)
|
80
|
+
parts.append(task_list[start:end])
|
81
|
+
start = end
|
82
|
+
return parts
|
83
|
+
|
84
|
+
async def _processing_tasks(self, tasks: list) -> pd.DataFrame:
|
85
|
+
"""Process tasks concurrently."""
|
86
|
+
results = []
|
87
|
+
total_tasks = len(tasks)
|
88
|
+
# Overall progress bar
|
89
|
+
with tqdm(total=total_tasks, desc="Scraping Progress", unit="task") as pbar_total:
|
90
|
+
if self.concurrently is False:
|
91
|
+
# run every task in a sequential manner:
|
92
|
+
for task in tasks:
|
93
|
+
try:
|
94
|
+
idx, row = await task
|
95
|
+
results.append((idx, row)) # Append as tuple (idx, row)
|
96
|
+
await asyncio.sleep(
|
97
|
+
random.uniform(0.25, 1.5)
|
98
|
+
)
|
99
|
+
except Exception as e:
|
100
|
+
self._logger.error(f"Task error: {str(e)}")
|
101
|
+
results.append((idx, row)) # Store the failure result
|
102
|
+
finally:
|
103
|
+
pbar_total.update(1)
|
104
|
+
else:
|
105
|
+
for chunk in self.split_parts(tasks, self.task_parts):
|
106
|
+
result = await asyncio.gather(*chunk, return_exceptions=False)
|
107
|
+
results.extend(result)
|
108
|
+
# Convert results to DataFrame
|
109
|
+
if not results:
|
110
|
+
return pd.DataFrame()
|
111
|
+
|
112
|
+
indices, data_dicts = zip(*results) if results else ([], [])
|
113
|
+
df = pd.DataFrame(data_dicts, index=indices)
|
114
|
+
return df
|
115
|
+
|
116
|
+
async def start(self, **kwargs) -> bool:
|
117
|
+
"""Initialize the component and validate required parameters."""
|
118
|
+
if self.previous:
|
119
|
+
self.data = self.input
|
120
|
+
|
121
|
+
if not isinstance(self.data, pd.DataFrame):
|
122
|
+
raise ComponentError(
|
123
|
+
"Input must be a DataFrame", status=404
|
124
|
+
)
|
125
|
+
|
126
|
+
if self.info_column not in self.data.columns:
|
127
|
+
raise ConfigError(
|
128
|
+
f"Column {self.info_column} not found in DataFrame"
|
129
|
+
)
|
130
|
+
|
131
|
+
return True
|
132
|
+
|
133
|
+
async def _start_scrapping(self, idx, row):
|
134
|
+
try:
|
135
|
+
async with self._semaphore:
|
136
|
+
url = row[self.info_column]
|
137
|
+
self._logger.debug(
|
138
|
+
f"Scraping URL: {url}"
|
139
|
+
)
|
140
|
+
async with self.scrapper_class as scrapper:
|
141
|
+
response = await scrapper.get(url, headers=self.headers)
|
142
|
+
if response:
|
143
|
+
try:
|
144
|
+
fn = getattr(scrapper, self._scrapper_func, 'scrapping')
|
145
|
+
idx, row = await fn(response, idx, row)
|
146
|
+
except Exception as err:
|
147
|
+
print(' Exception caught > ', err)
|
148
|
+
return idx, row
|
149
|
+
return idx, row
|
150
|
+
except Exception as err:
|
151
|
+
print(' Exception caught > ', err)
|
152
|
+
raise ComponentError(
|
153
|
+
f"Error while scrapping: {err}"
|
154
|
+
)
|
155
|
+
|
156
|
+
def _get_scrapper(self):
|
157
|
+
"""Get the scrapper class."""
|
158
|
+
try:
|
159
|
+
if self.scrapper_name == 'costco':
|
160
|
+
return CostcoScrapper()
|
161
|
+
else:
|
162
|
+
return None
|
163
|
+
except Exception as err:
|
164
|
+
print(err)
|
165
|
+
raise ConfigError(
|
166
|
+
f"Error while getting scrapper: {err}"
|
167
|
+
)
|
168
|
+
|
169
|
+
async def run(self):
|
170
|
+
"""Execute scraping for requested URL in the DataFrame."""
|
171
|
+
# function that import the specified scrapper
|
172
|
+
try:
|
173
|
+
self.scrapper_class = self._get_scrapper()
|
174
|
+
except Exception as err:
|
175
|
+
raise ConfigError(
|
176
|
+
f"Error while getting scrapper: {err}"
|
177
|
+
)
|
178
|
+
httpx_cookies = self.get_httpx_cookies(
|
179
|
+
domain=self.scrapper_class.domain, cookies=self.cookies
|
180
|
+
)
|
181
|
+
self.scrapper_class.cookies = httpx_cookies
|
182
|
+
self.scrapper_class.set_columns(self.data)
|
183
|
+
if not self.scrapper_class:
|
184
|
+
raise ConfigError(
|
185
|
+
"No valid scrapper were found or provided in configuration"
|
186
|
+
)
|
187
|
+
tasks = [
|
188
|
+
self._start_scrapping(
|
189
|
+
idx, row
|
190
|
+
) for idx, row in self.data.iterrows()
|
191
|
+
]
|
192
|
+
df = await self._processing_tasks(tasks)
|
193
|
+
self._result = df
|
194
|
+
self._print_data_(self._result, 'Scrapper Results')
|
195
|
+
return self._result
|
196
|
+
|
197
|
+
async def close(self):
|
198
|
+
"""Clean up resources."""
|
199
|
+
return True
|
@@ -0,0 +1,156 @@
|
|
1
|
+
import asyncio
|
2
|
+
from typing import Callable
|
3
|
+
from dateutil import parser
|
4
|
+
import pandas as pd
|
5
|
+
from ..exceptions import ComponentError
|
6
|
+
from .flow import FlowComponent
|
7
|
+
from ..utils.executor import getFunction
|
8
|
+
|
9
|
+
|
10
|
+
class SetVariables(FlowComponent):
|
11
|
+
"""
|
12
|
+
SetVariables
|
13
|
+
|
14
|
+
Overview
|
15
|
+
|
16
|
+
The SetVariables class is a component for extracting values from data and setting them as variables
|
17
|
+
for use in other components. This component can set variables based on specific column values in
|
18
|
+
a DataFrame or by executing functions, with support for date formatting and value aggregation.
|
19
|
+
|
20
|
+
.. table:: Properties
|
21
|
+
:widths: auto
|
22
|
+
|
23
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
24
|
+
| Name | Required | Summary |
|
25
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
26
|
+
| vars | Yes | Dictionary defining variables to set with options for format, |
|
27
|
+
| | | row selection, and data sources. |
|
28
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
29
|
+
|
30
|
+
Returns
|
31
|
+
|
32
|
+
This component returns the original data after setting variables based on the `vars` dictionary.
|
33
|
+
Each variable is created from a specified column or function, and supports formatting options
|
34
|
+
such as date, timestamp, epoch, or custom string formatting. Metrics are recorded for each variable
|
35
|
+
set, and any issues with variable definitions or data retrieval raise a descriptive `ComponentError`.
|
36
|
+
|
37
|
+
|
38
|
+
Example:
|
39
|
+
|
40
|
+
```yaml
|
41
|
+
SetVariables:
|
42
|
+
vars:
|
43
|
+
max_date:
|
44
|
+
- order_date
|
45
|
+
- row: max
|
46
|
+
min_date:
|
47
|
+
- order_date
|
48
|
+
- row: min
|
49
|
+
```
|
50
|
+
|
51
|
+
"""
|
52
|
+
|
53
|
+
data = None
|
54
|
+
|
55
|
+
def __init__(
|
56
|
+
self,
|
57
|
+
loop: asyncio.AbstractEventLoop = None,
|
58
|
+
job: Callable = None,
|
59
|
+
stat: Callable = None,
|
60
|
+
**kwargs,
|
61
|
+
):
|
62
|
+
"""Init Method."""
|
63
|
+
super(SetVariables, self).__init__(
|
64
|
+
loop=loop,
|
65
|
+
job=job,
|
66
|
+
stat=stat,
|
67
|
+
**kwargs
|
68
|
+
)
|
69
|
+
|
70
|
+
async def start(self, **kwargs):
|
71
|
+
if self.previous:
|
72
|
+
self.data = self.input
|
73
|
+
|
74
|
+
def close(self):
|
75
|
+
pass
|
76
|
+
|
77
|
+
async def run(self):
|
78
|
+
if hasattr(self, "vars"):
|
79
|
+
for var, params in self.vars.items():
|
80
|
+
variable = ""
|
81
|
+
fname = ""
|
82
|
+
try:
|
83
|
+
fname = params[0]
|
84
|
+
except (KeyError, IndexError, ValueError) as err:
|
85
|
+
raise ComponentError(
|
86
|
+
f"Error Getting the variable definition: {err}"
|
87
|
+
) from err
|
88
|
+
try:
|
89
|
+
fmt = params[1]["format"]
|
90
|
+
except (KeyError, IndexError, ValueError):
|
91
|
+
fmt = None
|
92
|
+
# Si existe una columna llamada fname en el dataframe se saca de ahí
|
93
|
+
if isinstance(self.data, pd.DataFrame) and fname in self.data.columns:
|
94
|
+
try:
|
95
|
+
try:
|
96
|
+
row = params[1]["row"]
|
97
|
+
except Exception:
|
98
|
+
row = 0
|
99
|
+
if isinstance(row, int):
|
100
|
+
variable = self.data.iloc[row][fname]
|
101
|
+
elif row == "min":
|
102
|
+
variable = self.data[fname].min()
|
103
|
+
elif row == "max":
|
104
|
+
variable = self.data[fname].max()
|
105
|
+
elif row == "array":
|
106
|
+
variable = self.data[fname].unique().tolist()
|
107
|
+
if fmt is not None:
|
108
|
+
# apply Format
|
109
|
+
if fmt == "date":
|
110
|
+
# convert to a date:
|
111
|
+
_var = parser.parse(str(variable))
|
112
|
+
variable = _var.strftime("%Y-%m-%d")
|
113
|
+
elif fmt == "timestamp":
|
114
|
+
_var = parser.parse(str(variable))
|
115
|
+
variable = _var.strftime("%Y-%m-%d %H:%M:%S")
|
116
|
+
elif fmt == "epoch":
|
117
|
+
_var = parser.parse(str(variable))
|
118
|
+
variable = _var.strftime("%s")
|
119
|
+
else:
|
120
|
+
try:
|
121
|
+
_var = parser.parse(variable)
|
122
|
+
variable = _var.strftime(fmt)
|
123
|
+
except (parser.ParserError, Exception):
|
124
|
+
# f-string formatting:
|
125
|
+
variable = f"{variable:fmt}"
|
126
|
+
except Exception as err:
|
127
|
+
print('E ', err)
|
128
|
+
raise ComponentError(
|
129
|
+
f"Error Getting the variable definition: {err}"
|
130
|
+
) from err
|
131
|
+
# Si no existe se saca de una función
|
132
|
+
else:
|
133
|
+
try:
|
134
|
+
func = getFunction(fname)
|
135
|
+
if callable(func):
|
136
|
+
try:
|
137
|
+
args = params[1]
|
138
|
+
variable = func(**args)
|
139
|
+
except (KeyError, IndexError, ValueError):
|
140
|
+
variable = func()
|
141
|
+
if fmt is not None:
|
142
|
+
print("VAR ", variable)
|
143
|
+
except Exception as err:
|
144
|
+
raise ComponentError(
|
145
|
+
f"Error Getting the variable definition: {err}"
|
146
|
+
) from err
|
147
|
+
self.add_metric(
|
148
|
+
f"{self.StepName}_{var!s}", variable
|
149
|
+
)
|
150
|
+
self._variables[f"{self.StepName}_{var}"] = variable
|
151
|
+
self._logger.debug(
|
152
|
+
f"Set Variable: {self.StepName}_{var} to {variable!s}"
|
153
|
+
)
|
154
|
+
print("VAR: ", f"{self.StepName}_{var}", variable)
|
155
|
+
self._result = self.data
|
156
|
+
return self._result
|