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,255 @@
|
|
1
|
+
import asyncio
|
2
|
+
import logging
|
3
|
+
import datetime
|
4
|
+
import builtins
|
5
|
+
from numbers import Number
|
6
|
+
from collections.abc import Callable
|
7
|
+
from asyncdb.exceptions import NoDataFound, ProviderError
|
8
|
+
from querysource.exceptions import DataNotFound
|
9
|
+
from querysource.utils.functions import format_date
|
10
|
+
import querysource.utils.functions as qsfunctions
|
11
|
+
from ..exceptions import ComponentError, NotSupported
|
12
|
+
from ..utils import fnExecutor
|
13
|
+
from .IteratorBase import IteratorBase
|
14
|
+
|
15
|
+
|
16
|
+
class DateList(IteratorBase):
|
17
|
+
"""
|
18
|
+
DateList.
|
19
|
+
|
20
|
+
Overview
|
21
|
+
|
22
|
+
Run as many times as dates generated by this component.
|
23
|
+
.. table:: Properties
|
24
|
+
:widths: auto
|
25
|
+
|
26
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
27
|
+
| Name | Required | Summary |
|
28
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
29
|
+
| range | Yes | Start and end date range parameter |
|
30
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
31
|
+
| inc | Yes | Increases the counter value N times |
|
32
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
33
|
+
| format | Yes | Date format to generate |
|
34
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
35
|
+
| vars | Yes | Generate variables from the start date you generate in each |
|
36
|
+
| | | iterator |
|
37
|
+
+--------------+----------+-----------+-------------------------------------------------------+
|
38
|
+
|
39
|
+
|
40
|
+
Return the list of arbitrary days
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
Example:
|
45
|
+
|
46
|
+
```yaml
|
47
|
+
DateList:
|
48
|
+
range:
|
49
|
+
start: 01-12-2021
|
50
|
+
end: 24-12-2021
|
51
|
+
format: '%d-%m-%Y'
|
52
|
+
inc: 1
|
53
|
+
format: '%Y-%m-%dT%H:%M:%S'
|
54
|
+
vars:
|
55
|
+
firstdate: '{date}'
|
56
|
+
lastdate:
|
57
|
+
- to_midnight
|
58
|
+
- mask: '%Y-%m-%d %H:%M:%S'
|
59
|
+
iterate: true
|
60
|
+
```
|
61
|
+
|
62
|
+
"""
|
63
|
+
|
64
|
+
def __init__(
|
65
|
+
self,
|
66
|
+
loop: asyncio.AbstractEventLoop = None,
|
67
|
+
job: Callable = None,
|
68
|
+
stat: Callable = None,
|
69
|
+
**kwargs,
|
70
|
+
):
|
71
|
+
self._path = None
|
72
|
+
self.pattern = None
|
73
|
+
self._increment = 1
|
74
|
+
self._iterator = None
|
75
|
+
self._format = "%Y-%m-%d"
|
76
|
+
super(DateList, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
|
77
|
+
|
78
|
+
async def start(self, **kwargs):
|
79
|
+
"""Get Range of Dates."""
|
80
|
+
await super(DateList, self).start()
|
81
|
+
if not hasattr(self, "range"):
|
82
|
+
raise ComponentError("Error: you need to specify a range attribute")
|
83
|
+
# get start and end dates
|
84
|
+
if "start" not in self.range:
|
85
|
+
raise ComponentError("Error: you need to specify a start Date")
|
86
|
+
if "end" not in self.range:
|
87
|
+
raise ComponentError("Error: you need to specify an End Date")
|
88
|
+
### Incremental:
|
89
|
+
if hasattr(self, "inc"):
|
90
|
+
self._increment = self.inc
|
91
|
+
if "increment" in self._variables:
|
92
|
+
self._increment = int(self._variables["increment"])
|
93
|
+
elif "inc" in self._args:
|
94
|
+
self._increment = int(self._args["inc"])
|
95
|
+
self.setVar("inc", self._increment)
|
96
|
+
if hasattr(self, "format"):
|
97
|
+
self._format = self.format
|
98
|
+
# set the start:end of the range
|
99
|
+
if "start" in self._args:
|
100
|
+
range_start = self._args["start"]
|
101
|
+
elif isinstance(self.range["start"], list):
|
102
|
+
range_start = fnExecutor(self.range["start"])
|
103
|
+
else:
|
104
|
+
range_start = self.range["start"]
|
105
|
+
if "end" in self._args:
|
106
|
+
range_end = self._args["end"]
|
107
|
+
elif isinstance(self.range["end"], list):
|
108
|
+
range_end = fnExecutor(self.range["end"])
|
109
|
+
else:
|
110
|
+
range_end = self.range["end"]
|
111
|
+
# build the dates
|
112
|
+
start = datetime.datetime.strptime(range_start, self.range["format"])
|
113
|
+
end = datetime.datetime.strptime(range_end, self.range["format"])
|
114
|
+
if self._debug:
|
115
|
+
self._logger.debug(f"RANGE> {start!s} - {end!s}")
|
116
|
+
self._logger.debug(f'INCREMENT> {self._increment}')
|
117
|
+
# define the generator
|
118
|
+
self._iterator = (
|
119
|
+
start + datetime.timedelta(days=x)
|
120
|
+
for x in range(0, (end - start).days + 1, self._increment)
|
121
|
+
)
|
122
|
+
self.add_metric("RANGE", f"{start!s} - {end!s}")
|
123
|
+
self.add_metric("INCREMENT", self._increment)
|
124
|
+
return True
|
125
|
+
|
126
|
+
def createJob(self, target, params, dt, d):
|
127
|
+
"""Create the Job Component."""
|
128
|
+
self._result = str(dt)
|
129
|
+
if hasattr(self, "vars"):
|
130
|
+
for name, value in self.vars.items():
|
131
|
+
kwargs = {}
|
132
|
+
if value == "{date}":
|
133
|
+
val = value.format(date=dt)
|
134
|
+
elif name in self._params:
|
135
|
+
val = self._params[name]
|
136
|
+
elif name in self.conditions:
|
137
|
+
val = self.conditions[name]
|
138
|
+
elif isinstance(value, list):
|
139
|
+
fname = value[0]
|
140
|
+
try:
|
141
|
+
kwargs = value[1].copy()
|
142
|
+
for k, v in value[1].items():
|
143
|
+
if isinstance(v, int):
|
144
|
+
kwargs[k] = v
|
145
|
+
elif "{increment}" in v:
|
146
|
+
kwargs[k] = self._increment - 1
|
147
|
+
elif "{date}" in v:
|
148
|
+
kwargs[k] = v.format(date=dt)
|
149
|
+
except IndexError:
|
150
|
+
kwargs = {}
|
151
|
+
if 'value' not in kwargs:
|
152
|
+
t = {"value": d}
|
153
|
+
else:
|
154
|
+
t = {}
|
155
|
+
kwargs = {**kwargs, **t}
|
156
|
+
try:
|
157
|
+
f = getattr(qsfunctions, fname)
|
158
|
+
except AttributeError:
|
159
|
+
f = getattr(builtins, fname)
|
160
|
+
try:
|
161
|
+
val = f(**kwargs)
|
162
|
+
except (TypeError, AttributeError):
|
163
|
+
try:
|
164
|
+
val = globals()[fname](**kwargs)
|
165
|
+
except (TypeError, ValueError) as err:
|
166
|
+
print(str(err))
|
167
|
+
val = None
|
168
|
+
elif name in self._mask:
|
169
|
+
val = self._mask[name]
|
170
|
+
elif isinstance(value, int):
|
171
|
+
val = int(value)
|
172
|
+
elif isinstance(value, Number):
|
173
|
+
val = value
|
174
|
+
elif isinstance(value, str):
|
175
|
+
val = value.format(date=dt)
|
176
|
+
else:
|
177
|
+
val = value.format(date=dt)
|
178
|
+
params[name] = val
|
179
|
+
self.setVar(name, val)
|
180
|
+
else:
|
181
|
+
# think if we need to create the vars using self._vars
|
182
|
+
for name, value in self._vars.items():
|
183
|
+
print("VARIABLES::: ", name, value)
|
184
|
+
if value == "{date}":
|
185
|
+
params[name] = dt
|
186
|
+
self.setVar(name, dt)
|
187
|
+
else:
|
188
|
+
params[name] = value
|
189
|
+
self.setVar(name, value)
|
190
|
+
params["date"] = dt
|
191
|
+
params["filterdate"] = dt
|
192
|
+
return self.get_job(target, **params)
|
193
|
+
|
194
|
+
def setAttributes(self, dt):
|
195
|
+
"""Defining the result to component."""
|
196
|
+
try:
|
197
|
+
self.setVar("{}_{}".format(self.StepName, "DATE"), dt)
|
198
|
+
self._result = str(dt)
|
199
|
+
except Exception as err:
|
200
|
+
print(err)
|
201
|
+
return False
|
202
|
+
|
203
|
+
async def close(self, job=None):
|
204
|
+
close = getattr(job, "close", None)
|
205
|
+
if job:
|
206
|
+
if asyncio.iscoroutinefunction(close):
|
207
|
+
await job.close()
|
208
|
+
else:
|
209
|
+
job.close()
|
210
|
+
|
211
|
+
async def run(self):
|
212
|
+
"""Async Run Method."""
|
213
|
+
status = False
|
214
|
+
if not self._iterator:
|
215
|
+
return False
|
216
|
+
if self.iterate:
|
217
|
+
# iterate over next task
|
218
|
+
step, target, params = self.get_step()
|
219
|
+
step_name = step.name
|
220
|
+
for d in self._iterator:
|
221
|
+
dt = format_date(d, self._format)
|
222
|
+
|
223
|
+
self.setAttributes(dt)
|
224
|
+
job = self.createJob(target, params, dt, d)
|
225
|
+
if job:
|
226
|
+
try:
|
227
|
+
status = await self.async_job(job, step_name)
|
228
|
+
except (NoDataFound, DataNotFound) as err:
|
229
|
+
# its a data component a no data was found
|
230
|
+
logging.debug(
|
231
|
+
f"Data not Found for Task {step_name}, Error: {err}"
|
232
|
+
)
|
233
|
+
continue
|
234
|
+
except (ProviderError, ComponentError) as err:
|
235
|
+
raise ComponentError(
|
236
|
+
f"Error running Component {step_name}, error: {err}"
|
237
|
+
) from err
|
238
|
+
except NotSupported as err:
|
239
|
+
raise NotSupported(
|
240
|
+
f"Not Supported: Error on Component {step_name}, error: {err}"
|
241
|
+
) from err
|
242
|
+
except Exception as err:
|
243
|
+
raise ComponentError(
|
244
|
+
f"DateList: Component Error on {step_name}, error: {err}"
|
245
|
+
) from err
|
246
|
+
finally:
|
247
|
+
await self.close(job)
|
248
|
+
if status is False:
|
249
|
+
return False
|
250
|
+
else:
|
251
|
+
return True
|
252
|
+
else:
|
253
|
+
# return the list of date
|
254
|
+
self._result = list(self._iterator)
|
255
|
+
return True
|
@@ -0,0 +1,163 @@
|
|
1
|
+
from abc import ABC
|
2
|
+
from typing import Union, Optional
|
3
|
+
from pathlib import PurePath
|
4
|
+
import aiofiles
|
5
|
+
import pandas
|
6
|
+
from asyncdb.drivers.base import BaseDriver
|
7
|
+
from asyncdb.exceptions import NoDataFound
|
8
|
+
from navconfig.logging import logging
|
9
|
+
from ..utils import cPrint
|
10
|
+
from ..utils.functions import is_empty, as_boolean
|
11
|
+
from ..exceptions import ComponentError, FileError, DataNotFound
|
12
|
+
from ..interfaces import DBInterface
|
13
|
+
|
14
|
+
|
15
|
+
class DbClient(DBInterface):
|
16
|
+
"""
|
17
|
+
DbClient.
|
18
|
+
|
19
|
+
Abstract base class for database clients using AsyncDB.
|
20
|
+
|
21
|
+
Provides common methods for connecting to a database, executing queries,
|
22
|
+
and handling results.
|
23
|
+
|
24
|
+
Inherits from the `DBInterface` interface.
|
25
|
+
|
26
|
+
.. note::
|
27
|
+
This class is intended to be subclassed by specific database client implementations.
|
28
|
+
|
29
|
+
.. table:: Properties
|
30
|
+
:widths: auto
|
31
|
+
|
32
|
+
+--------------------+----------+--------------------------------------------------------------------------------+
|
33
|
+
| Name | Required | Description |
|
34
|
+
+--------------------+----------+--------------------------------------------------------------------------------+
|
35
|
+
| driver | Yes | Database driver to use (e.g., "pg" for PostgreSQL). |
|
36
|
+
+--------------------+----------+--------------------------------------------------------------------------------+
|
37
|
+
| credentials | Yes | Dictionary containing database connection credentials (user, password, etc.). |
|
38
|
+
| | | Defined by the `_credentials` class attribute. |
|
39
|
+
+--------------------+----------+--------------------------------------------------------------------------------+
|
40
|
+
| raw_result | No | Boolean flag indicating whether to return raw query results or convert them |
|
41
|
+
| | | to dictionaries (defaults to False). |
|
42
|
+
+--------------------+----------+--------------------------------------------------------------------------------+
|
43
|
+
| infer_types | No | Boolean flag indicating whether to infer data types for pandas DataFrames |
|
44
|
+
| | | created from query results (defaults to False). |
|
45
|
+
+--------------------+----------+--------------------------------------------------------------------------------+
|
46
|
+
| as_dataframe | No | Boolean flag indicating whether to convert query results to a pandas DataFrame |
|
47
|
+
| | | (defaults to True). |
|
48
|
+
+--------------------+----------+--------------------------------------------------------------------------------+
|
49
|
+
| as_string | No | Boolean flag indicating whether to convert object columns in DataFrames |
|
50
|
+
| | | to strings (defaults to False). Converting to strings requires type |
|
51
|
+
| | | inference (set `infer_types` to True if used). |
|
52
|
+
+--------------------+----------+--------------------------------------------------------------------------------+
|
53
|
+
|
54
|
+
.. returns::
|
55
|
+
varies
|
56
|
+
The return value of the `_query` method depends on the `raw_result` and `as_dataframe` properties:
|
57
|
+
* If `raw_result` is True: Returns the raw result object specific to the database driver.
|
58
|
+
* If `raw_result` is False and `as_dataframe` is True: Returns a pandas DataFrame containing the query results.
|
59
|
+
* If `raw_result` is False and `as_dataframe` is False: Returns a list of dictionaries representing the query results.
|
60
|
+
Raises exceptions for errors during execution (e.g., `DataNotFound`, `ComponentError`).
|
61
|
+
""" # noqa
|
62
|
+
_credentials = {
|
63
|
+
"user": str,
|
64
|
+
"password": str,
|
65
|
+
"host": str,
|
66
|
+
"port": int,
|
67
|
+
"database": str,
|
68
|
+
}
|
69
|
+
|
70
|
+
def __init__(
|
71
|
+
self,
|
72
|
+
*args,
|
73
|
+
**kwargs
|
74
|
+
) -> None:
|
75
|
+
self.raw_result: bool = kwargs.pop("raw_result", False)
|
76
|
+
self.infer_types: bool = as_boolean(kwargs.pop("infer_types", False))
|
77
|
+
self.as_dataframe: bool = as_boolean(kwargs.pop("as_dataframe", True))
|
78
|
+
# using "string" instead objects in pandas
|
79
|
+
self.as_string: bool = as_boolean(kwargs.pop("as_string", False))
|
80
|
+
super().__init__(*args, **kwargs)
|
81
|
+
if self.as_string is True:
|
82
|
+
self.infer_types = True
|
83
|
+
# any other argument
|
84
|
+
self._args = kwargs
|
85
|
+
|
86
|
+
async def open_sqlfile(self, file: PurePath, **kwargs) -> str:
|
87
|
+
if file.exists() and file.is_file():
|
88
|
+
content = None
|
89
|
+
# open SQL File:
|
90
|
+
async with aiofiles.open(file, "r+") as afp:
|
91
|
+
content = await afp.read()
|
92
|
+
# check if we need to replace masks
|
93
|
+
if hasattr(self, "masks"):
|
94
|
+
content = self.mask_replacement(content)
|
95
|
+
if self.use_template is True:
|
96
|
+
content = self._templateparser.from_string(content, kwargs)
|
97
|
+
return content
|
98
|
+
else:
|
99
|
+
raise FileError(
|
100
|
+
f"{__name__}: Missing SQL File: {file}"
|
101
|
+
)
|
102
|
+
|
103
|
+
async def close(self, connection: BaseDriver = None) -> None:
|
104
|
+
if not connection:
|
105
|
+
connection = self._connection
|
106
|
+
try:
|
107
|
+
if connection is not None:
|
108
|
+
await connection.close()
|
109
|
+
except Exception as err: # pylint: disable=W0703
|
110
|
+
logging.error(
|
111
|
+
f"DbClient Closing error: {err}"
|
112
|
+
)
|
113
|
+
|
114
|
+
async def _query(
|
115
|
+
self, query: Union[str, dict], connection: BaseDriver = None
|
116
|
+
) -> Union[list, dict]:
|
117
|
+
if not connection:
|
118
|
+
connection = self._connection
|
119
|
+
try:
|
120
|
+
if isinstance(query, dict):
|
121
|
+
result, error = await connection.query(**query)
|
122
|
+
print('RESULT > ', result, error)
|
123
|
+
else:
|
124
|
+
result, error = await connection.query(query)
|
125
|
+
if error:
|
126
|
+
raise ComponentError(
|
127
|
+
f"DbClient: Query Error: {error}"
|
128
|
+
)
|
129
|
+
if self.raw_result is True:
|
130
|
+
return result
|
131
|
+
else: # converting to dict
|
132
|
+
result = [dict(row) for row in result]
|
133
|
+
return result
|
134
|
+
except (DataNotFound, NoDataFound) as err:
|
135
|
+
raise DataNotFound("DbClient: Data not found") from err
|
136
|
+
except Exception as err:
|
137
|
+
raise ComponentError(f"{err}") from err
|
138
|
+
|
139
|
+
async def get_dataframe(self, result):
|
140
|
+
try:
|
141
|
+
df = pandas.DataFrame(result)
|
142
|
+
except Exception as err: # pylint: disable=W0703
|
143
|
+
logging.exception(err, stack_info=True)
|
144
|
+
# Attempt to infer better dtypes for object columns.
|
145
|
+
if is_empty(df):
|
146
|
+
raise DataNotFound("DbClient: Data not Found")
|
147
|
+
df.infer_objects()
|
148
|
+
if self.infer_types is True:
|
149
|
+
df = df.convert_dtypes(convert_string=self.as_string)
|
150
|
+
if self._debug is True:
|
151
|
+
cPrint("Data Types:")
|
152
|
+
print(df.dtypes)
|
153
|
+
if hasattr(self, "drop_empty"):
|
154
|
+
df.dropna(axis=1, how="all", inplace=True)
|
155
|
+
df.dropna(axis=0, how="all", inplace=True)
|
156
|
+
if hasattr(self, "dropna"):
|
157
|
+
df.dropna(subset=self.dropna, how="all", inplace=True)
|
158
|
+
if (
|
159
|
+
hasattr(self, "clean_strings") and getattr(self, "clean_strings", False) is True
|
160
|
+
):
|
161
|
+
u = df.select_dtypes(include=["object", "string"])
|
162
|
+
df[u.columns] = u.fillna("")
|
163
|
+
return df
|
@@ -0,0 +1,146 @@
|
|
1
|
+
import asyncio
|
2
|
+
import pandas as pd
|
3
|
+
from collections.abc import Callable
|
4
|
+
from urllib.parse import urljoin
|
5
|
+
from io import StringIO
|
6
|
+
from navconfig.logging import logging
|
7
|
+
from .flow import FlowComponent
|
8
|
+
from ..interfaces.http import HTTPService
|
9
|
+
from ..exceptions import ComponentError
|
10
|
+
|
11
|
+
class DialPad(FlowComponent, HTTPService):
|
12
|
+
"""
|
13
|
+
DialPad
|
14
|
+
|
15
|
+
Overview
|
16
|
+
|
17
|
+
The DialPad class is a component for interacting with the DialPad API. It extends the FlowComponent and HTTPService
|
18
|
+
classes, providing methods for authentication, fetching statistics, and handling API responses.
|
19
|
+
|
20
|
+
.. table:: Properties
|
21
|
+
:widths: auto
|
22
|
+
|
23
|
+
+------------------+----------+--------------------------------------------------------------------------------------------------+
|
24
|
+
| Name | Required | Description |
|
25
|
+
+------------------+----------+--------------------------------------------------------------------------------------------------+
|
26
|
+
| accept | No | The accepted content type for API responses, defaults to "application/json". |
|
27
|
+
+------------------+----------+--------------------------------------------------------------------------------------------------+
|
28
|
+
| download | No | The download flag indicating if a file download is required. |
|
29
|
+
+------------------+----------+--------------------------------------------------------------------------------------------------+
|
30
|
+
| _credentials | Yes | A dictionary containing the API key for authentication. |
|
31
|
+
+------------------+----------+--------------------------------------------------------------------------------------------------+
|
32
|
+
| _base_url | Yes | The base URL for the DialPad API. |
|
33
|
+
+------------------+----------+--------------------------------------------------------------------------------------------------+
|
34
|
+
| auth | Yes | The authentication header for API requests. |
|
35
|
+
+------------------+----------+--------------------------------------------------------------------------------------------------+
|
36
|
+
Return
|
37
|
+
|
38
|
+
The methods in this class manage the interaction with the DialPad API, including initialization, fetching statistics,
|
39
|
+
processing results, and handling credentials.
|
40
|
+
|
41
|
+
""" # noqa
|
42
|
+
accept: str = "text/csv"
|
43
|
+
download = None
|
44
|
+
_credentials: dict = {"APIKEY": str}
|
45
|
+
|
46
|
+
def __init__(
|
47
|
+
self,
|
48
|
+
loop: asyncio.AbstractEventLoop = None,
|
49
|
+
job: Callable = None,
|
50
|
+
stat: Callable = None,
|
51
|
+
**kwargs,
|
52
|
+
):
|
53
|
+
FlowComponent.__init__(self, loop=loop, job=job, stat=stat, **kwargs)
|
54
|
+
HTTPService.__init__(self, **kwargs)
|
55
|
+
|
56
|
+
async def start(self, **kwargs):
|
57
|
+
self._base_url = "https://dialpad.com/api/v2/"
|
58
|
+
|
59
|
+
self.processing_credentials()
|
60
|
+
self.auth = {"apikey": self.credentials["APIKEY"]}
|
61
|
+
|
62
|
+
if self.previous:
|
63
|
+
self.data = self.input
|
64
|
+
else:
|
65
|
+
self.data = None
|
66
|
+
return True
|
67
|
+
|
68
|
+
async def dialpad_stats(self):
|
69
|
+
# processing statistics asynchronously
|
70
|
+
self.accept: str = "application/json"
|
71
|
+
stats_url = urljoin(self._base_url, "stats/")
|
72
|
+
processing_result, _ = await self.session(
|
73
|
+
stats_url, "post", data=self.body_params, use_json=True
|
74
|
+
)
|
75
|
+
request_id = processing_result.get("request_id")
|
76
|
+
|
77
|
+
count = 0
|
78
|
+
while True:
|
79
|
+
get_result_url = urljoin(stats_url, request_id)
|
80
|
+
response_result, _ = await self.session(get_result_url, use_json=True)
|
81
|
+
file_url = response_result.get("download_url", None)
|
82
|
+
if file_url or count > 60:
|
83
|
+
break
|
84
|
+
count += 1
|
85
|
+
logging.debug(f"Try: {count!s}")
|
86
|
+
await asyncio.sleep(10)
|
87
|
+
|
88
|
+
self.accept: str = "text/csv"
|
89
|
+
self.download = False
|
90
|
+
result, _ = await self.session(file_url)
|
91
|
+
df_results = await self.from_csv(StringIO(result))
|
92
|
+
return df_results
|
93
|
+
|
94
|
+
async def dialpad_send_sms(self):
|
95
|
+
# send SMS message
|
96
|
+
url = urljoin(self._base_url, "sms")
|
97
|
+
from_number = self.body_params.get("from_number")
|
98
|
+
to_numbers = self.body_params.get("to_numbers")
|
99
|
+
text = self.body_params.get("text")
|
100
|
+
|
101
|
+
if self.data is not None and not self.data.empty:
|
102
|
+
if text in self.data.columns:
|
103
|
+
text = self.data.get(text).iloc[0]
|
104
|
+
if from_number in self.data.columns:
|
105
|
+
from_number = self.data.get(from_number).iloc[0]
|
106
|
+
if not isinstance(to_numbers, list):
|
107
|
+
if isinstance(to_numbers, str):
|
108
|
+
if to_numbers in self.data.columns:
|
109
|
+
to_numbers = self.data[to_numbers].tolist()
|
110
|
+
else:
|
111
|
+
to_numbers = [to_numbers]
|
112
|
+
|
113
|
+
payload = {
|
114
|
+
"infer_country_code": True,
|
115
|
+
"text": text,
|
116
|
+
"from_number": from_number,
|
117
|
+
"to_numbers": to_numbers
|
118
|
+
}
|
119
|
+
|
120
|
+
self.accept: str = "application/json"
|
121
|
+
stats_url = urljoin(self._base_url, "sms")
|
122
|
+
result, _ = await self.session(
|
123
|
+
stats_url, "post", data=payload, use_json=True
|
124
|
+
)
|
125
|
+
|
126
|
+
df_results = pd.DataFrame([result])
|
127
|
+
return df_results
|
128
|
+
|
129
|
+
async def run(self):
|
130
|
+
try:
|
131
|
+
method = getattr(self, f"dialpad_{self.type}")
|
132
|
+
except AttributeError as ex:
|
133
|
+
raise ComponentError(f"{__name__}: Wrong 'type' on task definition") from ex
|
134
|
+
result = await method()
|
135
|
+
self._result = result
|
136
|
+
print(self._result)
|
137
|
+
if self._debug:
|
138
|
+
columns = list(self._result.columns)
|
139
|
+
print(f"Debugging: {self.__name__} ===")
|
140
|
+
for column in columns:
|
141
|
+
t = self._result[column].dtype
|
142
|
+
print(column, "->", t, "->", self._result[column].iloc[0])
|
143
|
+
return self._result
|
144
|
+
|
145
|
+
async def close(self):
|
146
|
+
pass
|