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
Binary file
|
@@ -0,0 +1,82 @@
|
|
1
|
+
"""BaseExtension is a Helper to build Pluggable extensions for FlowTask."""
|
2
|
+
import sys
|
3
|
+
from typing import Optional
|
4
|
+
from collections.abc import Callable
|
5
|
+
from abc import ABC
|
6
|
+
from navconfig.logging import logging
|
7
|
+
from navigator.types import WebApp
|
8
|
+
from ..exceptions import TaskException
|
9
|
+
|
10
|
+
if sys.version_info < (3, 10):
|
11
|
+
from typing_extensions import ParamSpec
|
12
|
+
else:
|
13
|
+
from typing import ParamSpec
|
14
|
+
P = ParamSpec("P")
|
15
|
+
|
16
|
+
|
17
|
+
class ExtensionError(TaskException):
|
18
|
+
"""Useful for raise errors from Extensions."""
|
19
|
+
|
20
|
+
|
21
|
+
class BaseExtension(ABC):
|
22
|
+
"""BaseExtension.
|
23
|
+
|
24
|
+
Description: Base Class for all FlowTask Extensions.
|
25
|
+
"""
|
26
|
+
|
27
|
+
app: WebApp
|
28
|
+
|
29
|
+
# Signal for any startup method on application.
|
30
|
+
on_startup: Optional[Callable] = None
|
31
|
+
|
32
|
+
# Signal for any shutdown process (will registered into App).
|
33
|
+
on_shutdown: Optional[Callable] = None
|
34
|
+
|
35
|
+
# Signal for any cleanup process (will registered into App).
|
36
|
+
on_cleanup: Optional[Callable] = None
|
37
|
+
|
38
|
+
# adding custom middlewares to app (if needed)
|
39
|
+
middleware: Optional[Callable] = None
|
40
|
+
|
41
|
+
def __init__(self, *args: P.args, **kwargs: P.kwargs) -> None:
|
42
|
+
### added config support
|
43
|
+
self._args = args
|
44
|
+
self._kwargs = kwargs
|
45
|
+
## name of the extension:
|
46
|
+
self.__name__: str = self.__class__.__name__
|
47
|
+
### logging
|
48
|
+
self.logger = logging.getLogger(f"FlowTask.ext.{self.__name__}")
|
49
|
+
|
50
|
+
def setup(self, app: WebApp) -> WebApp:
|
51
|
+
if hasattr(app, "get_app"): # migrate to BaseApplication (on types)
|
52
|
+
self.app = app.get_app()
|
53
|
+
elif isinstance(app, WebApp):
|
54
|
+
self.app = app # register the app into the Extension
|
55
|
+
else:
|
56
|
+
raise TypeError(f"Invalid type for aiohttp Application: {app}:{type(app)}")
|
57
|
+
self.logger.debug(f":::: FlowTask Extension {self.__name__} Loaded ::::")
|
58
|
+
# add a middleware to the app
|
59
|
+
if callable(self.middleware):
|
60
|
+
try:
|
61
|
+
mdl = self.app.middlewares
|
62
|
+
# add the middleware
|
63
|
+
mdl.append(self.middleware)
|
64
|
+
except Exception as err:
|
65
|
+
self.logger.exception(
|
66
|
+
f"Error loading Extension Middleware {self.__name__} init: {err!s}"
|
67
|
+
)
|
68
|
+
raise ExtensionError(
|
69
|
+
f"Error loading Extension Middleware {self.__name__} init: {err!s}"
|
70
|
+
) from err
|
71
|
+
|
72
|
+
# adding signals for startup and shutdown:
|
73
|
+
# startup operations over extension backend
|
74
|
+
if callable(self.on_startup):
|
75
|
+
self.app.on_startup.append(self.on_startup)
|
76
|
+
# cleanup operations over extension backend
|
77
|
+
if callable(self.on_shutdown):
|
78
|
+
self.app.on_shutdown.append(self.on_shutdown)
|
79
|
+
# cleanup operations over extension backend
|
80
|
+
if callable(self.on_cleanup):
|
81
|
+
self.app.on_cleanup.append(self.on_cleanup)
|
82
|
+
return self.app
|
@@ -0,0 +1,65 @@
|
|
1
|
+
"""
|
2
|
+
LoggingFacility.
|
3
|
+
|
4
|
+
API For sending Logs to Backend.
|
5
|
+
"""
|
6
|
+
from navconfig.logging import logging
|
7
|
+
from navigator.views import BaseView
|
8
|
+
from ...extensions import BaseExtension
|
9
|
+
|
10
|
+
|
11
|
+
class LoggingFacility(BaseExtension):
|
12
|
+
def setup(self, app):
|
13
|
+
super().setup(app)
|
14
|
+
# Logging Facility:
|
15
|
+
self.app.router.add_view("/api/v1/log", Logger)
|
16
|
+
|
17
|
+
|
18
|
+
## TODO: migrate to Handler.
|
19
|
+
class Logger(BaseView):
|
20
|
+
"""Logging Facility."""
|
21
|
+
|
22
|
+
async def post(self):
|
23
|
+
data = await self.json_data()
|
24
|
+
print(data)
|
25
|
+
try:
|
26
|
+
message = data["message"]
|
27
|
+
del data["message"]
|
28
|
+
except KeyError:
|
29
|
+
return self.error(
|
30
|
+
request=self.request, response="Log require Message Data", state=406
|
31
|
+
)
|
32
|
+
# TODO: using jsonschema to validate JSON request
|
33
|
+
if "level" in data:
|
34
|
+
level = data["level"]
|
35
|
+
else:
|
36
|
+
level = "debug"
|
37
|
+
# adding tags:
|
38
|
+
tags = ["Navigator"]
|
39
|
+
if "tags" in data:
|
40
|
+
tags = data["tags"] + tags
|
41
|
+
try:
|
42
|
+
if level == "error":
|
43
|
+
logging.error(message, extra=data)
|
44
|
+
elif level == "debug":
|
45
|
+
logging.debug(message, extra=data)
|
46
|
+
elif level == "warning":
|
47
|
+
logging.warning(message, extra=data)
|
48
|
+
elif level == "exception":
|
49
|
+
logging.exception(message, extra=data)
|
50
|
+
else:
|
51
|
+
logging.info(message, extra=data)
|
52
|
+
headers = {"X-STATUS": "OK", "X-MESSAGE": "Logging Success"}
|
53
|
+
msg = {"message": message}
|
54
|
+
return self.json_response(response=msg, headers=headers, state=202)
|
55
|
+
except Exception as err: # pylint: disable=W0703
|
56
|
+
headers = {
|
57
|
+
"X-STATUS": "Error",
|
58
|
+
"X-MESSAGE": "Resource Error: Logging Error",
|
59
|
+
}
|
60
|
+
msg = {
|
61
|
+
"state": "Failed",
|
62
|
+
"message": "Error: Failed Logging operation",
|
63
|
+
"status": 400,
|
64
|
+
}
|
65
|
+
return self.error(response=msg, exception=err, headers=headers, state=400)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
"""
|
2
|
+
Hook Actions.
|
3
|
+
|
4
|
+
Actions are the Components called by a Hook Definition.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from .abstract import AbstractAction
|
8
|
+
from .dummy import DummyAction
|
9
|
+
from .jira import JiraTicket, JiraIssue
|
10
|
+
from .zammad import Zammad
|
11
|
+
from .task import Task
|
12
|
+
from .sampledata import ProcessData
|
13
|
+
from .sensor import ProcessSensorData
|
14
|
+
|
15
|
+
__all__ = (
|
16
|
+
"AbstractAction",
|
17
|
+
"DummyAction",
|
18
|
+
"JiraTicket",
|
19
|
+
"JiraIssue",
|
20
|
+
"Zammad",
|
21
|
+
"Task",
|
22
|
+
)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
from typing import Any
|
2
|
+
from abc import ABC, abstractmethod
|
3
|
+
from ...interfaces import LogSupport, MaskSupport, LocaleSupport
|
4
|
+
|
5
|
+
|
6
|
+
class AbstractAction(MaskSupport, LogSupport, LocaleSupport, ABC):
|
7
|
+
"""AbstractAction.
|
8
|
+
|
9
|
+
Action can be used to perform operations when a Hook is called.
|
10
|
+
"""
|
11
|
+
|
12
|
+
def __init__(self, *args, **kwargs) -> None:
|
13
|
+
self._name_ = self.__class__.__name__
|
14
|
+
super().__init__(*args, **kwargs)
|
15
|
+
# program
|
16
|
+
self._program = kwargs.pop("program", "navigator")
|
17
|
+
# attributes (root-level of component arguments):
|
18
|
+
self._attributes: dict = kwargs.pop("attributes", {})
|
19
|
+
# arguments (root-level of component arguments):
|
20
|
+
self.arguments: dict = kwargs.pop("arguments", {})
|
21
|
+
# Arguments of actions::
|
22
|
+
try:
|
23
|
+
self.arguments = {**self.arguments, **kwargs}
|
24
|
+
except (TypeError, ValueError):
|
25
|
+
pass
|
26
|
+
# set the attributes of Action:
|
27
|
+
for arg, val in self.arguments.items():
|
28
|
+
if arg in self._attributes:
|
29
|
+
val = self._attributes[arg]
|
30
|
+
try:
|
31
|
+
setattr(self, arg, val)
|
32
|
+
except (AttributeError, TypeError) as err:
|
33
|
+
self._logger.warning(
|
34
|
+
f"Wrong Attribute: {arg}={val}"
|
35
|
+
)
|
36
|
+
self._logger.error(err)
|
37
|
+
# You can define any initialization logic here, such as
|
38
|
+
# storing parameters that control the behavior of the action.
|
39
|
+
self._args = args
|
40
|
+
self._kwargs = kwargs
|
41
|
+
|
42
|
+
def __repr__(self) -> str:
|
43
|
+
return f"<Action.{self._name_}>"
|
44
|
+
|
45
|
+
@abstractmethod
|
46
|
+
async def open(self) -> None:
|
47
|
+
pass
|
48
|
+
|
49
|
+
@abstractmethod
|
50
|
+
async def close(self) -> None:
|
51
|
+
pass
|
52
|
+
|
53
|
+
@abstractmethod
|
54
|
+
async def run(self, hook, *args, **kwargs) -> Any:
|
55
|
+
# This is where you define the behavior of the action.
|
56
|
+
# Since this method is asynchronous, you should use the "await"
|
57
|
+
# keyword to call other asynchronous functions or coroutines.
|
58
|
+
pass
|
59
|
+
|
60
|
+
async def __aenter__(self) -> "AbstractAction":
|
61
|
+
await self.open()
|
62
|
+
return self
|
63
|
+
|
64
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
|
65
|
+
# clean up anything you need to clean up
|
66
|
+
return await self.close()
|
@@ -0,0 +1,23 @@
|
|
1
|
+
from .abstract import AbstractAction
|
2
|
+
from ...utils import cPrint
|
3
|
+
|
4
|
+
class DummyAction(AbstractAction):
|
5
|
+
"""DummyAction.
|
6
|
+
|
7
|
+
Simply Print the Action object.
|
8
|
+
"""
|
9
|
+
|
10
|
+
async def open(self):
|
11
|
+
cPrint('Opening Action on Dummy.')
|
12
|
+
|
13
|
+
async def run(self, hook, *args, **kwargs):
|
14
|
+
print(
|
15
|
+
f"Running action from hook {hook} with arguments:",
|
16
|
+
args,
|
17
|
+
self._args,
|
18
|
+
kwargs,
|
19
|
+
self._kwargs
|
20
|
+
)
|
21
|
+
|
22
|
+
async def close(self):
|
23
|
+
cPrint("Closing Action on Dummy.")
|
@@ -0,0 +1,74 @@
|
|
1
|
+
from jira import JIRA
|
2
|
+
from ...conf import JIRA_API_TOKEN, JIRA_USERNAME, JIRA_INSTANCE, JIRA_PROJECT
|
3
|
+
from .ticket import AbstractTicket
|
4
|
+
from .abstract import AbstractAction
|
5
|
+
|
6
|
+
|
7
|
+
class JiraTicket(AbstractTicket):
|
8
|
+
"""Jira.
|
9
|
+
|
10
|
+
Create a Jira Ticket using a Hook.
|
11
|
+
"""
|
12
|
+
|
13
|
+
async def open(self):
|
14
|
+
args = {"basic_auth": (JIRA_USERNAME, JIRA_API_TOKEN)}
|
15
|
+
try:
|
16
|
+
self.service = JIRA(JIRA_INSTANCE, **args)
|
17
|
+
except Exception as e:
|
18
|
+
self._logger.error(f"Error connecting to JIRA Instance: {e}")
|
19
|
+
raise
|
20
|
+
|
21
|
+
async def close(self):
|
22
|
+
self.service = None
|
23
|
+
|
24
|
+
async def create(self, hook, *args, **kwargs):
|
25
|
+
"""create.
|
26
|
+
|
27
|
+
Create a new Ticket.
|
28
|
+
"""
|
29
|
+
project = kwargs.pop("project", JIRA_PROJECT)
|
30
|
+
summary = kwargs.pop("summary", None)
|
31
|
+
description = kwargs.pop("description", None)
|
32
|
+
args = {
|
33
|
+
"project": project,
|
34
|
+
"summary": summary,
|
35
|
+
"description": description,
|
36
|
+
"issuetype": {"name": "Bug"},
|
37
|
+
}
|
38
|
+
if "issuetype" in kwargs:
|
39
|
+
args["issuetype"] = {"name": kwargs["issuetype"]}
|
40
|
+
try:
|
41
|
+
new_issue = self.service.create_issue(**args)
|
42
|
+
print("ISSUE ", new_issue)
|
43
|
+
return new_issue
|
44
|
+
except Exception as e:
|
45
|
+
self._logger.error(f"Error creating Jira Ticket: {e}")
|
46
|
+
raise
|
47
|
+
|
48
|
+
|
49
|
+
class JiraIssue(AbstractAction):
|
50
|
+
"""An action to process Jira issue events."""
|
51
|
+
|
52
|
+
async def open(self):
|
53
|
+
# Initialize resources if needed
|
54
|
+
pass
|
55
|
+
|
56
|
+
async def close(self):
|
57
|
+
# Clean up resources if needed
|
58
|
+
pass
|
59
|
+
|
60
|
+
async def run(self, hook, event_type, issue_key, issue_fields, **kwargs):
|
61
|
+
self._logger.info(
|
62
|
+
f"Processing Jira issue {event_type}: {issue_key}"
|
63
|
+
)
|
64
|
+
issue = kwargs.get('issue')
|
65
|
+
print('ISSUE > ', issue)
|
66
|
+
# Implement your action logic here
|
67
|
+
# For example, send a notification or update a database
|
68
|
+
# Access issue details via issue_fields
|
69
|
+
return {
|
70
|
+
'status': 'success',
|
71
|
+
'issue_key': issue_key,
|
72
|
+
'event_type': event_type,
|
73
|
+
'issue': issue
|
74
|
+
}
|
@@ -0,0 +1,320 @@
|
|
1
|
+
import asyncio
|
2
|
+
from urllib.parse import urlencode
|
3
|
+
from functools import partial
|
4
|
+
from concurrent.futures import ThreadPoolExecutor
|
5
|
+
import aiohttp
|
6
|
+
import requests
|
7
|
+
from requests.auth import HTTPBasicAuth
|
8
|
+
|
9
|
+
# processing the response:
|
10
|
+
from bs4 import BeautifulSoup as bs
|
11
|
+
from lxml import html, etree
|
12
|
+
|
13
|
+
# flowtask related.
|
14
|
+
from querysource.libs.encoders import DefaultEncoder
|
15
|
+
from ...exceptions import ActionError
|
16
|
+
from .abstract import AbstractAction
|
17
|
+
|
18
|
+
|
19
|
+
class AbstractREST(AbstractAction):
|
20
|
+
"""AbstractREST.
|
21
|
+
|
22
|
+
Base class for actions that interact with REST APIs.
|
23
|
+
"""
|
24
|
+
|
25
|
+
timeout: int = 60
|
26
|
+
method: str = "get"
|
27
|
+
headers = {
|
28
|
+
"Accept-Encoding": "gzip, deflate",
|
29
|
+
"DNT": "1",
|
30
|
+
"Connection": "keep-alive",
|
31
|
+
"Upgrade-Insecure-Requests": "1",
|
32
|
+
"cache-control": "max-age=0",
|
33
|
+
}
|
34
|
+
auth_type: str = "key"
|
35
|
+
token_type: str = "Bearer"
|
36
|
+
data_format: str = "raw"
|
37
|
+
|
38
|
+
def __init__(self, hook, *args, **kwargs):
|
39
|
+
self.timeout = int(kwargs.pop("timeout", 60))
|
40
|
+
self.url: str = ""
|
41
|
+
## Auth Object:
|
42
|
+
self.auth: dict = {}
|
43
|
+
self.accept = kwargs.pop("accept", "application/json")
|
44
|
+
self.content_type = kwargs.pop("content_type", "application/json")
|
45
|
+
self._last_execution: dict = {}
|
46
|
+
## Headers
|
47
|
+
try:
|
48
|
+
headers = kwargs["headers"]
|
49
|
+
except KeyError:
|
50
|
+
headers = {}
|
51
|
+
self.headers = {
|
52
|
+
"Accept": self.accept,
|
53
|
+
"Content-Type": self.content_type,
|
54
|
+
**self.headers,
|
55
|
+
**headers,
|
56
|
+
}
|
57
|
+
# Language:
|
58
|
+
self.language: list = kwargs.pop("language", ["en-GB", "en-US"])
|
59
|
+
langs = []
|
60
|
+
for lang in self.language:
|
61
|
+
lang_str = f"{lang};q=0.9"
|
62
|
+
langs.append(lang_str)
|
63
|
+
langs.append("ml;q=0.7")
|
64
|
+
self.headers["Accept-Language"] = ",".join(langs)
|
65
|
+
super(AbstractREST, self).__init__(*args, **kwargs)
|
66
|
+
self._encoder = DefaultEncoder()
|
67
|
+
|
68
|
+
def build_url(self, url, queryparams: str = None, args: dict = None):
|
69
|
+
if isinstance(args, dict):
|
70
|
+
u = url.format(**args)
|
71
|
+
else:
|
72
|
+
u = url
|
73
|
+
if queryparams:
|
74
|
+
if "?" in u:
|
75
|
+
full_url = u + "&" + queryparams
|
76
|
+
else:
|
77
|
+
full_url = u + "?" + queryparams
|
78
|
+
else:
|
79
|
+
full_url = u
|
80
|
+
self._logger.debug(f"Action URL: {full_url!s}")
|
81
|
+
return full_url
|
82
|
+
|
83
|
+
async def session(
|
84
|
+
self,
|
85
|
+
url: str = None,
|
86
|
+
method: str = None,
|
87
|
+
data: dict = None,
|
88
|
+
cookies: dict = None,
|
89
|
+
headers: dict = None,
|
90
|
+
):
|
91
|
+
"""
|
92
|
+
session.
|
93
|
+
Connect to an http source using aiohttp.
|
94
|
+
"""
|
95
|
+
timeout = aiohttp.ClientTimeout(total=self.timeout)
|
96
|
+
if not url:
|
97
|
+
url = self.url
|
98
|
+
if not method:
|
99
|
+
method = self.method
|
100
|
+
auth = {}
|
101
|
+
if self.auth:
|
102
|
+
auth = self.auth
|
103
|
+
if isinstance(headers, dict):
|
104
|
+
headers = {**self.headers, **headers}
|
105
|
+
else:
|
106
|
+
headers = self.headers
|
107
|
+
async with aiohttp.ClientSession(auth) as session:
|
108
|
+
if method == "get":
|
109
|
+
async with session.get(
|
110
|
+
url, timeout=timeout, auth=auth, cookies=cookies, headers=headers
|
111
|
+
) as response:
|
112
|
+
return response
|
113
|
+
elif method == "post":
|
114
|
+
async with session.post(
|
115
|
+
url,
|
116
|
+
headers=headers,
|
117
|
+
timeout=timeout,
|
118
|
+
auth=auth,
|
119
|
+
data=data,
|
120
|
+
cookies=cookies,
|
121
|
+
) as response:
|
122
|
+
return response
|
123
|
+
|
124
|
+
async def request(
|
125
|
+
self,
|
126
|
+
url,
|
127
|
+
method: str = "get",
|
128
|
+
data: dict = None,
|
129
|
+
cookies: dict = None,
|
130
|
+
headers: dict = None,
|
131
|
+
):
|
132
|
+
"""
|
133
|
+
request
|
134
|
+
connect to an http source
|
135
|
+
"""
|
136
|
+
result = []
|
137
|
+
error = {}
|
138
|
+
auth = None
|
139
|
+
executor = ThreadPoolExecutor(max_workers=4)
|
140
|
+
if headers is not None and isinstance(headers, dict):
|
141
|
+
self.headers = {**self.headers, **headers}
|
142
|
+
if self.auth_type == "apikey":
|
143
|
+
self.headers["Authorization"] = f"{self.token_type} {self.auth['apikey']}"
|
144
|
+
elif self.auth:
|
145
|
+
if "apikey" in self.auth:
|
146
|
+
self.headers[
|
147
|
+
"Authorization"
|
148
|
+
] = f"{self.token_type} {self.auth['apikey']}"
|
149
|
+
elif self.auth_type == "api_key":
|
150
|
+
self.headers = {**self.headers, **self.auth}
|
151
|
+
elif self.auth_type == "key":
|
152
|
+
url = self.build_url(
|
153
|
+
url, args=self.arguments, queryparams=urlencode(self.auth)
|
154
|
+
)
|
155
|
+
elif self.auth_type == "basic":
|
156
|
+
auth = HTTPBasicAuth(*self.auth)
|
157
|
+
else:
|
158
|
+
auth = HTTPBasicAuth(*self.auth)
|
159
|
+
elif self._user:
|
160
|
+
auth = HTTPBasicAuth(self._user, self._pwd)
|
161
|
+
elif self.auth_type == "basic":
|
162
|
+
auth = HTTPBasicAuth(self._user, self._pwd)
|
163
|
+
## Start connection:
|
164
|
+
self._logger.notice(f"HTTP: Connecting to {url} using {method}")
|
165
|
+
if method == "get":
|
166
|
+
my_request = partial(
|
167
|
+
requests.get,
|
168
|
+
headers=self.headers,
|
169
|
+
verify=False,
|
170
|
+
auth=auth,
|
171
|
+
params=data,
|
172
|
+
timeout=self.timeout,
|
173
|
+
cookies=cookies,
|
174
|
+
)
|
175
|
+
elif method == "post":
|
176
|
+
if self.data_format == "json":
|
177
|
+
data = self._encoder.dumps(data)
|
178
|
+
my_request = partial(
|
179
|
+
requests.post,
|
180
|
+
headers=self.headers,
|
181
|
+
json={"query": data},
|
182
|
+
verify=False,
|
183
|
+
auth=auth,
|
184
|
+
timeout=self.timeout,
|
185
|
+
cookies=cookies,
|
186
|
+
)
|
187
|
+
else:
|
188
|
+
data = self._encoder.dumps(data)
|
189
|
+
my_request = partial(
|
190
|
+
requests.post,
|
191
|
+
headers=self.headers,
|
192
|
+
data=data,
|
193
|
+
verify=False,
|
194
|
+
auth=auth,
|
195
|
+
timeout=self.timeout,
|
196
|
+
cookies=cookies,
|
197
|
+
)
|
198
|
+
elif method == "put":
|
199
|
+
my_request = partial(
|
200
|
+
requests.put,
|
201
|
+
headers=self.headers,
|
202
|
+
data=data,
|
203
|
+
verify=False,
|
204
|
+
auth=auth,
|
205
|
+
timeout=self.timeout,
|
206
|
+
)
|
207
|
+
elif method == "delete":
|
208
|
+
my_request = partial(
|
209
|
+
requests.delete,
|
210
|
+
headers=self.headers,
|
211
|
+
data=data,
|
212
|
+
verify=False,
|
213
|
+
auth=auth,
|
214
|
+
timeout=self.timeout,
|
215
|
+
)
|
216
|
+
elif method == "patch":
|
217
|
+
my_request = partial(
|
218
|
+
requests.patch,
|
219
|
+
headers=self.headers,
|
220
|
+
data=data,
|
221
|
+
verify=False,
|
222
|
+
auth=auth,
|
223
|
+
timeout=self.timeout,
|
224
|
+
)
|
225
|
+
else:
|
226
|
+
my_request = partial(
|
227
|
+
requests.post,
|
228
|
+
headers=self.headers,
|
229
|
+
data=data,
|
230
|
+
verify=False,
|
231
|
+
auth=auth,
|
232
|
+
timeout=self.timeout,
|
233
|
+
cookies=cookies,
|
234
|
+
)
|
235
|
+
# making request
|
236
|
+
loop = asyncio.get_event_loop()
|
237
|
+
future = [loop.run_in_executor(executor, my_request, url)]
|
238
|
+
try:
|
239
|
+
result, error = await self.process_request(future)
|
240
|
+
if error:
|
241
|
+
if isinstance(error, BaseException):
|
242
|
+
raise error
|
243
|
+
elif isinstance(error, bs):
|
244
|
+
return (result, error)
|
245
|
+
else:
|
246
|
+
raise ActionError(str(error))
|
247
|
+
## saving last execution parameters:
|
248
|
+
self._last_execution = {
|
249
|
+
"url": self.url,
|
250
|
+
"method": method,
|
251
|
+
"data": data,
|
252
|
+
"auth": bool(auth),
|
253
|
+
"headers": self.headers,
|
254
|
+
}
|
255
|
+
return (result, error)
|
256
|
+
except Exception as err:
|
257
|
+
self._logger.exception(err)
|
258
|
+
raise ActionError(f"Error: {err}") from err
|
259
|
+
|
260
|
+
async def process_request(self, future):
|
261
|
+
try:
|
262
|
+
loop = asyncio.get_running_loop()
|
263
|
+
asyncio.set_event_loop(loop)
|
264
|
+
error = None
|
265
|
+
for response in await asyncio.gather(*future):
|
266
|
+
# getting the result, based on the Accept logic
|
267
|
+
if self.accept in (
|
268
|
+
"application/xhtml+xml",
|
269
|
+
"text/html",
|
270
|
+
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
|
271
|
+
):
|
272
|
+
try:
|
273
|
+
# html parser for lxml
|
274
|
+
self._parser = html.fromstring(response.text)
|
275
|
+
# Returning a BeautifulSoup parser
|
276
|
+
self._bs = bs(response.text, "html.parser")
|
277
|
+
result = self._bs
|
278
|
+
except (AttributeError, ValueError) as e:
|
279
|
+
error = e
|
280
|
+
elif self.accept == "application/xml":
|
281
|
+
try:
|
282
|
+
self._parser = etree.fromstring(response.text)
|
283
|
+
except (AttributeError, ValueError) as e:
|
284
|
+
error = e
|
285
|
+
elif self.accept in ("text/plain", "text/csv"):
|
286
|
+
result = response.text
|
287
|
+
elif self.accept == "application/json":
|
288
|
+
try:
|
289
|
+
result = self._encoder.loads(
|
290
|
+
response.text
|
291
|
+
) # instead using .json method
|
292
|
+
# result = response.json()
|
293
|
+
except (AttributeError, ValueError) as e:
|
294
|
+
self._logger.error(e)
|
295
|
+
# is not an json, try first with beautiful soup:
|
296
|
+
try:
|
297
|
+
self._bs = bs(response.text, "html.parser")
|
298
|
+
result = self._bs
|
299
|
+
except (AttributeError, ValueError) as ex:
|
300
|
+
error = ex
|
301
|
+
else:
|
302
|
+
try:
|
303
|
+
self._bs = bs(response.text, "html.parser")
|
304
|
+
except (AttributeError, ValueError) as ex:
|
305
|
+
error = ex
|
306
|
+
result = response.text
|
307
|
+
return (result, error)
|
308
|
+
except requests.exceptions.ProxyError as err:
|
309
|
+
raise ActionError(f"Proxy Connection Error: {err!r}") from err
|
310
|
+
except requests.ReadTimeout as ex:
|
311
|
+
return ([], ex)
|
312
|
+
except requests.exceptions.Timeout as err:
|
313
|
+
return ([], err)
|
314
|
+
except requests.exceptions.HTTPError as err:
|
315
|
+
return ([], err)
|
316
|
+
except (requests.exceptions.RequestException,) as e:
|
317
|
+
raise ActionError(f"HTTP Connection Error: {e!r}") from e
|
318
|
+
except Exception as e:
|
319
|
+
self.logger.exception(e)
|
320
|
+
raise ActionError(f"HTTP Connection Error: {e!r}") from e
|