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,223 @@
|
|
1
|
+
"""
|
2
|
+
Scrapping a Web Page Using Selenium + ChromeDriver + BeautifulSoup.
|
3
|
+
"""
|
4
|
+
import asyncio
|
5
|
+
from collections.abc import Callable
|
6
|
+
import random
|
7
|
+
import httpx
|
8
|
+
import pandas as pd
|
9
|
+
import backoff
|
10
|
+
# Internals
|
11
|
+
from ..exceptions import (
|
12
|
+
ComponentError,
|
13
|
+
ConfigError,
|
14
|
+
NotSupported
|
15
|
+
)
|
16
|
+
from ..interfaces.http import ua
|
17
|
+
from .reviewscrap import ReviewScrapper, bad_gateway_exception
|
18
|
+
|
19
|
+
|
20
|
+
class Target(ReviewScrapper):
|
21
|
+
"""Target.
|
22
|
+
|
23
|
+
Combining API Key and Web Scrapping, this component will be able to extract
|
24
|
+
TARGET Information (reviews, etc).
|
25
|
+
"""
|
26
|
+
def __init__(
|
27
|
+
self,
|
28
|
+
loop: asyncio.AbstractEventLoop = None,
|
29
|
+
job: Callable = None,
|
30
|
+
stat: Callable = None,
|
31
|
+
**kwargs,
|
32
|
+
):
|
33
|
+
self._fn = kwargs.pop('type', None)
|
34
|
+
self.chunk_size: int = kwargs.get('chunk_size', 100)
|
35
|
+
self.task_parts: int = kwargs.get('task_parts', 10)
|
36
|
+
self.product_info: bool = kwargs.get('product_info', False)
|
37
|
+
if not self._fn:
|
38
|
+
raise ConfigError(
|
39
|
+
"BestBuy: require a `type` Function to be called, ex: availability"
|
40
|
+
)
|
41
|
+
super(Target, self).__init__(
|
42
|
+
loop=loop,
|
43
|
+
job=job,
|
44
|
+
stat=stat,
|
45
|
+
**kwargs
|
46
|
+
)
|
47
|
+
# Always use proxies:
|
48
|
+
self.use_proxy: bool = True
|
49
|
+
self._free_proxy: bool = False
|
50
|
+
self.cookies = {
|
51
|
+
"Sid": "WcMH6IPyatK95shr5A-IWjsGf-qeWLo_",
|
52
|
+
"UserLocation": "45510|40.050|-4.210|TO|ES",
|
53
|
+
"__eoi": "ID=9528bd272a92431a:T=1736552136:RT=1736554579:S=AA-AfjZSTuM0txUk7Lsy-pJtCFok",
|
54
|
+
"accessToken": "eyJraWQiOiJlYXMyIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiI4M2JkOGI3NC0xYjA2LTRkMjQtOTA1Yi1iNTdjNWMwODg4ZGMiLCJpc3MiOiJNSTYiLCJleHAiOjE3MzY2Mzg1MzYsImlhdCI6MTczNjU1MjEzNiwianRpIjoiVEdULmU3MmZkNmQzMzM1OTQ4NzJhOWNiYTQ4NzY1OTc1NTA1LWwiLCJza3kiOiJlYXMyIiwic3V0IjoiRyIsImRpZCI6ImZjZGEzYmE4MGJmMmU3YmMxY2E1NDgxNzk3MjM1MzVkMDRmOGRlYTE5YzRiZjJmNWQ1NGJmNjQyNjY1NTEzZTciLCJzY28iOiJlY29tLm5vbmUsb3BlbmlkIiwiY2xpIjoiZWNvbS13ZWItMS4wLjAiLCJhc2wiOiJMIn0.DBH4-I6n69roAHnMrp9P1mYWEuGDyvIZR8EeR2nM3SDuVeiLs679E76XXyh4x7A5jnnjFKuaTcaNkEQy40J3eiNbtOkk-897OkqVP6ElCn8NB9ShTFKGvuBdpQy9H-qwieD5DUre_1UE94fIS2-U04WTl1rBs5Glrd1wsd5e4ajLvLH5pVfYyFg1o00b-B-CRn7Q68GzZ1V-MKt_gf-pXZH8nhMq7SCqRCooeSXGiGwuG78OfujIKVHxHgCwBO9nQzvxQ1y4eaDgXc9zzSpgZQ_fGSz9t_Jeuz4UgUbZwyStH9KYHUHYIu6TnqlEIPNuO2NbqJBLOP6wJFezQKN7iA",
|
55
|
+
"adScriptData": "TO",
|
56
|
+
"crl8.fpcuid": "c2aa8017-a2e2-4d24-a61e-2093551bb881",
|
57
|
+
"egsSessionId": "ffbc34de-8a71-4eeb-9490-6382040b0124",
|
58
|
+
"ffsession": "{%22sessionHash%22:%224a74f57be4bb61736552136688%22}",
|
59
|
+
"fiatsCookie": "DSI_1092|DSN_Beechmont%20Area|DSZ_45255",
|
60
|
+
"idToken": "eyJhbGciOiJub25lIn0.eyJzdWIiOiI4M2JkOGI3NC0xYjA2LTRkMjQtOTA1Yi1iNTdjNWMwODg4ZGMiLCJpc3MiOiJNSTYiLCJleHAiOjE3MzY2Mzg1MzYsImlhdCI6MTczNjU1MjEzNiwiYXNzIjoiTCIsInN1dCI6IkciLCJjbGkiOiJlY29tLXdlYi0xLjAuMCIsInBybyI6eyJmbiI6bnVsbCwiZW0iOm51bGwsInBoIjpmYWxzZSwibGVkIjpudWxsLCJsdHkiOmZhbHNlLCJzdCI6IlRPIn19.",
|
61
|
+
"refreshToken": "GQHHnolvR5mW5lY6C9BbK1XbpFSE3F_yFwtKjSUCJOaikGHKg5Ju0eyjhRlm9NmaYegjQuxPnVSv1kh75Y1VOg",
|
62
|
+
"sapphire": "1",
|
63
|
+
"visitorId": "01945292BA770201AEAA83A7E83DE4E9",
|
64
|
+
"kampyleSessionPageCounter": "6",
|
65
|
+
"kampyleUserSession": "1736552137812",
|
66
|
+
"kampyleUserSessionsCount": "4",
|
67
|
+
"mdLogger": "false",
|
68
|
+
}
|
69
|
+
self.headers: dict = {
|
70
|
+
"Accept": "application/json",
|
71
|
+
"Accept-Encoding": "gzip, deflate, br, zstd",
|
72
|
+
"Accept-Language": "es-US,es;q=0.9,en-US;q=0.8,en;q=0.7,es-419;q=0.6",
|
73
|
+
"Origin": "https://www.target.com",
|
74
|
+
"Referer": "https://www.target.com/p/",
|
75
|
+
"Sec-CH-UA": '"Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132"',
|
76
|
+
"Sec-CH-UA-Mobile": "?0",
|
77
|
+
"Sec-CH-UA-Platform": '"Linux"',
|
78
|
+
"Sec-Fetch-Dest": "empty",
|
79
|
+
"Sec-Fetch-Mode": "cors",
|
80
|
+
"Sec-Fetch-Site": "same-site",
|
81
|
+
"User-Agent": random.choice(ua),
|
82
|
+
}
|
83
|
+
self.semaphore = asyncio.Semaphore(10)
|
84
|
+
|
85
|
+
async def close(self, **kwargs) -> bool:
|
86
|
+
self.close_driver()
|
87
|
+
return True
|
88
|
+
|
89
|
+
async def start(self, **kwargs) -> bool:
|
90
|
+
await super(Target, self).start(**kwargs)
|
91
|
+
if self.previous:
|
92
|
+
self.data = self.input
|
93
|
+
if not isinstance(self.data, pd.DataFrame):
|
94
|
+
raise ComponentError(
|
95
|
+
"Incompatible Pandas Dataframe"
|
96
|
+
)
|
97
|
+
self.api_token = self.get_env_value(self.api_token) if hasattr(self, 'api_token') else self.get_env_value('TARGET_API_KEY') # noqa
|
98
|
+
if not hasattr(self, self._fn):
|
99
|
+
raise ConfigError(
|
100
|
+
f"BestBuy: Unable to found Function {self._fn} in Target Component."
|
101
|
+
)
|
102
|
+
|
103
|
+
@backoff.on_exception(
|
104
|
+
backoff.expo,
|
105
|
+
(httpx.ConnectTimeout, httpx.HTTPStatusError),
|
106
|
+
max_tries=2,
|
107
|
+
giveup=lambda e: not bad_gateway_exception(e) and not isinstance(e, httpx.ConnectTimeout)
|
108
|
+
)
|
109
|
+
async def _product_reviews(self, idx, row, cookies):
|
110
|
+
async with self.semaphore:
|
111
|
+
# Prepare payload for the API request
|
112
|
+
sku = row['sku']
|
113
|
+
pagesize = 20
|
114
|
+
max_pages = 2 # Maximum number of pages to fetch
|
115
|
+
current_page = 0
|
116
|
+
all_reviews = []
|
117
|
+
total_reviews = 0
|
118
|
+
try:
|
119
|
+
while current_page <= max_pages:
|
120
|
+
payload = {
|
121
|
+
"key": "c6b68aaef0eac4df4931aae70500b7056531cb37", # Ensure this key is valid and authorized
|
122
|
+
"hasOnlyPhotos": "false",
|
123
|
+
"includes": "reviews,reviewsWithPhotos,entities,metadata,statistics",
|
124
|
+
"page": current_page,
|
125
|
+
"entity": "",
|
126
|
+
"reviewedId": sku, # Ensure sku corresponds to 'reviewedId'
|
127
|
+
"reviewType": "PRODUCT",
|
128
|
+
"size": pagesize,
|
129
|
+
"sortBy": "most_recent",
|
130
|
+
"verifiedOnly": "false",
|
131
|
+
}
|
132
|
+
url = "https://r2d2.target.com/ggc/v2/summary"
|
133
|
+
result = await self.api_get(
|
134
|
+
url=url,
|
135
|
+
cookies=cookies,
|
136
|
+
params=payload,
|
137
|
+
headers=self.headers
|
138
|
+
)
|
139
|
+
total_reviews = result.get('statistics', {}).get('review_count', 0)
|
140
|
+
if not result:
|
141
|
+
self._logger.warning(
|
142
|
+
f"No Product Reviews found for {sku}."
|
143
|
+
)
|
144
|
+
break
|
145
|
+
# Extract the reviews data from the API response
|
146
|
+
reviews_section = result.get('reviews', {})
|
147
|
+
items = reviews_section.get('results', [])
|
148
|
+
if len(items) == 0:
|
149
|
+
break
|
150
|
+
all_reviews.extend(items)
|
151
|
+
# Determine if we've reached the last page
|
152
|
+
total_pages = reviews_section.get('total_pages', max_pages)
|
153
|
+
if current_page >= total_pages:
|
154
|
+
break
|
155
|
+
current_page += 1 # Move to the next page
|
156
|
+
except (httpx.TimeoutException, httpx.HTTPError) as ex:
|
157
|
+
self._logger.warning(f"Request failed: {ex}")
|
158
|
+
return []
|
159
|
+
except Exception as ex:
|
160
|
+
self._logger.error(f"An error occurred: {ex}")
|
161
|
+
return []
|
162
|
+
|
163
|
+
# Extract the reviews data from the API response
|
164
|
+
reviews = []
|
165
|
+
for item in all_reviews:
|
166
|
+
# Exclude certain keys
|
167
|
+
filtered_item = {
|
168
|
+
k: v for k, v in item.items()
|
169
|
+
if k not in ('photos', 'Badges', 'entities', 'tags', 'reviewer_attributes')
|
170
|
+
}
|
171
|
+
# Combine with original row data
|
172
|
+
review_data = row.to_dict()
|
173
|
+
review_data['total_reviews'] = total_reviews
|
174
|
+
review_data.update(filtered_item)
|
175
|
+
reviews.append(review_data)
|
176
|
+
self._logger.info(
|
177
|
+
f"Fetched {len(reviews)} reviews for SKU {sku}."
|
178
|
+
)
|
179
|
+
return reviews
|
180
|
+
|
181
|
+
async def reviews(self):
|
182
|
+
"""reviews.
|
183
|
+
|
184
|
+
Target Product Reviews.
|
185
|
+
"""
|
186
|
+
httpx_cookies = httpx.Cookies()
|
187
|
+
for key, value in self.cookies.items():
|
188
|
+
httpx_cookies.set(
|
189
|
+
key, value,
|
190
|
+
domain='.target.com',
|
191
|
+
path='/'
|
192
|
+
)
|
193
|
+
|
194
|
+
# Iterate over each row in the DataFrame
|
195
|
+
print('starting ...')
|
196
|
+
|
197
|
+
tasks = [
|
198
|
+
self._product_reviews(
|
199
|
+
idx,
|
200
|
+
row,
|
201
|
+
httpx_cookies
|
202
|
+
) for idx, row in self.data.iterrows()
|
203
|
+
]
|
204
|
+
# Gather results concurrently
|
205
|
+
all_reviews_nested = await self._processing_tasks(tasks)
|
206
|
+
|
207
|
+
# Flatten the list of lists
|
208
|
+
all_reviews = [review for reviews in all_reviews_nested for review in reviews]
|
209
|
+
|
210
|
+
# Convert to DataFrame
|
211
|
+
reviews_df = pd.DataFrame(all_reviews)
|
212
|
+
|
213
|
+
# show the num of rows in final dataframe:
|
214
|
+
self._logger.notice(
|
215
|
+
f"Ending Product Reviews: {len(reviews_df)}"
|
216
|
+
)
|
217
|
+
|
218
|
+
# Override previous dataframe:
|
219
|
+
reviews_df.rename(columns={"text": "review", "Rating": "rating"})
|
220
|
+
self.data = reviews_df
|
221
|
+
|
222
|
+
# return existing data
|
223
|
+
return self.data
|
@@ -0,0 +1,156 @@
|
|
1
|
+
from typing import Callable
|
2
|
+
import asyncio
|
3
|
+
import os
|
4
|
+
from pathlib import Path
|
5
|
+
import aiofiles
|
6
|
+
from io import BytesIO
|
7
|
+
import pyheif
|
8
|
+
from PIL import Image, UnidentifiedImageError
|
9
|
+
import filetype
|
10
|
+
import pandas as pd
|
11
|
+
from .flow import FlowComponent
|
12
|
+
|
13
|
+
|
14
|
+
class ThumbnailGenerator(FlowComponent):
|
15
|
+
"""
|
16
|
+
ThumbnailGenerator.
|
17
|
+
|
18
|
+
Overview
|
19
|
+
This component generates thumbnails for images stored in a DataFrame. It takes an image column, resizes the images
|
20
|
+
to a specified size, and saves them in a specified directory with a given filename format. The generated thumbnail
|
21
|
+
paths are added to a new column in the DataFrame.
|
22
|
+
.. table:: Properties
|
23
|
+
:widths: auto
|
24
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
25
|
+
| Name | Required | Summary |
|
26
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
27
|
+
| data_column | Yes | The name of the column containing the image data. |
|
28
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
29
|
+
| thumbnail_column| Yes | The name of the column to store the generated thumbnail paths. |
|
30
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
31
|
+
| size | Yes | The size of the thumbnail. Can be a tuple (width, height) or a single |
|
32
|
+
| | | integer for a square thumbnail. |
|
33
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
34
|
+
| format | Yes | The format of the thumbnail (e.g., 'JPEG', 'PNG'). |
|
35
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
36
|
+
| directory | Yes | The directory where the thumbnails will be saved. |
|
37
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
38
|
+
| filename | Yes | The filename template for the thumbnails. It can include placeholders |
|
39
|
+
| | for DataFrame columns (e.g., '{column_name}.jpg'). |
|
40
|
+
+----------------+----------+-----------+---------------------------------------------------------------+
|
41
|
+
Returns
|
42
|
+
This component returns a DataFrame with a new column containing the paths of the generated thumbnails.
|
43
|
+
Example:
|
44
|
+
```
|
45
|
+
- ThumbnailGenerator:
|
46
|
+
data_column: image
|
47
|
+
thumbnail_column: thumbnail
|
48
|
+
size: (128, 128)
|
49
|
+
format: JPEG
|
50
|
+
directory: /path/to/thumbnails
|
51
|
+
filename: thumbnail_{id}.jpg
|
52
|
+
```
|
53
|
+
""" # noqa: E501
|
54
|
+
def __init__(
|
55
|
+
self,
|
56
|
+
loop: asyncio.AbstractEventLoop = None,
|
57
|
+
job: Callable = None,
|
58
|
+
stat: Callable = None,
|
59
|
+
**kwargs,
|
60
|
+
):
|
61
|
+
self.data_column = kwargs.pop("data_column", None)
|
62
|
+
self.thumbnail_column = kwargs.pop("thumbnail_column", 'thumbnail')
|
63
|
+
if not self.data_column:
|
64
|
+
raise ValueError("data_column must be specified.")
|
65
|
+
self.size = kwargs.pop("size", (128, 128))
|
66
|
+
self.size = self.size if isinstance(self.size, tuple) else (self.size, self.size)
|
67
|
+
self.image_format = kwargs.pop("format", "JPEG").upper()
|
68
|
+
self.directory = kwargs.pop("directory", "./thumbnails")
|
69
|
+
self.filename_template = kwargs.pop("filename", "thumbnail_{id}.jpg")
|
70
|
+
super(ThumbnailGenerator, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
|
71
|
+
self._semaphore = asyncio.Semaphore(10) # Adjust the limit as needed
|
72
|
+
|
73
|
+
async def start(self, **kwargs) -> bool:
|
74
|
+
if self.previous:
|
75
|
+
self.data = self.input
|
76
|
+
if isinstance(self.directory, str):
|
77
|
+
self.directory = Path(self.directory).resolve()
|
78
|
+
# check if directory exists
|
79
|
+
if self.directory.exists() and not self.directory.is_dir():
|
80
|
+
raise ValueError(f"{self.directory} is not a directory.")
|
81
|
+
if not self.directory.exists():
|
82
|
+
self.directory.mkdir(parents=True, exist_ok=True)
|
83
|
+
return True
|
84
|
+
|
85
|
+
async def close(self):
|
86
|
+
return True
|
87
|
+
|
88
|
+
async def run(self) -> pd.DataFrame:
|
89
|
+
# check for duplicates
|
90
|
+
async def handle(idx):
|
91
|
+
async with self._semaphore:
|
92
|
+
row = self.data.loc[idx].to_dict()
|
93
|
+
file_obj = row[self.data_column]
|
94
|
+
if not file_obj:
|
95
|
+
self.logger.error(f"Row {idx}: No file object found.")
|
96
|
+
return None
|
97
|
+
stream = file_obj.getvalue() if isinstance(file_obj, BytesIO) else file_obj
|
98
|
+
# Detect MIME type first
|
99
|
+
kind = filetype.guess(stream)
|
100
|
+
if kind is None:
|
101
|
+
self.logger.error(
|
102
|
+
f"Row {idx}: Cannot detect MIME type. Please check the file, skipping"
|
103
|
+
)
|
104
|
+
return None
|
105
|
+
self.logger.info(
|
106
|
+
f"Row {idx}: Detected MIME type: {kind.mime}"
|
107
|
+
)
|
108
|
+
filename = self.filename_template.format(**row)
|
109
|
+
filename = self.mask_replacement(filename)
|
110
|
+
filepath = self.directory.joinpath(filename)
|
111
|
+
try:
|
112
|
+
if kind == 'image/heic':
|
113
|
+
try:
|
114
|
+
i = pyheif.read_heif(stream)
|
115
|
+
image = Image.frombytes(mode=i.mode, size=i.size, data=i.data)
|
116
|
+
except Exception as e:
|
117
|
+
self._logger.error(
|
118
|
+
f"Unable to parse Apple Heic Photo at row {row}"
|
119
|
+
)
|
120
|
+
return None
|
121
|
+
else:
|
122
|
+
image = Image.open(BytesIO(stream))
|
123
|
+
image.thumbnail(self.size)
|
124
|
+
# Set the thumbnail path in the DataFrame
|
125
|
+
self.data.at[idx, self.thumbnail_column] = str(filepath)
|
126
|
+
# check if file exists
|
127
|
+
if filepath.exists():
|
128
|
+
return filepath
|
129
|
+
image.save(filepath, self.image_format)
|
130
|
+
except UnidentifiedImageError:
|
131
|
+
self._logger.error(
|
132
|
+
f"Row {idx}: PIL cannot identify image file. MIME: {kind.mime}"
|
133
|
+
)
|
134
|
+
bad_folder = self.directory.joinpath('bad_images')
|
135
|
+
if not bad_folder.exists():
|
136
|
+
bad_folder.mkdir(parents=True, exist_ok=True)
|
137
|
+
try:
|
138
|
+
# Save bad file into disk:
|
139
|
+
bad_file = bad_folder.joinpath(filename)
|
140
|
+
async with aiofiles.open(bad_file, "wb") as fp:
|
141
|
+
await fp.write(stream)
|
142
|
+
except Exception as e:
|
143
|
+
self._logger.warning(
|
144
|
+
f"Unable to save {bad_file} on disk, error: {e}"
|
145
|
+
)
|
146
|
+
return
|
147
|
+
except Exception as e:
|
148
|
+
self._logger.exception(
|
149
|
+
f"Row {idx}: Unexpected error processing image: {e}"
|
150
|
+
)
|
151
|
+
return
|
152
|
+
|
153
|
+
await asyncio.gather(*(handle(i) for i in self.data.index))
|
154
|
+
|
155
|
+
self._result = self.data
|
156
|
+
return self._result
|
@@ -0,0 +1,67 @@
|
|
1
|
+
from collections.abc import Callable
|
2
|
+
import asyncio
|
3
|
+
from .flow import FlowComponent
|
4
|
+
from ..exceptions import DataNotFound
|
5
|
+
from ..interfaces.dataframes import (
|
6
|
+
PandasDataframe,
|
7
|
+
PolarsDataframe,
|
8
|
+
ArrowDataframe,
|
9
|
+
DtDataframe
|
10
|
+
)
|
11
|
+
|
12
|
+
|
13
|
+
class ToPandas(FlowComponent):
|
14
|
+
"""
|
15
|
+
Convert any input into a DataFrame.
|
16
|
+
"""
|
17
|
+
def __init__(
|
18
|
+
self,
|
19
|
+
loop: asyncio.AbstractEventLoop = None,
|
20
|
+
job: Callable = None,
|
21
|
+
stat: Callable = None,
|
22
|
+
**kwargs,
|
23
|
+
):
|
24
|
+
self._frame = kwargs.get('frame', 'pandas')
|
25
|
+
self._type = kwargs.get('type', 'dict')
|
26
|
+
self._data_path = kwargs.get('data_path', None)
|
27
|
+
super().__init__(loop=loop, job=job, stat=stat, **kwargs)
|
28
|
+
|
29
|
+
async def start(self, **kwargs):
|
30
|
+
"""Initialize the component."""
|
31
|
+
if self.previous:
|
32
|
+
self.data = self.input
|
33
|
+
if self.data is None:
|
34
|
+
raise DataNotFound(
|
35
|
+
f"No data found for component '{self.name}'."
|
36
|
+
)
|
37
|
+
# convert into a List.
|
38
|
+
if isinstance(self.data, dict):
|
39
|
+
if self._data_path:
|
40
|
+
self.data = self.data.get(self._data_path, {})
|
41
|
+
self.data = [self.data]
|
42
|
+
return True
|
43
|
+
|
44
|
+
async def run(self):
|
45
|
+
"""Run the component."""
|
46
|
+
if self._frame == 'pandas':
|
47
|
+
self._result = await PandasDataframe().create_dataframe(
|
48
|
+
self.data
|
49
|
+
)
|
50
|
+
elif self._frame == 'polars':
|
51
|
+
self._result = await PolarsDataframe().create_dataframe(
|
52
|
+
self.data
|
53
|
+
)
|
54
|
+
elif self._frame == 'arrow':
|
55
|
+
self._result = await ArrowDataframe().create_dataframe(
|
56
|
+
self.data
|
57
|
+
)
|
58
|
+
elif self._frame == 'dt':
|
59
|
+
self._result = await DtDataframe().create_dataframe(
|
60
|
+
self.data
|
61
|
+
)
|
62
|
+
self._print_data_(self._result)
|
63
|
+
return self._result
|
64
|
+
|
65
|
+
async def close(self):
|
66
|
+
"""Close the component."""
|
67
|
+
pass
|