ai-parrot 0.17.2__cp310-cp310-manylinux_2_17_x86_64.manylinux2014_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.
- agentui/.prettierrc +15 -0
- agentui/QUICKSTART.md +272 -0
- agentui/README.md +59 -0
- agentui/env.example +16 -0
- agentui/jsconfig.json +14 -0
- agentui/package-lock.json +4242 -0
- agentui/package.json +34 -0
- agentui/scripts/postinstall/apply-patches.mjs +260 -0
- agentui/src/app.css +61 -0
- agentui/src/app.d.ts +13 -0
- agentui/src/app.html +12 -0
- agentui/src/components/LoadingSpinner.svelte +64 -0
- agentui/src/components/ThemeSwitcher.svelte +159 -0
- agentui/src/components/index.js +4 -0
- agentui/src/lib/api/bots.ts +60 -0
- agentui/src/lib/api/chat.ts +22 -0
- agentui/src/lib/api/http.ts +25 -0
- agentui/src/lib/components/BotCard.svelte +33 -0
- agentui/src/lib/components/ChatBubble.svelte +63 -0
- agentui/src/lib/components/Toast.svelte +21 -0
- agentui/src/lib/config.ts +20 -0
- agentui/src/lib/stores/auth.svelte.ts +73 -0
- agentui/src/lib/stores/theme.svelte.js +64 -0
- agentui/src/lib/stores/toast.svelte.ts +31 -0
- agentui/src/lib/utils/conversation.ts +39 -0
- agentui/src/routes/+layout.svelte +20 -0
- agentui/src/routes/+page.svelte +232 -0
- agentui/src/routes/login/+page.svelte +200 -0
- agentui/src/routes/talk/[agentId]/+page.svelte +297 -0
- agentui/src/routes/talk/[agentId]/+page.ts +7 -0
- agentui/static/README.md +1 -0
- agentui/svelte.config.js +11 -0
- agentui/tailwind.config.ts +53 -0
- agentui/tsconfig.json +3 -0
- agentui/vite.config.ts +10 -0
- ai_parrot-0.17.2.dist-info/METADATA +472 -0
- ai_parrot-0.17.2.dist-info/RECORD +535 -0
- ai_parrot-0.17.2.dist-info/WHEEL +6 -0
- ai_parrot-0.17.2.dist-info/entry_points.txt +2 -0
- ai_parrot-0.17.2.dist-info/licenses/LICENSE +21 -0
- ai_parrot-0.17.2.dist-info/top_level.txt +6 -0
- crew-builder/.prettierrc +15 -0
- crew-builder/QUICKSTART.md +259 -0
- crew-builder/README.md +113 -0
- crew-builder/env.example +17 -0
- crew-builder/jsconfig.json +14 -0
- crew-builder/package-lock.json +4182 -0
- crew-builder/package.json +37 -0
- crew-builder/scripts/postinstall/apply-patches.mjs +260 -0
- crew-builder/src/app.css +62 -0
- crew-builder/src/app.d.ts +13 -0
- crew-builder/src/app.html +12 -0
- crew-builder/src/components/LoadingSpinner.svelte +64 -0
- crew-builder/src/components/ThemeSwitcher.svelte +149 -0
- crew-builder/src/components/index.js +9 -0
- crew-builder/src/lib/api/bots.ts +60 -0
- crew-builder/src/lib/api/chat.ts +80 -0
- crew-builder/src/lib/api/client.ts +56 -0
- crew-builder/src/lib/api/crew/crew.ts +136 -0
- crew-builder/src/lib/api/index.ts +5 -0
- crew-builder/src/lib/api/o365/auth.ts +65 -0
- crew-builder/src/lib/auth/auth.ts +54 -0
- crew-builder/src/lib/components/AgentNode.svelte +43 -0
- crew-builder/src/lib/components/BotCard.svelte +33 -0
- crew-builder/src/lib/components/ChatBubble.svelte +67 -0
- crew-builder/src/lib/components/ConfigPanel.svelte +278 -0
- crew-builder/src/lib/components/JsonTreeNode.svelte +76 -0
- crew-builder/src/lib/components/JsonViewer.svelte +24 -0
- crew-builder/src/lib/components/MarkdownEditor.svelte +48 -0
- crew-builder/src/lib/components/ThemeToggle.svelte +36 -0
- crew-builder/src/lib/components/Toast.svelte +67 -0
- crew-builder/src/lib/components/Toolbar.svelte +157 -0
- crew-builder/src/lib/components/index.ts +10 -0
- crew-builder/src/lib/config.ts +8 -0
- crew-builder/src/lib/stores/auth.svelte.ts +228 -0
- crew-builder/src/lib/stores/crewStore.ts +369 -0
- crew-builder/src/lib/stores/theme.svelte.js +145 -0
- crew-builder/src/lib/stores/toast.svelte.ts +69 -0
- crew-builder/src/lib/utils/conversation.ts +39 -0
- crew-builder/src/lib/utils/markdown.ts +122 -0
- crew-builder/src/lib/utils/talkHistory.ts +47 -0
- crew-builder/src/routes/+layout.svelte +20 -0
- crew-builder/src/routes/+page.svelte +539 -0
- crew-builder/src/routes/agents/+page.svelte +247 -0
- crew-builder/src/routes/agents/[agentId]/+page.svelte +288 -0
- crew-builder/src/routes/agents/[agentId]/+page.ts +7 -0
- crew-builder/src/routes/builder/+page.svelte +204 -0
- crew-builder/src/routes/crew/ask/+page.svelte +1052 -0
- crew-builder/src/routes/crew/ask/+page.ts +1 -0
- crew-builder/src/routes/integrations/o365/+page.svelte +304 -0
- crew-builder/src/routes/login/+page.svelte +197 -0
- crew-builder/src/routes/talk/[agentId]/+page.svelte +487 -0
- crew-builder/src/routes/talk/[agentId]/+page.ts +7 -0
- crew-builder/static/README.md +1 -0
- crew-builder/svelte.config.js +11 -0
- crew-builder/tailwind.config.ts +53 -0
- crew-builder/tsconfig.json +3 -0
- crew-builder/vite.config.ts +10 -0
- mcp_servers/calculator_server.py +309 -0
- parrot/__init__.py +27 -0
- parrot/__pycache__/__init__.cpython-310.pyc +0 -0
- parrot/__pycache__/version.cpython-310.pyc +0 -0
- parrot/_version.py +34 -0
- parrot/a2a/__init__.py +48 -0
- parrot/a2a/client.py +658 -0
- parrot/a2a/discovery.py +89 -0
- parrot/a2a/mixin.py +257 -0
- parrot/a2a/models.py +376 -0
- parrot/a2a/server.py +770 -0
- parrot/agents/__init__.py +29 -0
- parrot/bots/__init__.py +12 -0
- parrot/bots/a2a_agent.py +19 -0
- parrot/bots/abstract.py +3139 -0
- parrot/bots/agent.py +1129 -0
- parrot/bots/basic.py +9 -0
- parrot/bots/chatbot.py +669 -0
- parrot/bots/data.py +1618 -0
- parrot/bots/database/__init__.py +5 -0
- parrot/bots/database/abstract.py +3071 -0
- parrot/bots/database/cache.py +286 -0
- parrot/bots/database/models.py +468 -0
- parrot/bots/database/prompts.py +154 -0
- parrot/bots/database/retries.py +98 -0
- parrot/bots/database/router.py +269 -0
- parrot/bots/database/sql.py +41 -0
- parrot/bots/db/__init__.py +6 -0
- parrot/bots/db/abstract.py +556 -0
- parrot/bots/db/bigquery.py +602 -0
- parrot/bots/db/cache.py +85 -0
- parrot/bots/db/documentdb.py +668 -0
- parrot/bots/db/elastic.py +1014 -0
- parrot/bots/db/influx.py +898 -0
- parrot/bots/db/mock.py +96 -0
- parrot/bots/db/multi.py +783 -0
- parrot/bots/db/prompts.py +185 -0
- parrot/bots/db/sql.py +1255 -0
- parrot/bots/db/tools.py +212 -0
- parrot/bots/document.py +680 -0
- parrot/bots/hrbot.py +15 -0
- parrot/bots/kb.py +170 -0
- parrot/bots/mcp.py +36 -0
- parrot/bots/orchestration/README.md +463 -0
- parrot/bots/orchestration/__init__.py +1 -0
- parrot/bots/orchestration/agent.py +155 -0
- parrot/bots/orchestration/crew.py +3330 -0
- parrot/bots/orchestration/fsm.py +1179 -0
- parrot/bots/orchestration/hr.py +434 -0
- parrot/bots/orchestration/storage/__init__.py +4 -0
- parrot/bots/orchestration/storage/memory.py +100 -0
- parrot/bots/orchestration/storage/mixin.py +119 -0
- parrot/bots/orchestration/verify.py +202 -0
- parrot/bots/product.py +204 -0
- parrot/bots/prompts/__init__.py +96 -0
- parrot/bots/prompts/agents.py +155 -0
- parrot/bots/prompts/data.py +216 -0
- parrot/bots/prompts/output_generation.py +8 -0
- parrot/bots/scraper/__init__.py +3 -0
- parrot/bots/scraper/models.py +122 -0
- parrot/bots/scraper/scraper.py +1173 -0
- parrot/bots/scraper/templates.py +115 -0
- parrot/bots/stores/__init__.py +5 -0
- parrot/bots/stores/local.py +172 -0
- parrot/bots/webdev.py +81 -0
- parrot/cli.py +17 -0
- parrot/clients/__init__.py +16 -0
- parrot/clients/base.py +1491 -0
- parrot/clients/claude.py +1191 -0
- parrot/clients/factory.py +129 -0
- parrot/clients/google.py +4567 -0
- parrot/clients/gpt.py +1975 -0
- parrot/clients/grok.py +432 -0
- parrot/clients/groq.py +986 -0
- parrot/clients/hf.py +582 -0
- parrot/clients/models.py +18 -0
- parrot/conf.py +395 -0
- parrot/embeddings/__init__.py +9 -0
- parrot/embeddings/base.py +157 -0
- parrot/embeddings/google.py +98 -0
- parrot/embeddings/huggingface.py +74 -0
- parrot/embeddings/openai.py +84 -0
- parrot/embeddings/processor.py +88 -0
- parrot/exceptions.c +13868 -0
- parrot/exceptions.cpython-310-x86_64-linux-gnu.so +0 -0
- parrot/exceptions.pxd +22 -0
- parrot/exceptions.pxi +15 -0
- parrot/exceptions.pyx +44 -0
- parrot/generators/__init__.py +29 -0
- parrot/generators/base.py +200 -0
- parrot/generators/html.py +293 -0
- parrot/generators/react.py +205 -0
- parrot/generators/streamlit.py +203 -0
- parrot/generators/template.py +105 -0
- parrot/handlers/__init__.py +4 -0
- parrot/handlers/agent.py +861 -0
- parrot/handlers/agents/__init__.py +1 -0
- parrot/handlers/agents/abstract.py +900 -0
- parrot/handlers/bots.py +338 -0
- parrot/handlers/chat.py +915 -0
- parrot/handlers/creation.sql +192 -0
- parrot/handlers/crew/ARCHITECTURE.md +362 -0
- parrot/handlers/crew/README_BOTMANAGER_PERSISTENCE.md +303 -0
- parrot/handlers/crew/README_REDIS_PERSISTENCE.md +366 -0
- parrot/handlers/crew/__init__.py +0 -0
- parrot/handlers/crew/handler.py +801 -0
- parrot/handlers/crew/models.py +229 -0
- parrot/handlers/crew/redis_persistence.py +523 -0
- parrot/handlers/jobs/__init__.py +10 -0
- parrot/handlers/jobs/job.py +384 -0
- parrot/handlers/jobs/mixin.py +627 -0
- parrot/handlers/jobs/models.py +115 -0
- parrot/handlers/jobs/worker.py +31 -0
- parrot/handlers/models.py +596 -0
- parrot/handlers/o365_auth.py +105 -0
- parrot/handlers/stream.py +337 -0
- parrot/interfaces/__init__.py +6 -0
- parrot/interfaces/aws.py +143 -0
- parrot/interfaces/credentials.py +113 -0
- parrot/interfaces/database.py +27 -0
- parrot/interfaces/google.py +1123 -0
- parrot/interfaces/hierarchy.py +1227 -0
- parrot/interfaces/http.py +651 -0
- parrot/interfaces/images/__init__.py +0 -0
- parrot/interfaces/images/plugins/__init__.py +24 -0
- parrot/interfaces/images/plugins/abstract.py +58 -0
- parrot/interfaces/images/plugins/analisys.py +148 -0
- parrot/interfaces/images/plugins/classify.py +150 -0
- parrot/interfaces/images/plugins/classifybase.py +182 -0
- parrot/interfaces/images/plugins/detect.py +150 -0
- parrot/interfaces/images/plugins/exif.py +1103 -0
- parrot/interfaces/images/plugins/hash.py +52 -0
- parrot/interfaces/images/plugins/vision.py +104 -0
- parrot/interfaces/images/plugins/yolo.py +66 -0
- parrot/interfaces/images/plugins/zerodetect.py +197 -0
- parrot/interfaces/o365.py +978 -0
- parrot/interfaces/onedrive.py +822 -0
- parrot/interfaces/sharepoint.py +1435 -0
- parrot/interfaces/soap.py +257 -0
- parrot/loaders/__init__.py +8 -0
- parrot/loaders/abstract.py +1131 -0
- parrot/loaders/audio.py +199 -0
- parrot/loaders/basepdf.py +53 -0
- parrot/loaders/basevideo.py +1568 -0
- parrot/loaders/csv.py +409 -0
- parrot/loaders/docx.py +116 -0
- parrot/loaders/epubloader.py +316 -0
- parrot/loaders/excel.py +199 -0
- parrot/loaders/factory.py +55 -0
- parrot/loaders/files/__init__.py +0 -0
- parrot/loaders/files/abstract.py +39 -0
- parrot/loaders/files/html.py +26 -0
- parrot/loaders/files/text.py +63 -0
- parrot/loaders/html.py +152 -0
- parrot/loaders/markdown.py +442 -0
- parrot/loaders/pdf.py +373 -0
- parrot/loaders/pdfmark.py +320 -0
- parrot/loaders/pdftables.py +506 -0
- parrot/loaders/ppt.py +476 -0
- parrot/loaders/qa.py +63 -0
- parrot/loaders/splitters/__init__.py +10 -0
- parrot/loaders/splitters/base.py +138 -0
- parrot/loaders/splitters/md.py +228 -0
- parrot/loaders/splitters/token.py +143 -0
- parrot/loaders/txt.py +26 -0
- parrot/loaders/video.py +89 -0
- parrot/loaders/videolocal.py +218 -0
- parrot/loaders/videounderstanding.py +377 -0
- parrot/loaders/vimeo.py +167 -0
- parrot/loaders/web.py +599 -0
- parrot/loaders/youtube.py +504 -0
- parrot/manager/__init__.py +5 -0
- parrot/manager/manager.py +1030 -0
- parrot/mcp/__init__.py +28 -0
- parrot/mcp/adapter.py +105 -0
- parrot/mcp/cli.py +174 -0
- parrot/mcp/client.py +119 -0
- parrot/mcp/config.py +75 -0
- parrot/mcp/integration.py +842 -0
- parrot/mcp/oauth.py +933 -0
- parrot/mcp/server.py +225 -0
- parrot/mcp/transports/__init__.py +3 -0
- parrot/mcp/transports/base.py +279 -0
- parrot/mcp/transports/grpc_session.py +163 -0
- parrot/mcp/transports/http.py +312 -0
- parrot/mcp/transports/mcp.proto +108 -0
- parrot/mcp/transports/quic.py +1082 -0
- parrot/mcp/transports/sse.py +330 -0
- parrot/mcp/transports/stdio.py +309 -0
- parrot/mcp/transports/unix.py +395 -0
- parrot/mcp/transports/websocket.py +547 -0
- parrot/memory/__init__.py +16 -0
- parrot/memory/abstract.py +209 -0
- parrot/memory/agent.py +32 -0
- parrot/memory/cache.py +175 -0
- parrot/memory/core.py +555 -0
- parrot/memory/file.py +153 -0
- parrot/memory/mem.py +131 -0
- parrot/memory/redis.py +613 -0
- parrot/models/__init__.py +46 -0
- parrot/models/basic.py +118 -0
- parrot/models/compliance.py +208 -0
- parrot/models/crew.py +395 -0
- parrot/models/detections.py +654 -0
- parrot/models/generation.py +85 -0
- parrot/models/google.py +223 -0
- parrot/models/groq.py +23 -0
- parrot/models/openai.py +30 -0
- parrot/models/outputs.py +285 -0
- parrot/models/responses.py +938 -0
- parrot/notifications/__init__.py +743 -0
- parrot/openapi/__init__.py +3 -0
- parrot/openapi/components.yaml +641 -0
- parrot/openapi/config.py +322 -0
- parrot/outputs/__init__.py +32 -0
- parrot/outputs/formats/__init__.py +108 -0
- parrot/outputs/formats/altair.py +359 -0
- parrot/outputs/formats/application.py +122 -0
- parrot/outputs/formats/base.py +351 -0
- parrot/outputs/formats/bokeh.py +356 -0
- parrot/outputs/formats/card.py +424 -0
- parrot/outputs/formats/chart.py +436 -0
- parrot/outputs/formats/d3.py +255 -0
- parrot/outputs/formats/echarts.py +310 -0
- parrot/outputs/formats/generators/__init__.py +0 -0
- parrot/outputs/formats/generators/abstract.py +61 -0
- parrot/outputs/formats/generators/panel.py +145 -0
- parrot/outputs/formats/generators/streamlit.py +86 -0
- parrot/outputs/formats/generators/terminal.py +63 -0
- parrot/outputs/formats/holoviews.py +310 -0
- parrot/outputs/formats/html.py +147 -0
- parrot/outputs/formats/jinja2.py +46 -0
- parrot/outputs/formats/json.py +87 -0
- parrot/outputs/formats/map.py +933 -0
- parrot/outputs/formats/markdown.py +172 -0
- parrot/outputs/formats/matplotlib.py +237 -0
- parrot/outputs/formats/mixins/__init__.py +0 -0
- parrot/outputs/formats/mixins/emaps.py +855 -0
- parrot/outputs/formats/plotly.py +341 -0
- parrot/outputs/formats/seaborn.py +310 -0
- parrot/outputs/formats/table.py +397 -0
- parrot/outputs/formats/template_report.py +138 -0
- parrot/outputs/formats/yaml.py +125 -0
- parrot/outputs/formatter.py +152 -0
- parrot/outputs/templates/__init__.py +95 -0
- parrot/pipelines/__init__.py +0 -0
- parrot/pipelines/abstract.py +210 -0
- parrot/pipelines/detector.py +124 -0
- parrot/pipelines/models.py +90 -0
- parrot/pipelines/planogram.py +3002 -0
- parrot/pipelines/table.sql +97 -0
- parrot/plugins/__init__.py +106 -0
- parrot/plugins/importer.py +80 -0
- parrot/py.typed +0 -0
- parrot/registry/__init__.py +18 -0
- parrot/registry/registry.py +594 -0
- parrot/scheduler/__init__.py +1189 -0
- parrot/scheduler/models.py +60 -0
- parrot/security/__init__.py +16 -0
- parrot/security/prompt_injection.py +268 -0
- parrot/security/security_events.sql +25 -0
- parrot/services/__init__.py +1 -0
- parrot/services/mcp/__init__.py +8 -0
- parrot/services/mcp/config.py +13 -0
- parrot/services/mcp/server.py +295 -0
- parrot/services/o365_remote_auth.py +235 -0
- parrot/stores/__init__.py +7 -0
- parrot/stores/abstract.py +352 -0
- parrot/stores/arango.py +1090 -0
- parrot/stores/bigquery.py +1377 -0
- parrot/stores/cache.py +106 -0
- parrot/stores/empty.py +10 -0
- parrot/stores/faiss_store.py +1157 -0
- parrot/stores/kb/__init__.py +9 -0
- parrot/stores/kb/abstract.py +68 -0
- parrot/stores/kb/cache.py +165 -0
- parrot/stores/kb/doc.py +325 -0
- parrot/stores/kb/hierarchy.py +346 -0
- parrot/stores/kb/local.py +457 -0
- parrot/stores/kb/prompt.py +28 -0
- parrot/stores/kb/redis.py +659 -0
- parrot/stores/kb/store.py +115 -0
- parrot/stores/kb/user.py +374 -0
- parrot/stores/models.py +59 -0
- parrot/stores/pgvector.py +3 -0
- parrot/stores/postgres.py +2853 -0
- parrot/stores/utils/__init__.py +0 -0
- parrot/stores/utils/chunking.py +197 -0
- parrot/telemetry/__init__.py +3 -0
- parrot/telemetry/mixin.py +111 -0
- parrot/template/__init__.py +3 -0
- parrot/template/engine.py +259 -0
- parrot/tools/__init__.py +23 -0
- parrot/tools/abstract.py +644 -0
- parrot/tools/agent.py +363 -0
- parrot/tools/arangodbsearch.py +537 -0
- parrot/tools/arxiv_tool.py +188 -0
- parrot/tools/calculator/__init__.py +3 -0
- parrot/tools/calculator/operations/__init__.py +38 -0
- parrot/tools/calculator/operations/calculus.py +80 -0
- parrot/tools/calculator/operations/statistics.py +76 -0
- parrot/tools/calculator/tool.py +150 -0
- parrot/tools/cloudwatch.py +988 -0
- parrot/tools/codeinterpreter/__init__.py +127 -0
- parrot/tools/codeinterpreter/executor.py +371 -0
- parrot/tools/codeinterpreter/internals.py +473 -0
- parrot/tools/codeinterpreter/models.py +643 -0
- parrot/tools/codeinterpreter/prompts.py +224 -0
- parrot/tools/codeinterpreter/tool.py +664 -0
- parrot/tools/company_info/__init__.py +6 -0
- parrot/tools/company_info/tool.py +1138 -0
- parrot/tools/correlationanalysis.py +437 -0
- parrot/tools/database/abstract.py +286 -0
- parrot/tools/database/bq.py +115 -0
- parrot/tools/database/cache.py +284 -0
- parrot/tools/database/models.py +95 -0
- parrot/tools/database/pg.py +343 -0
- parrot/tools/databasequery.py +1159 -0
- parrot/tools/db.py +1800 -0
- parrot/tools/ddgo.py +370 -0
- parrot/tools/decorators.py +271 -0
- parrot/tools/dftohtml.py +282 -0
- parrot/tools/document.py +549 -0
- parrot/tools/ecs.py +819 -0
- parrot/tools/edareport.py +368 -0
- parrot/tools/elasticsearch.py +1049 -0
- parrot/tools/employees.py +462 -0
- parrot/tools/epson/__init__.py +96 -0
- parrot/tools/excel.py +683 -0
- parrot/tools/file/__init__.py +13 -0
- parrot/tools/file/abstract.py +76 -0
- parrot/tools/file/gcs.py +378 -0
- parrot/tools/file/local.py +284 -0
- parrot/tools/file/s3.py +511 -0
- parrot/tools/file/tmp.py +309 -0
- parrot/tools/file/tool.py +501 -0
- parrot/tools/file_reader.py +129 -0
- parrot/tools/flowtask/__init__.py +19 -0
- parrot/tools/flowtask/tool.py +761 -0
- parrot/tools/gittoolkit.py +508 -0
- parrot/tools/google/__init__.py +18 -0
- parrot/tools/google/base.py +169 -0
- parrot/tools/google/tools.py +1251 -0
- parrot/tools/googlelocation.py +5 -0
- parrot/tools/googleroutes.py +5 -0
- parrot/tools/googlesearch.py +5 -0
- parrot/tools/googlesitesearch.py +5 -0
- parrot/tools/googlevoice.py +2 -0
- parrot/tools/gvoice.py +695 -0
- parrot/tools/ibisworld/README.md +225 -0
- parrot/tools/ibisworld/__init__.py +11 -0
- parrot/tools/ibisworld/tool.py +366 -0
- parrot/tools/jiratoolkit.py +1718 -0
- parrot/tools/manager.py +1098 -0
- parrot/tools/math.py +152 -0
- parrot/tools/metadata.py +476 -0
- parrot/tools/msteams.py +1621 -0
- parrot/tools/msword.py +635 -0
- parrot/tools/multidb.py +580 -0
- parrot/tools/multistoresearch.py +369 -0
- parrot/tools/networkninja.py +167 -0
- parrot/tools/nextstop/__init__.py +4 -0
- parrot/tools/nextstop/base.py +286 -0
- parrot/tools/nextstop/employee.py +733 -0
- parrot/tools/nextstop/store.py +462 -0
- parrot/tools/notification.py +435 -0
- parrot/tools/o365/__init__.py +42 -0
- parrot/tools/o365/base.py +295 -0
- parrot/tools/o365/bundle.py +522 -0
- parrot/tools/o365/events.py +554 -0
- parrot/tools/o365/mail.py +992 -0
- parrot/tools/o365/onedrive.py +497 -0
- parrot/tools/o365/sharepoint.py +641 -0
- parrot/tools/openapi_toolkit.py +904 -0
- parrot/tools/openweather.py +527 -0
- parrot/tools/pdfprint.py +1001 -0
- parrot/tools/powerbi.py +518 -0
- parrot/tools/powerpoint.py +1113 -0
- parrot/tools/pricestool.py +146 -0
- parrot/tools/products/__init__.py +246 -0
- parrot/tools/prophet_tool.py +171 -0
- parrot/tools/pythonpandas.py +630 -0
- parrot/tools/pythonrepl.py +910 -0
- parrot/tools/qsource.py +436 -0
- parrot/tools/querytoolkit.py +395 -0
- parrot/tools/quickeda.py +827 -0
- parrot/tools/resttool.py +553 -0
- parrot/tools/retail/__init__.py +0 -0
- parrot/tools/retail/bby.py +528 -0
- parrot/tools/sandboxtool.py +703 -0
- parrot/tools/sassie/__init__.py +352 -0
- parrot/tools/scraping/__init__.py +7 -0
- parrot/tools/scraping/docs/select.md +466 -0
- parrot/tools/scraping/documentation.md +1278 -0
- parrot/tools/scraping/driver.py +436 -0
- parrot/tools/scraping/models.py +576 -0
- parrot/tools/scraping/options.py +85 -0
- parrot/tools/scraping/orchestrator.py +517 -0
- parrot/tools/scraping/readme.md +740 -0
- parrot/tools/scraping/tool.py +3115 -0
- parrot/tools/seasonaldetection.py +642 -0
- parrot/tools/shell_tool/__init__.py +5 -0
- parrot/tools/shell_tool/actions.py +408 -0
- parrot/tools/shell_tool/engine.py +155 -0
- parrot/tools/shell_tool/models.py +322 -0
- parrot/tools/shell_tool/tool.py +442 -0
- parrot/tools/site_search.py +214 -0
- parrot/tools/textfile.py +418 -0
- parrot/tools/think.py +378 -0
- parrot/tools/toolkit.py +298 -0
- parrot/tools/webapp_tool.py +187 -0
- parrot/tools/whatif.py +1279 -0
- parrot/tools/workday/MULTI_WSDL_EXAMPLE.md +249 -0
- parrot/tools/workday/__init__.py +6 -0
- parrot/tools/workday/models.py +1389 -0
- parrot/tools/workday/tool.py +1293 -0
- parrot/tools/yfinance_tool.py +306 -0
- parrot/tools/zipcode.py +217 -0
- parrot/utils/__init__.py +2 -0
- parrot/utils/helpers.py +73 -0
- parrot/utils/parsers/__init__.py +5 -0
- parrot/utils/parsers/toml.c +12078 -0
- parrot/utils/parsers/toml.cpython-310-x86_64-linux-gnu.so +0 -0
- parrot/utils/parsers/toml.pyx +21 -0
- parrot/utils/toml.py +11 -0
- parrot/utils/types.cpp +20936 -0
- parrot/utils/types.cpython-310-x86_64-linux-gnu.so +0 -0
- parrot/utils/types.pyx +213 -0
- parrot/utils/uv.py +11 -0
- parrot/version.py +10 -0
- parrot/yaml-rs/Cargo.lock +350 -0
- parrot/yaml-rs/Cargo.toml +19 -0
- parrot/yaml-rs/pyproject.toml +19 -0
- parrot/yaml-rs/python/yaml_rs/__init__.py +81 -0
- parrot/yaml-rs/src/lib.rs +222 -0
- requirements/docker-compose.yml +24 -0
- requirements/requirements-dev.txt +21 -0
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Enhanced Selenium Setup for WebScrapingTool
|
|
3
|
+
Extracted and adapted from SeleniumService class
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import asyncio
|
|
7
|
+
import logging
|
|
8
|
+
import random
|
|
9
|
+
from typing import Optional, Dict, Any, Literal, List
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
# WebDriver Manager for auto-installation
|
|
13
|
+
from webdriver_manager.chrome import ChromeDriverManager
|
|
14
|
+
from webdriver_manager.firefox import GeckoDriverManager
|
|
15
|
+
from webdriver_manager.microsoft import EdgeChromiumDriverManager
|
|
16
|
+
from webdriver_manager.core.driver_cache import DriverCacheManager
|
|
17
|
+
|
|
18
|
+
# Selenium imports
|
|
19
|
+
try:
|
|
20
|
+
from seleniumwire import webdriver
|
|
21
|
+
except ImportError:
|
|
22
|
+
from selenium import webdriver
|
|
23
|
+
from selenium.webdriver.chrome.service import Service as ChromeService
|
|
24
|
+
from selenium.webdriver.chrome.options import Options as ChromeOptions
|
|
25
|
+
from selenium.webdriver.firefox.service import Service as FirefoxService
|
|
26
|
+
from selenium.webdriver.firefox.options import Options as FirefoxOptions
|
|
27
|
+
from selenium.webdriver.edge.service import Service as EdgeService
|
|
28
|
+
from selenium.webdriver.edge.options import Options as EdgeOptions
|
|
29
|
+
from selenium.webdriver.safari.options import Options as SafariOptions
|
|
30
|
+
from selenium.webdriver.safari.service import Service as SafariService
|
|
31
|
+
|
|
32
|
+
# For undetected Chrome
|
|
33
|
+
try:
|
|
34
|
+
import undetected_chromedriver as uc
|
|
35
|
+
UNDETECTED_CHROME_AVAILABLE = True
|
|
36
|
+
except ImportError:
|
|
37
|
+
UNDETECTED_CHROME_AVAILABLE = False
|
|
38
|
+
|
|
39
|
+
from .options import (
|
|
40
|
+
USER_AGENTS,
|
|
41
|
+
MOBILE_USER_AGENTS,
|
|
42
|
+
MOBILE_DEVICES,
|
|
43
|
+
CHROME_OPTIONS,
|
|
44
|
+
UNDETECTED_OPTIONS,
|
|
45
|
+
FIREFOX_OPTIONS
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class SeleniumSetup:
|
|
50
|
+
"""
|
|
51
|
+
Selenium Setup Configuration.
|
|
52
|
+
"""
|
|
53
|
+
def __init__(
|
|
54
|
+
self,
|
|
55
|
+
browser: Literal['chrome', 'firefox', 'edge', 'safari', 'undetected'] = 'chrome',
|
|
56
|
+
headless: bool = True,
|
|
57
|
+
mobile: bool = False,
|
|
58
|
+
mobile_device: Optional[str] = None,
|
|
59
|
+
browser_binary: Optional[str] = None,
|
|
60
|
+
driver_binary: Optional[str] = None,
|
|
61
|
+
auto_install: bool = True,
|
|
62
|
+
cache_valid_range: int = 7,
|
|
63
|
+
user_data_dir: Optional[str] = None,
|
|
64
|
+
enable_logging: bool = True,
|
|
65
|
+
timeout: int = 10,
|
|
66
|
+
detach: bool = False,
|
|
67
|
+
debugger_address: Optional[str] = None,
|
|
68
|
+
**kwargs
|
|
69
|
+
):
|
|
70
|
+
"""
|
|
71
|
+
Initialize enhanced Selenium setup.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
browser: Browser type to use
|
|
75
|
+
headless: Run in headless mode
|
|
76
|
+
mobile: Enable mobile emulation (Chrome only)
|
|
77
|
+
mobile_device: Specific mobile device to emulate
|
|
78
|
+
browser_binary: Path to browser executable
|
|
79
|
+
driver_binary: Path to driver executable
|
|
80
|
+
auto_install: Auto-install driver if not found
|
|
81
|
+
cache_valid_range: Driver cache validity in days
|
|
82
|
+
user_data_dir: Custom user data directory
|
|
83
|
+
enable_logging: Enable detailed logging
|
|
84
|
+
"""
|
|
85
|
+
self.browser = browser
|
|
86
|
+
self.headless = headless
|
|
87
|
+
self.mobile = mobile
|
|
88
|
+
self.mobile_device = mobile_device or random.choice(MOBILE_DEVICES)
|
|
89
|
+
self.browser_binary = browser_binary
|
|
90
|
+
self.driver_binary = driver_binary
|
|
91
|
+
self.auto_install = auto_install
|
|
92
|
+
self.cache_valid_range = cache_valid_range
|
|
93
|
+
self.user_data_dir = user_data_dir
|
|
94
|
+
self.enable_logging = enable_logging
|
|
95
|
+
self.timeout = timeout or 10 # Default timeout for waits
|
|
96
|
+
# Additional configuration
|
|
97
|
+
self.disable_http2 = kwargs.get('disable_http2', False)
|
|
98
|
+
self.disable_images = kwargs.get('disable_images', False)
|
|
99
|
+
self.disable_javascript = kwargs.get('disable_javascript', False)
|
|
100
|
+
self.custom_user_agent = kwargs.get('custom_user_agent')
|
|
101
|
+
self.window_size = kwargs.get('window_size', (1920, 1080))
|
|
102
|
+
# Debugging options
|
|
103
|
+
self.detach = detach
|
|
104
|
+
self.debugger_address = debugger_address
|
|
105
|
+
# Setup logging
|
|
106
|
+
self.logger = logging.getLogger(
|
|
107
|
+
f"WebScrapingTool.{self.browser}"
|
|
108
|
+
)
|
|
109
|
+
if not self.enable_logging:
|
|
110
|
+
self.logger.setLevel(logging.WARNING)
|
|
111
|
+
|
|
112
|
+
def _get_user_agent(self) -> str:
|
|
113
|
+
"""Get appropriate user agent based on mobile/desktop mode"""
|
|
114
|
+
if self.custom_user_agent:
|
|
115
|
+
return self.custom_user_agent
|
|
116
|
+
|
|
117
|
+
if self.mobile:
|
|
118
|
+
return random.choice(MOBILE_USER_AGENTS)
|
|
119
|
+
else:
|
|
120
|
+
return random.choice(USER_AGENTS)
|
|
121
|
+
|
|
122
|
+
def _setup_chrome_options(self) -> ChromeOptions:
|
|
123
|
+
"""Setup Chrome/Chromium options"""
|
|
124
|
+
options = ChromeOptions()
|
|
125
|
+
|
|
126
|
+
# Add basic options
|
|
127
|
+
for option in CHROME_OPTIONS:
|
|
128
|
+
options.add_argument(option)
|
|
129
|
+
|
|
130
|
+
# Headless mode
|
|
131
|
+
if self.headless:
|
|
132
|
+
options.add_argument("--headless=new")
|
|
133
|
+
|
|
134
|
+
# Custom window size
|
|
135
|
+
options.add_argument(f"--window-size={self.window_size[0]},{self.window_size[1]}")
|
|
136
|
+
|
|
137
|
+
# User agent
|
|
138
|
+
user_agent = self._get_user_agent()
|
|
139
|
+
options.add_argument(f"--user-agent={user_agent}")
|
|
140
|
+
|
|
141
|
+
# enable performance logging
|
|
142
|
+
options.set_capability('goog:loggingPrefs', {'performance': 'ALL'})
|
|
143
|
+
|
|
144
|
+
# Browser binary
|
|
145
|
+
if self.browser_binary:
|
|
146
|
+
options.binary_location = self.browser_binary
|
|
147
|
+
|
|
148
|
+
# User data directory
|
|
149
|
+
if self.user_data_dir:
|
|
150
|
+
options.add_argument(f"--user-data-dir={self.user_data_dir}")
|
|
151
|
+
|
|
152
|
+
# Mobile emulation
|
|
153
|
+
if self.mobile:
|
|
154
|
+
mobile_emulation = {
|
|
155
|
+
# "deviceName": self.mobile_device,
|
|
156
|
+
"userAgent": user_agent
|
|
157
|
+
}
|
|
158
|
+
options.add_experimental_option("mobileEmulation", mobile_emulation)
|
|
159
|
+
self.logger.info(f"Mobile emulation enabled: {self.mobile_device}")
|
|
160
|
+
|
|
161
|
+
# Performance optimizations
|
|
162
|
+
if self.disable_images:
|
|
163
|
+
prefs = {"profile.managed_default_content_settings.images": 2}
|
|
164
|
+
options.add_experimental_option("prefs", prefs)
|
|
165
|
+
|
|
166
|
+
if self.disable_http2:
|
|
167
|
+
options.add_experimental_option("prefs", {"disable-http2": True})
|
|
168
|
+
|
|
169
|
+
# Anti-detection measures
|
|
170
|
+
# options.add_experimental_option("excludeSwitches", ["enable-automation"])
|
|
171
|
+
# options.add_experimental_option('useAutomationExtension', False)
|
|
172
|
+
options.page_load_strategy = 'eager'
|
|
173
|
+
|
|
174
|
+
# Keep the window open for human interaction after the script ends
|
|
175
|
+
if self.detach:
|
|
176
|
+
options.add_experimental_option("detach", True)
|
|
177
|
+
|
|
178
|
+
# Attach to an existing Chrome started with --remote-debugging-port
|
|
179
|
+
if self.debugger_address:
|
|
180
|
+
options.debugger_address = self.debugger_address
|
|
181
|
+
self.logger.info(f"Connecting to debugger at {self.debugger_address}")
|
|
182
|
+
|
|
183
|
+
return options
|
|
184
|
+
|
|
185
|
+
def _setup_undetected_chrome_options(self) -> 'uc.ChromeOptions':
|
|
186
|
+
"""Setup undetected Chrome options"""
|
|
187
|
+
if not UNDETECTED_CHROME_AVAILABLE:
|
|
188
|
+
raise ImportError(
|
|
189
|
+
"undetected-chromedriver not installed. Run: pip install undetected-chromedriver"
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
options = uc.ChromeOptions()
|
|
193
|
+
|
|
194
|
+
# Add undetected-specific options
|
|
195
|
+
for option in UNDETECTED_OPTIONS:
|
|
196
|
+
options.add_argument(option)
|
|
197
|
+
|
|
198
|
+
# User agent
|
|
199
|
+
user_agent = self._get_user_agent()
|
|
200
|
+
options.add_argument(f"--user-agent={user_agent}")
|
|
201
|
+
|
|
202
|
+
# Custom window size
|
|
203
|
+
options.add_argument(f"--window-size={self.window_size[0]},{self.window_size[1]}")
|
|
204
|
+
|
|
205
|
+
# Browser binary
|
|
206
|
+
if self.browser_binary:
|
|
207
|
+
options.binary_location = self.browser_binary
|
|
208
|
+
|
|
209
|
+
return options
|
|
210
|
+
|
|
211
|
+
def _setup_firefox_options(self) -> FirefoxOptions:
|
|
212
|
+
"""Setup Firefox options"""
|
|
213
|
+
options = FirefoxOptions()
|
|
214
|
+
|
|
215
|
+
# Add basic options
|
|
216
|
+
for option in FIREFOX_OPTIONS:
|
|
217
|
+
options.add_argument(option)
|
|
218
|
+
|
|
219
|
+
# Headless mode
|
|
220
|
+
if self.headless:
|
|
221
|
+
options.add_argument("--headless")
|
|
222
|
+
|
|
223
|
+
# User agent
|
|
224
|
+
user_agent = self._get_user_agent()
|
|
225
|
+
options.set_preference("general.useragent.override", user_agent)
|
|
226
|
+
|
|
227
|
+
# Disable HTTP/2 if requested
|
|
228
|
+
if self.disable_http2:
|
|
229
|
+
options.set_preference("network.http.http2.enabled", False)
|
|
230
|
+
|
|
231
|
+
# Disable images if requested
|
|
232
|
+
if self.disable_images:
|
|
233
|
+
options.set_preference("permissions.default.image", 2)
|
|
234
|
+
|
|
235
|
+
# Disable JavaScript if requested
|
|
236
|
+
if self.disable_javascript:
|
|
237
|
+
options.set_preference("javascript.enabled", False)
|
|
238
|
+
|
|
239
|
+
# Browser binary
|
|
240
|
+
if self.browser_binary:
|
|
241
|
+
options.binary_location = self.browser_binary
|
|
242
|
+
|
|
243
|
+
try:
|
|
244
|
+
options.set_preference("webdriver.load.strategy", "eager")
|
|
245
|
+
except Exception:
|
|
246
|
+
pass
|
|
247
|
+
|
|
248
|
+
return options
|
|
249
|
+
|
|
250
|
+
def _setup_edge_options(self) -> EdgeOptions:
|
|
251
|
+
"""Setup Edge options"""
|
|
252
|
+
options = EdgeOptions()
|
|
253
|
+
|
|
254
|
+
# Add Chrome-like options (Edge is Chromium-based)
|
|
255
|
+
for option in CHROME_OPTIONS:
|
|
256
|
+
options.add_argument(option)
|
|
257
|
+
|
|
258
|
+
# Headless mode
|
|
259
|
+
if self.headless:
|
|
260
|
+
options.add_argument("--headless=new")
|
|
261
|
+
|
|
262
|
+
# User agent
|
|
263
|
+
user_agent = self._get_user_agent()
|
|
264
|
+
options.add_argument(f"--user-agent={user_agent}")
|
|
265
|
+
|
|
266
|
+
# Custom window size
|
|
267
|
+
options.add_argument(f"--window-size={self.window_size[0]},{self.window_size[1]}")
|
|
268
|
+
|
|
269
|
+
# Browser binary
|
|
270
|
+
if self.browser_binary:
|
|
271
|
+
options.binary_location = self.browser_binary
|
|
272
|
+
|
|
273
|
+
# Mobile emulation (similar to Chrome)
|
|
274
|
+
if self.mobile:
|
|
275
|
+
mobile_emulation = {
|
|
276
|
+
"deviceName": self.mobile_device,
|
|
277
|
+
"userAgent": user_agent
|
|
278
|
+
}
|
|
279
|
+
options.add_experimental_option("mobileEmulation", mobile_emulation)
|
|
280
|
+
|
|
281
|
+
# HTTP/2 setting
|
|
282
|
+
options.add_experimental_option("ms:edgeOptions", {"http2": not self.disable_http2})
|
|
283
|
+
options.page_load_strategy = 'eager'
|
|
284
|
+
return options
|
|
285
|
+
|
|
286
|
+
def _setup_safari_options(self) -> SafariOptions:
|
|
287
|
+
"""Setup Safari options"""
|
|
288
|
+
options = SafariOptions()
|
|
289
|
+
|
|
290
|
+
# Safari has limited customization options
|
|
291
|
+
# Mobile mode is not supported via options in Safari
|
|
292
|
+
if self.mobile:
|
|
293
|
+
self.logger.warning("Mobile emulation not supported in Safari WebDriver")
|
|
294
|
+
|
|
295
|
+
return options
|
|
296
|
+
|
|
297
|
+
def _get_service(self, browser_type: str):
|
|
298
|
+
"""Get appropriate WebDriver service with auto-installation"""
|
|
299
|
+
|
|
300
|
+
if self.driver_binary:
|
|
301
|
+
# Use custom driver binary
|
|
302
|
+
self.logger.info(f"Using custom {browser_type} driver: {self.driver_binary}")
|
|
303
|
+
if browser_type == 'chrome':
|
|
304
|
+
return ChromeService(executable_path=self.driver_binary)
|
|
305
|
+
elif browser_type == 'firefox':
|
|
306
|
+
return FirefoxService(executable_path=self.driver_binary)
|
|
307
|
+
elif browser_type == 'edge':
|
|
308
|
+
return EdgeService(executable_path=self.driver_binary)
|
|
309
|
+
elif browser_type == 'safari':
|
|
310
|
+
return SafariService(executable_path=self.driver_binary)
|
|
311
|
+
|
|
312
|
+
if not self.auto_install:
|
|
313
|
+
# Don't auto-install, use system driver
|
|
314
|
+
if browser_type == 'chrome':
|
|
315
|
+
return ChromeService()
|
|
316
|
+
elif browser_type == 'firefox':
|
|
317
|
+
return FirefoxService()
|
|
318
|
+
elif browser_type == 'edge':
|
|
319
|
+
return EdgeService()
|
|
320
|
+
elif browser_type == 'safari':
|
|
321
|
+
return SafariService()
|
|
322
|
+
|
|
323
|
+
# Auto-install driver
|
|
324
|
+
cache_manager = DriverCacheManager(valid_range=self.cache_valid_range)
|
|
325
|
+
|
|
326
|
+
if browser_type == 'chrome':
|
|
327
|
+
driver_path = ChromeDriverManager(cache_manager=cache_manager).install()
|
|
328
|
+
return ChromeService(executable_path=driver_path)
|
|
329
|
+
elif browser_type == 'firefox':
|
|
330
|
+
driver_path = GeckoDriverManager(cache_manager=cache_manager).install()
|
|
331
|
+
return FirefoxService(executable_path=driver_path)
|
|
332
|
+
elif browser_type == 'edge':
|
|
333
|
+
driver_path = EdgeChromiumDriverManager(cache_manager=cache_manager).install()
|
|
334
|
+
return EdgeService(executable_path=driver_path)
|
|
335
|
+
elif browser_type == 'safari':
|
|
336
|
+
return SafariService() # Safari driver is built into macOS
|
|
337
|
+
|
|
338
|
+
raise ValueError(f"Unsupported browser type: {browser_type}")
|
|
339
|
+
|
|
340
|
+
async def get_driver(self):
|
|
341
|
+
"""
|
|
342
|
+
Get configured WebDriver instance.
|
|
343
|
+
|
|
344
|
+
Returns:
|
|
345
|
+
WebDriver instance configured according to specifications
|
|
346
|
+
"""
|
|
347
|
+
self.logger.info(f"Setting up {self.browser} WebDriver...")
|
|
348
|
+
|
|
349
|
+
try:
|
|
350
|
+
if self.browser == 'undetected':
|
|
351
|
+
# Undetected Chrome
|
|
352
|
+
if not UNDETECTED_CHROME_AVAILABLE:
|
|
353
|
+
raise ImportError(
|
|
354
|
+
"undetected-chromedriver not available, falling back to regular Chrome"
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
options = self._setup_undetected_chrome_options()
|
|
358
|
+
|
|
359
|
+
# Run in executor to avoid blocking
|
|
360
|
+
loop = asyncio.get_event_loop()
|
|
361
|
+
driver = await loop.run_in_executor(
|
|
362
|
+
None,
|
|
363
|
+
lambda: uc.Chrome(
|
|
364
|
+
options=options,
|
|
365
|
+
headless=self.headless,
|
|
366
|
+
use_subprocess=False,
|
|
367
|
+
advanced_elements=True,
|
|
368
|
+
enable_cdp_events=True
|
|
369
|
+
)
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
elif self.browser == 'chrome':
|
|
373
|
+
# Regular Chrome
|
|
374
|
+
options = self._setup_chrome_options()
|
|
375
|
+
service = self._get_service('chrome')
|
|
376
|
+
|
|
377
|
+
loop = asyncio.get_event_loop()
|
|
378
|
+
driver = await loop.run_in_executor(
|
|
379
|
+
None,
|
|
380
|
+
lambda: webdriver.Chrome(service=service, options=options)
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
elif self.browser == 'firefox':
|
|
384
|
+
# Firefox
|
|
385
|
+
options = self._setup_firefox_options()
|
|
386
|
+
service = self._get_service('firefox')
|
|
387
|
+
|
|
388
|
+
loop = asyncio.get_event_loop()
|
|
389
|
+
driver = await loop.run_in_executor(
|
|
390
|
+
None,
|
|
391
|
+
lambda: webdriver.Firefox(service=service, options=options)
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
elif self.browser == 'edge':
|
|
395
|
+
# Edge
|
|
396
|
+
options = self._setup_edge_options()
|
|
397
|
+
service = self._get_service('edge')
|
|
398
|
+
|
|
399
|
+
loop = asyncio.get_event_loop()
|
|
400
|
+
driver = await loop.run_in_executor(
|
|
401
|
+
None,
|
|
402
|
+
lambda: webdriver.Edge(service=service, options=options)
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
elif self.browser == 'safari':
|
|
406
|
+
# Safari
|
|
407
|
+
options = self._setup_safari_options()
|
|
408
|
+
service = self._get_service('safari')
|
|
409
|
+
|
|
410
|
+
loop = asyncio.get_event_loop()
|
|
411
|
+
driver = await loop.run_in_executor(
|
|
412
|
+
None,
|
|
413
|
+
lambda: webdriver.Safari(service=service, options=options)
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
else:
|
|
417
|
+
raise ValueError(f"Unsupported browser: {self.browser}")
|
|
418
|
+
|
|
419
|
+
# Set timeouts
|
|
420
|
+
try:
|
|
421
|
+
self.timeout = max(getattr(self, 'timeout', 10), 10)
|
|
422
|
+
except Exception:
|
|
423
|
+
self.timeout = 10
|
|
424
|
+
driver.implicitly_wait(self.timeout)
|
|
425
|
+
driver.set_page_load_timeout(self.timeout)
|
|
426
|
+
|
|
427
|
+
self.logger.info(
|
|
428
|
+
f"{self.browser} WebDriver setup completed successfully"
|
|
429
|
+
)
|
|
430
|
+
return driver
|
|
431
|
+
|
|
432
|
+
except Exception as e:
|
|
433
|
+
self.logger.error(
|
|
434
|
+
f"Failed to setup {self.browser} WebDriver: {str(e)}"
|
|
435
|
+
)
|
|
436
|
+
raise
|