diff --git a/docker-compose.yml b/docker-compose.yml index 1f0b82dd..d3ff4f2c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -40,8 +40,10 @@ services: - ENABLE_CODE_BLOCK=true # - BROWSER_TYPE=cdp-connect # Use this command to start Chrome with remote debugging: - # "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="C:\chrome-cdp-profile" --no-first-run --no-default-browser-check - # /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --user-data-dir="/Users/yourusername/chrome-cdp-profile" --no-first-run --no-default-browser-check + # To set up Chrome with remote debugging for CDP connection, use the Skyvern CLI: + # skyvern init + # and select option 3 (cdp-connect) + # If you're using Docker, ensure Chrome is accessible from your container: # - BROWSER_REMOTE_DEBUGGING_URL=http://host.docker.internal:9222/ # ========================= diff --git a/poetry.lock b/poetry.lock index c6dc972f..4c3b0fec 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. [[package]] name = "aioboto3" @@ -415,7 +415,7 @@ version = "3.0.0" description = "Annotate AST trees with source code positions" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2"}, {file = "asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7"}, @@ -597,7 +597,7 @@ description = "Backport of CPython tarfile module" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\"" +markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and python_version ~= \"3.11.0\"" files = [ {file = "backports.tarfile-1.2.0-py3-none-any.whl", hash = "sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34"}, {file = "backports_tarfile-1.2.0.tar.gz", hash = "sha256:d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991"}, @@ -1011,7 +1011,7 @@ version = "0.2.2" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3"}, {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"}, @@ -1175,8 +1175,13 @@ files = [ ] [package.dependencies] -bytecode = {version = ">=0.14.0", markers = "python_version ~= \"3.11.0\""} +bytecode = [ + {version = ">=0.16.0", markers = "python_version >= \"3.13.0\""}, + {version = ">=0.15.0", markers = "python_version ~= \"3.12.0\""}, + {version = ">=0.14.0", markers = "python_version ~= \"3.11.0\""}, +] envier = "0.5.2" +legacy-cgi = {version = ">=2.0.0", markers = "python_version >= \"3.13.0\""} opentelemetry-api = ">=1" protobuf = ">=3" typing_extensions = "*" @@ -1229,7 +1234,7 @@ version = "5.2.1" description = "Decorators for Humans" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a"}, {file = "decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360"}, @@ -1390,7 +1395,7 @@ version = "2.2.0" description = "Get the currently executing AST node of a frame, and other information" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa"}, {file = "executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755"}, @@ -1726,7 +1731,10 @@ google-auth = ">=2.14.1,<3.0.0" googleapis-common-protos = ">=1.56.2,<2.0.0" grpcio = {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""} grpcio-status = {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""} -proto-plus = ">=1.22.3,<2.0.0" +proto-plus = [ + {version = ">=1.25.0,<2.0.0", markers = "python_version >= \"3.13\""}, + {version = ">=1.22.3,<2.0.0"}, +] protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" requests = ">=2.18.0,<3.0.0" @@ -1885,7 +1893,10 @@ files = [ google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0", extras = ["grpc"]} google-auth = ">=2.14.1,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0" grpc-google-iam-v1 = ">=0.14.0,<1.0.0" -proto-plus = ">=1.22.3,<2.0.0" +proto-plus = [ + {version = ">=1.25.0,<2.0.0", markers = "python_version >= \"3.13\""}, + {version = ">=1.22.3,<2.0.0"}, +] protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" [[package]] @@ -1999,70 +2010,67 @@ grpc = ["grpcio (>=1.44.0,<2.0.0)"] [[package]] name = "greenlet" -version = "3.0.3" +version = "3.2.2" description = "Lightweight in-process concurrent programming" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" groups = ["main"] files = [ - {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"}, - {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"}, - {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"}, - {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"}, - {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"}, - {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"}, - {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"}, - {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"}, - {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"}, - {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"}, - {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"}, - {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"}, - {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"}, - {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"}, - {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"}, - {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"}, - {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"}, - {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"}, - {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"}, - {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"}, - {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"}, - {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"}, - {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"}, - {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"}, - {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"}, - {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"}, - {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"}, - {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"}, + {file = "greenlet-3.2.2-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:c49e9f7c6f625507ed83a7485366b46cbe325717c60837f7244fc99ba16ba9d6"}, + {file = "greenlet-3.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3cc1a3ed00ecfea8932477f729a9f616ad7347a5e55d50929efa50a86cb7be7"}, + {file = "greenlet-3.2.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7c9896249fbef2c615853b890ee854f22c671560226c9221cfd27c995db97e5c"}, + {file = "greenlet-3.2.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7409796591d879425997a518138889d8d17e63ada7c99edc0d7a1c22007d4907"}, + {file = "greenlet-3.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7791dcb496ec53d60c7f1c78eaa156c21f402dda38542a00afc3e20cae0f480f"}, + {file = "greenlet-3.2.2-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d8009ae46259e31bc73dc183e402f548e980c96f33a6ef58cc2e7865db012e13"}, + {file = "greenlet-3.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fd9fb7c941280e2c837b603850efc93c999ae58aae2b40765ed682a6907ebbc5"}, + {file = "greenlet-3.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:00cd814b8959b95a546e47e8d589610534cfb71f19802ea8a2ad99d95d702057"}, + {file = "greenlet-3.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:d0cb7d47199001de7658c213419358aa8937df767936506db0db7ce1a71f4a2f"}, + {file = "greenlet-3.2.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:dcb9cebbf3f62cb1e5afacae90761ccce0effb3adaa32339a0670fe7805d8068"}, + {file = "greenlet-3.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf3fc9145141250907730886b031681dfcc0de1c158f3cc51c092223c0f381ce"}, + {file = "greenlet-3.2.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:efcdfb9df109e8a3b475c016f60438fcd4be68cd13a365d42b35914cdab4bb2b"}, + {file = "greenlet-3.2.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4bd139e4943547ce3a56ef4b8b1b9479f9e40bb47e72cc906f0f66b9d0d5cab3"}, + {file = "greenlet-3.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71566302219b17ca354eb274dfd29b8da3c268e41b646f330e324e3967546a74"}, + {file = "greenlet-3.2.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3091bc45e6b0c73f225374fefa1536cd91b1e987377b12ef5b19129b07d93ebe"}, + {file = "greenlet-3.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:44671c29da26539a5f142257eaba5110f71887c24d40df3ac87f1117df589e0e"}, + {file = "greenlet-3.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c23ea227847c9dbe0b3910f5c0dd95658b607137614eb821e6cbaecd60d81cc6"}, + {file = "greenlet-3.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:0a16fb934fcabfdfacf21d79e6fed81809d8cd97bc1be9d9c89f0e4567143d7b"}, + {file = "greenlet-3.2.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:df4d1509efd4977e6a844ac96d8be0b9e5aa5d5c77aa27ca9f4d3f92d3fcf330"}, + {file = "greenlet-3.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da956d534a6d1b9841f95ad0f18ace637668f680b1339ca4dcfb2c1837880a0b"}, + {file = "greenlet-3.2.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c7b15fb9b88d9ee07e076f5a683027bc3befd5bb5d25954bb633c385d8b737e"}, + {file = "greenlet-3.2.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:752f0e79785e11180ebd2e726c8a88109ded3e2301d40abced2543aa5d164275"}, + {file = "greenlet-3.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ae572c996ae4b5e122331e12bbb971ea49c08cc7c232d1bd43150800a2d6c65"}, + {file = "greenlet-3.2.2-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02f5972ff02c9cf615357c17ab713737cccfd0eaf69b951084a9fd43f39833d3"}, + {file = "greenlet-3.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4fefc7aa68b34b9224490dfda2e70ccf2131368493add64b4ef2d372955c207e"}, + {file = "greenlet-3.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a31ead8411a027c2c4759113cf2bd473690517494f3d6e4bf67064589afcd3c5"}, + {file = "greenlet-3.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:b24c7844c0a0afc3ccbeb0b807adeefb7eff2b5599229ecedddcfeb0ef333bec"}, + {file = "greenlet-3.2.2-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:3ab7194ee290302ca15449f601036007873028712e92ca15fc76597a0aeb4c59"}, + {file = "greenlet-3.2.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc5c43bb65ec3669452af0ab10729e8fdc17f87a1f2ad7ec65d4aaaefabf6bf"}, + {file = "greenlet-3.2.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:decb0658ec19e5c1f519faa9a160c0fc85a41a7e6654b3ce1b44b939f8bf1325"}, + {file = "greenlet-3.2.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6fadd183186db360b61cb34e81117a096bff91c072929cd1b529eb20dd46e6c5"}, + {file = "greenlet-3.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1919cbdc1c53ef739c94cf2985056bcc0838c1f217b57647cbf4578576c63825"}, + {file = "greenlet-3.2.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3885f85b61798f4192d544aac7b25a04ece5fe2704670b4ab73c2d2c14ab740d"}, + {file = "greenlet-3.2.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:85f3e248507125bf4af607a26fd6cb8578776197bd4b66e35229cdf5acf1dfbf"}, + {file = "greenlet-3.2.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:1e76106b6fc55fa3d6fe1c527f95ee65e324a13b62e243f77b48317346559708"}, + {file = "greenlet-3.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:fe46d4f8e94e637634d54477b0cfabcf93c53f29eedcbdeecaf2af32029b4421"}, + {file = "greenlet-3.2.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba30e88607fb6990544d84caf3c706c4b48f629e18853fc6a646f82db9629418"}, + {file = "greenlet-3.2.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:055916fafad3e3388d27dd68517478933a97edc2fc54ae79d3bec827de2c64c4"}, + {file = "greenlet-3.2.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2593283bf81ca37d27d110956b79e8723f9aa50c4bcdc29d3c0543d4743d2763"}, + {file = "greenlet-3.2.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89c69e9a10670eb7a66b8cef6354c24671ba241f46152dd3eed447f79c29fb5b"}, + {file = "greenlet-3.2.2-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02a98600899ca1ca5d3a2590974c9e3ec259503b2d6ba6527605fcd74e08e207"}, + {file = "greenlet-3.2.2-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:b50a8c5c162469c3209e5ec92ee4f95c8231b11db6a04db09bbe338176723bb8"}, + {file = "greenlet-3.2.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:45f9f4853fb4cc46783085261c9ec4706628f3b57de3e68bae03e8f8b3c0de51"}, + {file = "greenlet-3.2.2-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:9ea5231428af34226c05f927e16fc7f6fa5e39e3ad3cd24ffa48ba53a47f4240"}, + {file = "greenlet-3.2.2-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:1e4747712c4365ef6765708f948acc9c10350719ca0545e362c24ab973017370"}, + {file = "greenlet-3.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:782743700ab75716650b5238a4759f840bb2dcf7bff56917e9ffdf9f1f23ec59"}, + {file = "greenlet-3.2.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:354f67445f5bed6604e493a06a9a49ad65675d3d03477d38a4db4a427e9aad0e"}, + {file = "greenlet-3.2.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3aeca9848d08ce5eb653cf16e15bb25beeab36e53eb71cc32569f5f3afb2a3aa"}, + {file = "greenlet-3.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cb8553ee954536500d88a1a2f58fcb867e45125e600e80f586ade399b3f8819"}, + {file = "greenlet-3.2.2-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1592a615b598643dbfd566bac8467f06c8c8ab6e56f069e573832ed1d5d528cc"}, + {file = "greenlet-3.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1f72667cc341c95184f1c68f957cb2d4fc31eef81646e8e59358a10ce6689457"}, + {file = "greenlet-3.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a8fa80665b1a29faf76800173ff5325095f3e66a78e62999929809907aca5659"}, + {file = "greenlet-3.2.2-cp39-cp39-win32.whl", hash = "sha256:6629311595e3fe7304039c67f00d145cd1d38cf723bb5b99cc987b23c1433d61"}, + {file = "greenlet-3.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:eeb27bece45c0c2a5842ac4c5a1b5c2ceaefe5711078eed4e8043159fa05c834"}, + {file = "greenlet-3.2.2.tar.gz", hash = "sha256:ad053d34421a2debba45aa3cc39acf454acbcd025b3fc1a9f8a0dee237abd485"}, ] [package.extras] @@ -2527,7 +2535,7 @@ files = [ {file = "importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e"}, {file = "importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580"}, ] -markers = {dev = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\""} +markers = {dev = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and python_version ~= \"3.11.0\""} [package.dependencies] zipp = ">=3.20" @@ -2593,7 +2601,7 @@ version = "8.36.0" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.10" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "ipython-8.36.0-py3-none-any.whl", hash = "sha256:12b913914d010dcffa2711505ec8be4bf0180742d97f1e5175e51f22086428c1"}, {file = "ipython-8.36.0.tar.gz", hash = "sha256:24658e9fe5c5c819455043235ba59cfffded4a35936eefceceab6b192f7092ff"}, @@ -2631,7 +2639,7 @@ version = "8.1.6" description = "Jupyter interactive widgets" optional = false python-versions = ">=3.7" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "ipywidgets-8.1.6-py3-none-any.whl", hash = "sha256:446e7630a1d025bdc7635e1169fcc06f2ce33b5bd41c2003edeb4a47c8d4bbb1"}, {file = "ipywidgets-8.1.6.tar.gz", hash = "sha256:d8ace49c66f14419fc66071371b99d01bed230bbc15d8a60233b18bfbd782851"}, @@ -2747,7 +2755,7 @@ version = "0.19.2" description = "An autocompletion tool for Python that can be used for text editors." optional = false python-versions = ">=3.6" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"}, {file = "jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"}, @@ -3199,7 +3207,7 @@ version = "3.0.14" description = "Jupyter interactive widgets for JupyterLab" optional = false python-versions = ">=3.7" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "jupyterlab_widgets-3.0.14-py3-none-any.whl", hash = "sha256:54c33e3306b7fca139d165d6190dc6c0627aafa5d14adfc974a4e9a3d26cb703"}, {file = "jupyterlab_widgets-3.0.14.tar.gz", hash = "sha256:bad03e59546869f026e537e0d170e454259e6dc7048e14041707ca31e523c8a1"}, @@ -3247,6 +3255,19 @@ files = [ {file = "lark-parser-0.7.8.tar.gz", hash = "sha256:26215ebb157e6fb2ee74319aa4445b9f3b7e456e26be215ce19fdaaa901c20a4"}, ] +[[package]] +name = "legacy-cgi" +version = "2.6.3" +description = "Fork of the standard library cgi and cgitb modules removed in Python 3.13" +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version == \"3.13\"" +files = [ + {file = "legacy_cgi-2.6.3-py3-none-any.whl", hash = "sha256:6df2ea5ae14c71ef6f097f8b6372b44f6685283dc018535a75c924564183cdab"}, + {file = "legacy_cgi-2.6.3.tar.gz", hash = "sha256:4c119d6cb8e9d8b6ad7cc0ddad880552c62df4029622835d06dfd18f438a8154"}, +] + [[package]] name = "litellm" version = "1.68.2" @@ -3302,7 +3323,7 @@ version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, @@ -3398,7 +3419,7 @@ version = "0.1.7" description = "Inline Matplotlib backend for Jupyter" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, @@ -3452,7 +3473,7 @@ version = "0.1.2" description = "Markdown URL utilities" optional = false python-versions = ">=3.7" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, @@ -3955,39 +3976,34 @@ files = [ {file = "numpy-2.2.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d2e3bdadaba0e040d1e7ab39db73e0afe2c74ae277f5614dad53eadbecbbb169"}, {file = "numpy-2.2.5.tar.gz", hash = "sha256:a9c0d994680cd991b1cb772e8b297340085466a6fe964bc9d4e80f5e2f43c291"}, ] +markers = {dev = "python_version <= \"3.13.0\""} [[package]] name = "onnxruntime" -version = "1.16.3" +version = "1.22.0" description = "ONNX Runtime is a runtime accelerator for Machine Learning models" optional = false -python-versions = "*" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "onnxruntime-1.16.3-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:3bc41f323ac77acfed190be8ffdc47a6a75e4beeb3473fbf55eeb075ccca8df2"}, - {file = "onnxruntime-1.16.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:212741b519ee61a4822c79c47147d63a8b0ffde25cd33988d3d7be9fbd51005d"}, - {file = "onnxruntime-1.16.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f91f5497fe3df4ceee2f9e66c6148d9bfeb320cd6a71df361c66c5b8bac985a"}, - {file = "onnxruntime-1.16.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef2b1fc269cabd27f129fb9058917d6fdc89b188c49ed8700f300b945c81f889"}, - {file = "onnxruntime-1.16.3-cp310-cp310-win32.whl", hash = "sha256:f36b56a593b49a3c430be008c2aea6658d91a3030115729609ec1d5ffbaab1b6"}, - {file = "onnxruntime-1.16.3-cp310-cp310-win_amd64.whl", hash = "sha256:3c467eaa3d2429c026b10c3d17b78b7f311f718ef9d2a0d6938e5c3c2611b0cf"}, - {file = "onnxruntime-1.16.3-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:a225bb683991001d111f75323d355b3590e75e16b5e0f07a0401e741a0143ea1"}, - {file = "onnxruntime-1.16.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9aded21fe3d898edd86be8aa2eb995aa375e800ad3dfe4be9f618a20b8ee3630"}, - {file = "onnxruntime-1.16.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00cccc37a5195c8fca5011b9690b349db435986bd508eb44c9fce432da9228a4"}, - {file = "onnxruntime-1.16.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e253e572021563226a86f1c024f8f70cdae28f2fb1cc8c3a9221e8b1ce37db5"}, - {file = "onnxruntime-1.16.3-cp311-cp311-win32.whl", hash = "sha256:a82a8f0b4c978d08f9f5c7a6019ae51151bced9fd91e5aaa0c20a9e4ac7a60b6"}, - {file = "onnxruntime-1.16.3-cp311-cp311-win_amd64.whl", hash = "sha256:78d81d9af457a1dc90db9a7da0d09f3ccb1288ea1236c6ab19f0ca61f3eee2d3"}, - {file = "onnxruntime-1.16.3-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:04ebcd29c20473596a1412e471524b2fb88d55e6301c40b98dd2407b5911595f"}, - {file = "onnxruntime-1.16.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9996bab0f202a6435ab867bc55598f15210d0b72794d5de83712b53d564084ae"}, - {file = "onnxruntime-1.16.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b8f5083f903408238883821dd8c775f8120cb4a604166dbdabe97f4715256d5"}, - {file = "onnxruntime-1.16.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c2dcf1b70f8434abb1116fe0975c00e740722aaf321997195ea3618cc00558e"}, - {file = "onnxruntime-1.16.3-cp38-cp38-win32.whl", hash = "sha256:d4a0151e1accd04da6711f6fd89024509602f82c65a754498e960b032359b02d"}, - {file = "onnxruntime-1.16.3-cp38-cp38-win_amd64.whl", hash = "sha256:e8aa5bba78afbd4d8a2654b14ec7462ff3ce4a6aad312a3c2d2c2b65009f2541"}, - {file = "onnxruntime-1.16.3-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:6829dc2a79d48c911fedaf4c0f01e03c86297d32718a3fdee7a282766dfd282a"}, - {file = "onnxruntime-1.16.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:76f876c53bfa912c6c242fc38213a6f13f47612d4360bc9d599bd23753e53161"}, - {file = "onnxruntime-1.16.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4137e5d443e2dccebe5e156a47f1d6d66f8077b03587c35f11ee0c7eda98b533"}, - {file = "onnxruntime-1.16.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c56695c1a343c7c008b647fff3df44da63741fbe7b6003ef576758640719be7b"}, - {file = "onnxruntime-1.16.3-cp39-cp39-win32.whl", hash = "sha256:985a029798744ce4743fcf8442240fed35c8e4d4d30ec7d0c2cdf1388cd44408"}, - {file = "onnxruntime-1.16.3-cp39-cp39-win_amd64.whl", hash = "sha256:28ff758b17ce3ca6bcad3d936ec53bd7f5482e7630a13f6dcae518eba8f71d85"}, + {file = "onnxruntime-1.22.0-cp310-cp310-macosx_13_0_universal2.whl", hash = "sha256:85d8826cc8054e4d6bf07f779dc742a363c39094015bdad6a08b3c18cfe0ba8c"}, + {file = "onnxruntime-1.22.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:468c9502a12f6f49ec335c2febd22fdceecc1e4cc96dfc27e419ba237dff5aff"}, + {file = "onnxruntime-1.22.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:681fe356d853630a898ee05f01ddb95728c9a168c9460e8361d0a240c9b7cb97"}, + {file = "onnxruntime-1.22.0-cp310-cp310-win_amd64.whl", hash = "sha256:20bca6495d06925631e201f2b257cc37086752e8fe7b6c83a67c6509f4759bc9"}, + {file = "onnxruntime-1.22.0-cp311-cp311-macosx_13_0_universal2.whl", hash = "sha256:8d6725c5b9a681d8fe72f2960c191a96c256367887d076b08466f52b4e0991df"}, + {file = "onnxruntime-1.22.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fef17d665a917866d1f68f09edc98223b9a27e6cb167dec69da4c66484ad12fd"}, + {file = "onnxruntime-1.22.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b978aa63a9a22095479c38371a9b359d4c15173cbb164eaad5f2cd27d666aa65"}, + {file = "onnxruntime-1.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:03d3ef7fb11adf154149d6e767e21057e0e577b947dd3f66190b212528e1db31"}, + {file = "onnxruntime-1.22.0-cp312-cp312-macosx_13_0_universal2.whl", hash = "sha256:f3c0380f53c1e72a41b3f4d6af2ccc01df2c17844072233442c3a7e74851ab97"}, + {file = "onnxruntime-1.22.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8601128eaef79b636152aea76ae6981b7c9fc81a618f584c15d78d42b310f1c"}, + {file = "onnxruntime-1.22.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6964a975731afc19dc3418fad8d4e08c48920144ff590149429a5ebe0d15fb3c"}, + {file = "onnxruntime-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:c0d534a43d1264d1273c2d4f00a5a588fa98d21117a3345b7104fa0bbcaadb9a"}, + {file = "onnxruntime-1.22.0-cp313-cp313-macosx_13_0_universal2.whl", hash = "sha256:fe7c051236aae16d8e2e9ffbfc1e115a0cc2450e873a9c4cb75c0cc96c1dae07"}, + {file = "onnxruntime-1.22.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a6bbed10bc5e770c04d422893d3045b81acbbadc9fb759a2cd1ca00993da919"}, + {file = "onnxruntime-1.22.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9fe45ee3e756300fccfd8d61b91129a121d3d80e9d38e01f03ff1295badc32b8"}, + {file = "onnxruntime-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:5a31d84ef82b4b05d794a4ce8ba37b0d9deb768fd580e36e17b39e0b4840253b"}, + {file = "onnxruntime-1.22.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a2ac5bd9205d831541db4e508e586e764a74f14efdd3f89af7fd20e1bf4a1ed"}, + {file = "onnxruntime-1.22.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64845709f9e8a2809e8e009bc4c8f73b788cee9c6619b7d9930344eae4c9cd36"}, ] [package.dependencies] @@ -4200,7 +4216,10 @@ files = [ ] [package.dependencies] -numpy = {version = ">=1.23.2", markers = "python_version == \"3.11\""} +numpy = [ + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, +] python-dateutil = ">=2.8.2" pytz = ">=2020.1" tzdata = ">=2022.7" @@ -4248,7 +4267,7 @@ version = "0.8.4" description = "A Python Parser" optional = false python-versions = ">=3.6" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, @@ -4264,7 +4283,7 @@ version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." optional = false python-versions = "*" -groups = ["dev"] +groups = ["main", "dev"] markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\"" files = [ {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, @@ -4391,24 +4410,25 @@ type = ["mypy (>=1.14.1)"] [[package]] name = "playwright" -version = "1.46.0" +version = "1.52.0" description = "A high-level API to automate web browsers" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["main"] files = [ - {file = "playwright-1.46.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:fa60b95c16f6ce954636229a6c9dd885485326bca52d5ba20d02c0bc731a2bbb"}, - {file = "playwright-1.46.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:73dcfc24834f4d004bc862ed0d74b4c1406793a8164734238ad035356fddc8ac"}, - {file = "playwright-1.46.0-py3-none-macosx_11_0_universal2.whl", hash = "sha256:f5acfec1dbdc84d02dc696a17a344227e66c91413eab2036428dab405f195b82"}, - {file = "playwright-1.46.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:3b418509f45879f1403d070858657a39bd0b333b23d92c37355682b671726df9"}, - {file = "playwright-1.46.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23580f6a3f99757bb9779d29be37144cb9328cd9bafa178e6db5b3ab4b7faf4c"}, - {file = "playwright-1.46.0-py3-none-win32.whl", hash = "sha256:85f44dd32a23d02850f0ff4dafe51580e5199531fff5121a62489d9838707782"}, - {file = "playwright-1.46.0-py3-none-win_amd64.whl", hash = "sha256:f14a7fd7e24e954eec6ce61d787d499e41937ade811a0818e9a088aabe28ebb6"}, + {file = "playwright-1.52.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:19b2cb9d4794062008a635a99bd135b03ebb782d460f96534a91cb583f549512"}, + {file = "playwright-1.52.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0797c0479cbdc99607412a3c486a3a2ec9ddc77ac461259fd2878c975bcbb94a"}, + {file = "playwright-1.52.0-py3-none-macosx_11_0_universal2.whl", hash = "sha256:7223960b7dd7ddeec1ba378c302d1d09733b8dac438f492e9854c85d3ca7144f"}, + {file = "playwright-1.52.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:d010124d24a321e0489a8c0d38a3971a7ca7656becea7656c9376bfea7f916d4"}, + {file = "playwright-1.52.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4173e453c43180acc60fd77ffe1ebee8d0efbfd9986c03267007b9c3845415af"}, + {file = "playwright-1.52.0-py3-none-win32.whl", hash = "sha256:cd0bdf92df99db6237a99f828e80a6a50db6180ef8d5352fc9495df2c92f9971"}, + {file = "playwright-1.52.0-py3-none-win_amd64.whl", hash = "sha256:dcbf75101eba3066b7521c6519de58721ea44379eb17a0dafa94f9f1b17f59e4"}, + {file = "playwright-1.52.0-py3-none-win_arm64.whl", hash = "sha256:9d0085b8de513de5fb50669f8e6677f0252ef95a9a1d2d23ccee9638e71e65cb"}, ] [package.dependencies] -greenlet = "3.0.3" -pyee = "11.1.0" +greenlet = ">=3.1.1,<4.0.0" +pyee = ">=13,<14" [[package]] name = "pluggy" @@ -4492,7 +4512,7 @@ version = "3.0.51" description = "Library for building powerful interactive command lines in Python" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "prompt_toolkit-3.0.51-py3-none-any.whl", hash = "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07"}, {file = "prompt_toolkit-3.0.51.tar.gz", hash = "sha256:931a162e3b27fc90c86f1b48bb1fb2c528c2761475e57c9c06de13311c7b54ed"}, @@ -4672,104 +4692,104 @@ test = ["pytest", "pytest-xdist", "setuptools"] [[package]] name = "psycopg" -version = "3.1.18" +version = "3.2.9" description = "PostgreSQL database adapter for Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" groups = ["main"] files = [ - {file = "psycopg-3.1.18-py3-none-any.whl", hash = "sha256:4d5a0a5a8590906daa58ebd5f3cfc34091377354a1acced269dd10faf55da60e"}, - {file = "psycopg-3.1.18.tar.gz", hash = "sha256:31144d3fb4c17d78094d9e579826f047d4af1da6a10427d91dfcfb6ecdf6f12b"}, + {file = "psycopg-3.2.9-py3-none-any.whl", hash = "sha256:01a8dadccdaac2123c916208c96e06631641c0566b22005493f09663c7a8d3b6"}, + {file = "psycopg-3.2.9.tar.gz", hash = "sha256:2fbb46fcd17bc81f993f28c47f1ebea38d66ae97cc2dbc3cad73b37cefbff700"}, ] [package.dependencies] -psycopg-binary = {version = "3.1.18", optional = true, markers = "implementation_name != \"pypy\" and extra == \"binary\""} +psycopg-binary = {version = "3.2.9", optional = true, markers = "implementation_name != \"pypy\" and extra == \"binary\""} psycopg-pool = {version = "*", optional = true, markers = "extra == \"pool\""} -typing-extensions = ">=4.1" +typing-extensions = {version = ">=4.6", markers = "python_version < \"3.13\""} tzdata = {version = "*", markers = "sys_platform == \"win32\""} [package.extras] -binary = ["psycopg-binary (==3.1.18) ; implementation_name != \"pypy\""] -c = ["psycopg-c (==3.1.18) ; implementation_name != \"pypy\""] -dev = ["black (>=24.1.0)", "codespell (>=2.2)", "dnspython (>=2.1)", "flake8 (>=4.0)", "mypy (>=1.4.1)", "types-setuptools (>=57.4)", "wheel (>=0.37)"] +binary = ["psycopg-binary (==3.2.9) ; implementation_name != \"pypy\""] +c = ["psycopg-c (==3.2.9) ; implementation_name != \"pypy\""] +dev = ["ast-comments (>=1.1.2)", "black (>=24.1.0)", "codespell (>=2.2)", "dnspython (>=2.1)", "flake8 (>=4.0)", "isort-psycopg", "isort[colors] (>=6.0)", "mypy (>=1.14)", "pre-commit (>=4.0.1)", "types-setuptools (>=57.4)", "types-shapely (>=2.0)", "wheel (>=0.37)"] docs = ["Sphinx (>=5.0)", "furo (==2022.6.21)", "sphinx-autobuild (>=2021.3.14)", "sphinx-autodoc-typehints (>=1.12)"] pool = ["psycopg-pool"] -test = ["anyio (>=3.6.2,<4.0)", "mypy (>=1.4.1)", "pproxy (>=2.7)", "pytest (>=6.2.5)", "pytest-cov (>=3.0)", "pytest-randomly (>=3.5)"] +test = ["anyio (>=4.0)", "mypy (>=1.14)", "pproxy (>=2.7)", "pytest (>=6.2.5)", "pytest-cov (>=3.0)", "pytest-randomly (>=3.5)"] [[package]] name = "psycopg-binary" -version = "3.1.18" +version = "3.2.9" description = "PostgreSQL database adapter for Python -- C optimisation distribution" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" groups = ["main"] markers = "implementation_name != \"pypy\"" files = [ - {file = "psycopg_binary-3.1.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c323103dfa663b88204cf5f028e83c77d7a715f9b6f51d2bbc8184b99ddd90a"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:887f8d856c91510148be942c7acd702ccf761a05f59f8abc123c22ab77b5a16c"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d322ba72cde4ca2eefc2196dad9ad7e52451acd2f04e3688d590290625d0c970"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:489aa4fe5a0b653b68341e9e44af247dedbbc655326854aa34c163ef1bcb3143"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55ff0948457bfa8c0d35c46e3a75193906d1c275538877ba65907fd67aa059ad"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b15e3653c82384b043d820fc637199b5c6a36b37fa4a4943e0652785bb2bad5d"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f8ff3bc08b43f36fdc24fedb86d42749298a458c4724fb588c4d76823ac39f54"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1729d0e3dfe2546d823841eb7a3d003144189d6f5e138ee63e5227f8b75276a5"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:13bcd3742112446037d15e360b27a03af4b5afcf767f5ee374ef8f5dd7571b31"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:320047e3d3554b857e16c2b6b615a85e0db6a02426f4d203a4594a2f125dfe57"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-win_amd64.whl", hash = "sha256:888a72c2aca4316ca6d4a619291b805677bae99bba2f6e31a3c18424a48c7e4d"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4e4de16a637ec190cbee82e0c2dc4860fed17a23a35f7a1e6dc479a5c6876722"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6432047b8b24ef97e3fbee1d1593a0faaa9544c7a41a2c67d1f10e7621374c83"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d684227ef8212e27da5f2aff9d4d303cc30b27ac1702d4f6881935549486dd5"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:67284e2e450dc7a9e4d76e78c0bd357dc946334a3d410defaeb2635607f632cd"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c9b6bd7fb5c6638cb32469674707649b526acfe786ba6d5a78ca4293d87bae4"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7121acc783c4e86d2d320a7fb803460fab158a7f0a04c5e8c5d49065118c1e73"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e28ff8f3de7b56588c2a398dc135fd9f157d12c612bd3daa7e6ba9872337f6f5"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c84a0174109f329eeda169004c7b7ca2e884a6305acab4a39600be67f915ed38"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:531381f6647fc267383dca88dbe8a70d0feff433a8e3d0c4939201fea7ae1b82"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b293e01057e63c3ac0002aa132a1071ce0fdb13b9ee2b6b45d3abdb3525c597d"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-win_amd64.whl", hash = "sha256:780a90bcb69bf27a8b08bc35b958e974cb6ea7a04cdec69e737f66378a344d68"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:87dd9154b757a5fbf6d590f6f6ea75f4ad7b764a813ae04b1d91a70713f414a1"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f876ebbf92db70125f6375f91ab4bc6b27648aa68f90d661b1fc5affb4c9731c"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:258d2f0cb45e4574f8b2fe7c6d0a0e2eb58903a4fd1fbaf60954fba82d595ab7"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd27f713f2e5ef3fd6796e66c1a5203a27a30ecb847be27a78e1df8a9a5ae68c"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c38a4796abf7380f83b1653c2711cb2449dd0b2e5aca1caa75447d6fa5179c69"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2f7f95746efd1be2dc240248cc157f4315db3fd09fef2adfcc2a76e24aa5741"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4085f56a8d4fc8b455e8f44380705c7795be5317419aa5f8214f315e4205d804"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:2e2484ae835dedc80cdc7f1b1a939377dc967fed862262cfd097aa9f50cade46"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:3c2b039ae0c45eee4cd85300ef802c0f97d0afc78350946a5d0ec77dd2d7e834"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f54978c4b646dec77fefd8485fa82ec1a87807f334004372af1aaa6de9539a5"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-win_amd64.whl", hash = "sha256:9ffcbbd389e486d3fd83d30107bbf8b27845a295051ccabde240f235d04ed921"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c76659ae29a84f2c14f56aad305dd00eb685bd88f8c0a3281a9a4bc6bd7d2aa7"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c7afcd6f1d55992f26d9ff7b0bd4ee6b475eb43aa3f054d67d32e09f18b0065"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:639dd78ac09b144b0119076783cb64e1128cc8612243e9701d1503c816750b2e"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e1cf59e0bb12e031a48bb628aae32df3d0c98fd6c759cb89f464b1047f0ca9c8"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e262398e5d51563093edf30612cd1e20fedd932ad0994697d7781ca4880cdc3d"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:59701118c7d8842e451f1e562d08e8708b3f5d14974eefbce9374badd723c4ae"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:dea4a59da7850192fdead9da888e6b96166e90608cf39e17b503f45826b16f84"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4575da95fc441244a0e2ebaf33a2b2f74164603341d2046b5cde0a9aa86aa7e2"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:812726266ab96de681f2c7dbd6b734d327f493a78357fcc16b2ac86ff4f4e080"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-win_amd64.whl", hash = "sha256:3e7ce4d988112ca6c75765c7f24c83bdc476a6a5ce00878df6c140ca32c3e16d"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:02bd4da45d5ee9941432e2e9bf36fa71a3ac21c6536fe7366d1bd3dd70d6b1e7"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:39242546383f6b97032de7af30edb483d237a0616f6050512eee7b218a2aa8ee"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d46ae44d66bf6058a812467f6ae84e4e157dee281bfb1cfaeca07dee07452e85"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad35ac7fd989184bf4d38a87decfb5a262b419e8ba8dcaeec97848817412c64a"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:247474af262bdd5559ee6e669926c4f23e9cf53dae2d34c4d991723c72196404"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ebecbf2406cd6875bdd2453e31067d1bd8efe96705a9489ef37e93b50dc6f09"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1859aeb2133f5ecdd9cbcee155f5e38699afc06a365f903b1512c765fd8d457e"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:da917f6df8c6b2002043193cb0d74cc173b3af7eb5800ad69c4e1fbac2a71c30"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9e24e7b6a68a51cc3b162d0339ae4e1263b253e887987d5c759652f5692b5efe"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e252d66276c992319ed6cd69a3ffa17538943954075051e992143ccbf6dc3d3e"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-win_amd64.whl", hash = "sha256:5d6e860edf877d4413e4a807e837d55e3a7c7df701e9d6943c06e460fa6c058f"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eea5f14933177ffe5c40b200f04f814258cc14b14a71024ad109f308e8bad414"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:824a1bfd0db96cc6bef2d1e52d9e0963f5bf653dd5bc3ab519a38f5e6f21c299"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a87e9eeb80ce8ec8c2783f29bce9a50bbcd2e2342a340f159c3326bf4697afa1"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91074f78a9f890af5f2c786691575b6b93a4967ad6b8c5a90101f7b8c1a91d9c"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e05f6825f8db4428782135e6986fec79b139210398f3710ed4aa6ef41473c008"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f68ac2364a50d4cf9bb803b4341e83678668f1881a253e1224574921c69868c"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7ac1785d67241d5074f8086705fa68e046becea27964267ab3abd392481d7773"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:cd2a9f7f0d4dacc5b9ce7f0e767ae6cc64153264151f50698898c42cabffec0c"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:3e4b0bb91da6f2238dbd4fbb4afc40dfb4f045bb611b92fce4d381b26413c686"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:74e498586b72fb819ca8ea82107747d0cb6e00ae685ea6d1ab3f929318a8ce2d"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-win_amd64.whl", hash = "sha256:d4422af5232699f14b7266a754da49dc9bcd45eba244cf3812307934cd5d6679"}, + {file = "psycopg_binary-3.2.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:528239bbf55728ba0eacbd20632342867590273a9bacedac7538ebff890f1093"}, + {file = "psycopg_binary-3.2.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4978c01ca4c208c9d6376bd585e2c0771986b76ff7ea518f6d2b51faece75e8"}, + {file = "psycopg_binary-3.2.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ed2bab85b505d13e66a914d0f8cdfa9475c16d3491cf81394e0748b77729af2"}, + {file = "psycopg_binary-3.2.9-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:799fa1179ab8a58d1557a95df28b492874c8f4135101b55133ec9c55fc9ae9d7"}, + {file = "psycopg_binary-3.2.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb37ac3955d19e4996c3534abfa4f23181333974963826db9e0f00731274b695"}, + {file = "psycopg_binary-3.2.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:001e986656f7e06c273dd4104e27f4b4e0614092e544d950c7c938d822b1a894"}, + {file = "psycopg_binary-3.2.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fa5c80d8b4cbf23f338db88a7251cef8bb4b68e0f91cf8b6ddfa93884fdbb0c1"}, + {file = "psycopg_binary-3.2.9-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:39a127e0cf9b55bd4734a8008adf3e01d1fd1cb36339c6a9e2b2cbb6007c50ee"}, + {file = "psycopg_binary-3.2.9-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fb7599e436b586e265bea956751453ad32eb98be6a6e694252f4691c31b16edb"}, + {file = "psycopg_binary-3.2.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5d2c9fe14fe42b3575a0b4e09b081713e83b762c8dc38a3771dd3265f8f110e7"}, + {file = "psycopg_binary-3.2.9-cp310-cp310-win_amd64.whl", hash = "sha256:7e4660fad2807612bb200de7262c88773c3483e85d981324b3c647176e41fdc8"}, + {file = "psycopg_binary-3.2.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2504e9fd94eabe545d20cddcc2ff0da86ee55d76329e1ab92ecfcc6c0a8156c4"}, + {file = "psycopg_binary-3.2.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:093a0c079dd6228a7f3c3d82b906b41964eaa062a9a8c19f45ab4984bf4e872b"}, + {file = "psycopg_binary-3.2.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:387c87b51d72442708e7a853e7e7642717e704d59571da2f3b29e748be58c78a"}, + {file = "psycopg_binary-3.2.9-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9ac10a2ebe93a102a326415b330fff7512f01a9401406896e78a81d75d6eddc"}, + {file = "psycopg_binary-3.2.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:72fdbda5b4c2a6a72320857ef503a6589f56d46821592d4377c8c8604810342b"}, + {file = "psycopg_binary-3.2.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f34e88940833d46108f949fdc1fcfb74d6b5ae076550cd67ab59ef47555dba95"}, + {file = "psycopg_binary-3.2.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a3e0f89fe35cb03ff1646ab663dabf496477bab2a072315192dbaa6928862891"}, + {file = "psycopg_binary-3.2.9-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6afb3e62f2a3456f2180a4eef6b03177788df7ce938036ff7f09b696d418d186"}, + {file = "psycopg_binary-3.2.9-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:cc19ed5c7afca3f6b298bfc35a6baa27adb2019670d15c32d0bb8f780f7d560d"}, + {file = "psycopg_binary-3.2.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc75f63653ce4ec764c8f8c8b0ad9423e23021e1c34a84eb5f4ecac8538a4a4a"}, + {file = "psycopg_binary-3.2.9-cp311-cp311-win_amd64.whl", hash = "sha256:3db3ba3c470801e94836ad78bf11fd5fab22e71b0c77343a1ee95d693879937a"}, + {file = "psycopg_binary-3.2.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:be7d650a434921a6b1ebe3fff324dbc2364393eb29d7672e638ce3e21076974e"}, + {file = "psycopg_binary-3.2.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6a76b4722a529390683c0304501f238b365a46b1e5fb6b7249dbc0ad6fea51a0"}, + {file = "psycopg_binary-3.2.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96a551e4683f1c307cfc3d9a05fec62c00a7264f320c9962a67a543e3ce0d8ff"}, + {file = "psycopg_binary-3.2.9-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:61d0a6ceed8f08c75a395bc28cb648a81cf8dee75ba4650093ad1a24a51c8724"}, + {file = "psycopg_binary-3.2.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad280bbd409bf598683dda82232f5215cfc5f2b1bf0854e409b4d0c44a113b1d"}, + {file = "psycopg_binary-3.2.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76eddaf7fef1d0994e3d536ad48aa75034663d3a07f6f7e3e601105ae73aeff6"}, + {file = "psycopg_binary-3.2.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:52e239cd66c4158e412318fbe028cd94b0ef21b0707f56dcb4bdc250ee58fd40"}, + {file = "psycopg_binary-3.2.9-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:08bf9d5eabba160dd4f6ad247cf12f229cc19d2458511cab2eb9647f42fa6795"}, + {file = "psycopg_binary-3.2.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1b2cf018168cad87580e67bdde38ff5e51511112f1ce6ce9a8336871f465c19a"}, + {file = "psycopg_binary-3.2.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:14f64d1ac6942ff089fc7e926440f7a5ced062e2ed0949d7d2d680dc5c00e2d4"}, + {file = "psycopg_binary-3.2.9-cp312-cp312-win_amd64.whl", hash = "sha256:7a838852e5afb6b4126f93eb409516a8c02a49b788f4df8b6469a40c2157fa21"}, + {file = "psycopg_binary-3.2.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:98bbe35b5ad24a782c7bf267596638d78aa0e87abc7837bdac5b2a2ab954179e"}, + {file = "psycopg_binary-3.2.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:72691a1615ebb42da8b636c5ca9f2b71f266be9e172f66209a361c175b7842c5"}, + {file = "psycopg_binary-3.2.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25ab464bfba8c401f5536d5aa95f0ca1dd8257b5202eede04019b4415f491351"}, + {file = "psycopg_binary-3.2.9-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e8aeefebe752f46e3c4b769e53f1d4ad71208fe1150975ef7662c22cca80fab"}, + {file = "psycopg_binary-3.2.9-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7e4e4dd177a8665c9ce86bc9caae2ab3aa9360b7ce7ec01827ea1baea9ff748"}, + {file = "psycopg_binary-3.2.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fc2915949e5c1ea27a851f7a472a7da7d0a40d679f0a31e42f1022f3c562e87"}, + {file = "psycopg_binary-3.2.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a1fa38a4687b14f517f049477178093c39c2a10fdcced21116f47c017516498f"}, + {file = "psycopg_binary-3.2.9-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5be8292d07a3ab828dc95b5ee6b69ca0a5b2e579a577b39671f4f5b47116dfd2"}, + {file = "psycopg_binary-3.2.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:778588ca9897b6c6bab39b0d3034efff4c5438f5e3bd52fda3914175498202f9"}, + {file = "psycopg_binary-3.2.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f0d5b3af045a187aedbd7ed5fc513bd933a97aaff78e61c3745b330792c4345b"}, + {file = "psycopg_binary-3.2.9-cp313-cp313-win_amd64.whl", hash = "sha256:2290bc146a1b6a9730350f695e8b670e1d1feb8446597bed0bbe7c3c30e0abcb"}, + {file = "psycopg_binary-3.2.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4df22ec17390ec5ccb38d211fb251d138d37a43344492858cea24de8efa15003"}, + {file = "psycopg_binary-3.2.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eac3a6e926421e976c1c2653624e1294f162dc67ac55f9addbe8f7b8d08ce603"}, + {file = "psycopg_binary-3.2.9-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf789be42aea5752ee396d58de0538d5fcb76795c85fb03ab23620293fb81b6f"}, + {file = "psycopg_binary-3.2.9-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0f05b9dafa5670a7503abc715af081dbbb176a8e6770de77bccaeb9024206c5"}, + {file = "psycopg_binary-3.2.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2d7a6646d41228e9049978be1f3f838b557a1bde500b919906d54c4390f5086"}, + {file = "psycopg_binary-3.2.9-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a4d76e28df27ce25dc19583407f5c6c6c2ba33b443329331ab29b6ef94c8736d"}, + {file = "psycopg_binary-3.2.9-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:418f52b77b715b42e8ec43ee61ca74abc6765a20db11e8576e7f6586488a266f"}, + {file = "psycopg_binary-3.2.9-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:1f1736d5b21f69feefeef8a75e8d3bf1f0a1e17c165a7488c3111af9d6936e91"}, + {file = "psycopg_binary-3.2.9-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5918c0fab50df764812f3ca287f0d716c5c10bedde93d4da2cefc9d40d03f3aa"}, + {file = "psycopg_binary-3.2.9-cp38-cp38-win_amd64.whl", hash = "sha256:7b617b81f08ad8def5edd110de44fd6d326f969240cc940c6f6b3ef21fe9c59f"}, + {file = "psycopg_binary-3.2.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:587a3f19954d687a14e0c8202628844db692dbf00bba0e6d006659bf1ca91cbe"}, + {file = "psycopg_binary-3.2.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:791759138380df21d356ff991265fde7fe5997b0c924a502847a9f9141e68786"}, + {file = "psycopg_binary-3.2.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95315b8c8ddfa2fdcb7fe3ddea8a595c1364524f512160c604e3be368be9dd07"}, + {file = "psycopg_binary-3.2.9-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18ac08475c9b971237fcc395b0a6ee4e8580bb5cf6247bc9b8461644bef5d9f4"}, + {file = "psycopg_binary-3.2.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac2c04b6345e215e65ca6aef5c05cc689a960b16674eaa1f90a8f86dfaee8c04"}, + {file = "psycopg_binary-3.2.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1ab25e3134774f1e476d4bb9050cdec25f10802e63e92153906ae934578734"}, + {file = "psycopg_binary-3.2.9-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4bfec4a73e8447d8fe8854886ffa78df2b1c279a7592241c2eb393d4499a17e2"}, + {file = "psycopg_binary-3.2.9-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:166acc57af5d2ff0c0c342aed02e69a0cd5ff216cae8820c1059a6f3b7cf5f78"}, + {file = "psycopg_binary-3.2.9-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:413f9e46259fe26d99461af8e1a2b4795a4e27cc8ac6f7919ec19bcee8945074"}, + {file = "psycopg_binary-3.2.9-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:354dea21137a316b6868ee41c2ae7cce001e104760cf4eab3ec85627aed9b6cd"}, + {file = "psycopg_binary-3.2.9-cp39-cp39-win_amd64.whl", hash = "sha256:24ddb03c1ccfe12d000d950c9aba93a7297993c4e3905d9f2c9795bb0764d523"}, ] [[package]] @@ -4793,12 +4813,12 @@ version = "0.7.0" description = "Run a subprocess in a pseudo terminal" optional = false python-versions = "*" -groups = ["dev"] -markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\" or os_name != \"nt\"" +groups = ["main", "dev"] files = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, ] +markers = {main = "sys_platform != \"win32\" and sys_platform != \"emscripten\"", dev = "sys_platform != \"win32\" and sys_platform != \"emscripten\" or os_name != \"nt\""} [[package]] name = "pure-eval" @@ -4806,7 +4826,7 @@ version = "0.2.3" description = "Safely evaluate AST nodes without side effects" optional = false python-versions = "*" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, @@ -5038,21 +5058,21 @@ files = [ [[package]] name = "pyee" -version = "11.1.0" +version = "13.0.0" description = "A rough port of Node.js's EventEmitter to Python with a few tricks of its own" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "pyee-11.1.0-py3-none-any.whl", hash = "sha256:5d346a7d0f861a4b2e6c47960295bd895f816725b27d656181947346be98d7c1"}, - {file = "pyee-11.1.0.tar.gz", hash = "sha256:b53af98f6990c810edd9b56b87791021a8f54fd13db4edd1142438d44ba2263f"}, + {file = "pyee-13.0.0-py3-none-any.whl", hash = "sha256:48195a3cddb3b1515ce0695ed76036b5ccc2ef3a9f963ff9f77aec0139845498"}, + {file = "pyee-13.0.0.tar.gz", hash = "sha256:b391e3c5a434d1f5118a25615001dbc8f669cf410ab67d04c4d4e07c55481c37"}, ] [package.dependencies] typing-extensions = "*" [package.extras] -dev = ["black", "build", "flake8", "flake8-black", "isort", "jupyter-console", "mkdocs", "mkdocs-include-markdown-plugin", "mkdocstrings[python]", "pytest", "pytest-asyncio ; python_version >= \"3.4\"", "pytest-trio ; python_version >= \"3.7\"", "sphinx", "toml", "tox", "trio", "trio ; python_version > \"3.6\"", "trio-typing ; python_version > \"3.6\"", "twine", "twisted", "validate-pyproject[all]"] +dev = ["black", "build", "flake8", "flake8-black", "isort", "jupyter-console", "mkdocs", "mkdocs-include-markdown-plugin", "mkdocstrings[python]", "mypy", "pytest", "pytest-asyncio ; python_version >= \"3.4\"", "pytest-trio ; python_version >= \"3.7\"", "sphinx", "toml", "tox", "trio", "trio ; python_version > \"3.6\"", "trio-typing ; python_version > \"3.6\"", "twine", "twisted", "validate-pyproject[all]"] [[package]] name = "pyflakes" @@ -5072,7 +5092,7 @@ version = "2.19.1" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"}, {file = "pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f"}, @@ -5766,7 +5786,7 @@ version = "13.9.4" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, @@ -6243,7 +6263,7 @@ version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" optional = false python-versions = "*" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, @@ -6573,7 +6593,7 @@ version = "5.14.3" description = "Traitlets Python configuration system" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, @@ -6985,7 +7005,7 @@ version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, @@ -7120,7 +7140,7 @@ version = "4.0.14" description = "Jupyter interactive widgets for Jupyter Notebook" optional = false python-versions = ">=3.7" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "widgetsnbextension-4.0.14-py3-none-any.whl", hash = "sha256:4875a9eaf72fbf5079dc372a51a9f268fc38d46f767cbf85c43a36da5cb9b575"}, {file = "widgetsnbextension-4.0.14.tar.gz", hash = "sha256:a3629b04e3edb893212df862038c7232f62973373869db5084aed739b437b5af"}, @@ -7357,7 +7377,7 @@ files = [ {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, ] -markers = {dev = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\""} +markers = {dev = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and python_version ~= \"3.11.0\""} [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] @@ -7369,5 +7389,5 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" -python-versions = "^3.11,<3.12" -content-hash = "81fb59e4ecd1124ab664c84c633ad015acdfc059fda8495a7fe4d40cad33435f" +python-versions = ">=3.11,<3.14" +content-hash = "57a3088e67587092f55c9b3fa60f48e41eebe513fbb4de7af2bf81835017f6fc" diff --git a/pyproject.toml b/pyproject.toml index 15e07618..51e99bae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ readme = "README.md" packages = [{ include = "skyvern" }, { include = "alembic" }] [tool.poetry.dependencies] -python = "^3.11,<3.12" +python = ">=3.11,<3.14" python-dotenv = "^1.0.0" openai = ">=1.68.2" sqlalchemy = {extras = ["mypy"], version = "^2.0.29"} @@ -17,14 +17,21 @@ toml = "^0.10.2" jinja2 = "^3.1.2" uvicorn = {extras = ["standard"], version = "^0.24.0.post1"} litellm = ">=1.68.2" -playwright = "1.46.0" +playwright = [ + {version = ">=1.52.0", python = ">=3.13,<3.14"}, # Python 3.13 requires 1.52.0+ + {version = ">=1.46.0", python = ">=3.11,<3.13"} # Older Python versions can use 1.46.0+ +] +greenlet = [ + {version = ">=3.2.2", python = ">=3.13,<3.14"}, # Python 3.13 requires 3.2.2+ + {version = ">=2.0.2", python = ">=3.11,<3.13"} # Older Python versions can use 2.0.2+ +] pillow = "^10.1.0" starlette-context = "^0.3.6" ddtrace = "^2.3.2" pydantic = "^2.5.2" pydantic-settings = "^2.1.0" fastapi = "^0.115.4" -psycopg = {version = "3.1.18", extras = ["binary", "pool"]} +psycopg = {version = ">=3.2.2,<3.3.0", extras = ["binary", "pool"]} alembic = "^1.12.1" python-jose = {extras = ["cryptography"], version = "^3.3.0"} cachetools = "^5.3.2" @@ -33,12 +40,12 @@ commentjson = "^0.9.0" asyncache = "^0.3.1" orjson = "^3.9.10" structlog = "^23.2.0" -typer = ">=0.9.0,<1.0" +typer = ">=0.9.0,<0.10.0" types-toml = "^0.10.8.7" httpx = {version = "^0.27.0", extras = ["socks"]} filetype = "^1.2.0" redis = "^5.0.3" -onnxruntime = "<1.17" +onnxruntime = ">=1.20.0,<1.23.0" aioredlock = "^0.7.3" stripe = "^9.7.0" tldextract = "^5.1.2" @@ -46,6 +53,7 @@ websockets = "^12.0" email-validator = "^2.2.0" temporalio = "^1.6.0" requests-toolbelt = "^1.0.0" +rich = {extras = ["jupyter"], version = "^13.7.0"}Í posthog = "^3.7.0" aiofiles = "^24.1.0" pyotp = "^2.9.0" @@ -83,9 +91,8 @@ build = "^1.2.2.post1" pandas = "^2.2.3" pre-commit = "^4.2.0" - [build-system] -requires = ["poetry-core"] +requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" [tool.ruff] @@ -145,4 +152,4 @@ module-root = "skyvern" tests-root = "codeflash-tests" test-framework = "pytest" ignore-paths = ["skyvern/client"] -formatter-cmds = ["ruff check --exit-zero --fix $file", "ruff format $file"] +formatter-cmds = ["ruff check --exit-zero --fix $file", "ruff format $file"] diff --git a/skyvern/cli/commands.py b/skyvern/cli/commands.py index 1f7d1b0f..ada74038 100644 --- a/skyvern/cli/commands.py +++ b/skyvern/cli/commands.py @@ -3,69 +3,910 @@ import json import os import shutil import subprocess +import sys import time +import webbrowser import uuid +from enum import Enum from pathlib import Path -from typing import Optional -from urllib.parse import urlparse - -import requests +from typing import List, Optional, Dict, Any, Tuple import typer -import uvicorn +from rich.console import Console +from rich.panel import Panel +from rich.progress import Progress, SpinnerColumn, TextColumn +from rich.table import Table +from rich import print as rprint +from rich.markdown import Markdown from dotenv import load_dotenv, set_key -from mcp.server.fastmcp import FastMCP from skyvern.config import settings -from skyvern.forge import app -from skyvern.forge.sdk.db.enums import OrganizationAuthTokenType from skyvern.library import Skyvern +from skyvern.forge.sdk.db.enums import OrganizationAuthTokenType +from skyvern.forge import app from skyvern.utils import detect_os, get_windows_appdata_roaming, migrate_db -load_dotenv() +# Initialize Rich console for better formatting +console = Console() -cli_app = typer.Typer() -run_app = typer.Typer() -setup_app = typer.Typer() +# Main application +cli_app = typer.Typer( + help="Skyvern - Browser automation powered by LLMs and Computer Vision", + add_completion=False, +) + +# Subcommands +run_app = typer.Typer(help="Run Skyvern components") +setup_app = typer.Typer(help="Set up Skyvern configurations") +tasks_app = typer.Typer(help="Manage Skyvern tasks") +workflows_app = typer.Typer(help="Manage Skyvern workflows") +docs_app = typer.Typer(help="Access Skyvern documentation") + +# Add subcommands to main app cli_app.add_typer(run_app, name="run") cli_app.add_typer(setup_app, name="setup") -mcp = FastMCP("Skyvern") +cli_app.add_typer(tasks_app, name="tasks") +cli_app.add_typer(workflows_app, name="workflows") +cli_app.add_typer(docs_app, name="docs") +# Documentation sections and their URLs -@mcp.tool() -async def skyvern_run_task(prompt: str, url: str) -> dict[str, str]: - """Use Skyvern to execute anything in the browser. Useful for accomplishing tasks that require browser automation. +# Documentation sections and their URLs +DOCUMENTATION = { + "quickstart": "https://docs.skyvern.com/introduction", + "tasks": "https://docs.skyvern.com/running-tasks/introduction", + "workflows": "https://docs.skyvern.com/workflows/introduction", + "prompting": "https://docs.skyvern.com/getting-started/prompting-guide", + "api": "https://docs.skyvern.com/integrations/api", +} - This tool uses Skyvern's browser automation to navigate websites and perform actions to achieve - the user's intended outcome. It can handle tasks like form filling, clicking buttons, data extraction, - and multi-step workflows. +class DeploymentType(str, Enum): + LOCAL = "local" + CLOUD = "cloud" - It can even help you find updated data on the internet if your model information is outdated. +class BrowserType(str, Enum): + HEADLESS = "chromium-headless" + HEADFUL = "chromium-headful" + CDP = "cdp-connect" - Args: - prompt: A natural language description of what needs to be accomplished (e.g. "Book a flight from - NYC to LA", "Sign up for the newsletter", "Find the price of item X", "Apply to a job") - url: The starting URL of the website where the task should be performed +#---------------------------------------------------- +# 1. Guided Onboarding Flow +#---------------------------------------------------- + +@cli_app.command(name="init") +def init( + deployment: Optional[DeploymentType] = typer.Option( + None, + help="Deployment type: local or cloud" + ), + no_postgres: bool = typer.Option( + False, + "--no-postgres", + help="Skip starting PostgreSQL container" + ) +) -> None: """ - skyvern_agent = Skyvern( - base_url=settings.SKYVERN_BASE_URL, - api_key=settings.SKYVERN_API_KEY, - ) - res = await skyvern_agent.run_task(prompt=prompt, url=url, user_agent="skyvern-mcp") + Initialize Skyvern with a guided setup process. + + This wizard will help you configure Skyvern for either local development + or connection to Skyvern Cloud. It will guide you through: + + - Choosing deployment type (local or cloud) + - Setting up database (for local deployment) + - Configuring LLM providers + - Setting up browser automation + - Configuring integrations + """ + console.print(Panel.fit( + "[bold blue]Welcome to Skyvern Setup Wizard[/]", + subtitle="Let's get you started with browser automation" + )) - # TODO: It would be nice if we could return the task URL here - output = res.model_dump()["output"] - base_url = settings.SKYVERN_BASE_URL - run_history_url = ( - "https://app.skyvern.com/history" if "skyvern.com" in base_url else "http://localhost:8080/history" + # Step 1: Choose deployment type + if deployment is None: + console.print(Markdown("## Step 1: Choose Deployment Type")) + console.print("\n[yellow]Local deployment[/] - Run Skyvern on your machine") + console.print(" • Requires local database and LLM API keys") + console.print(" • Good for development and testing") + console.print("\n[yellow]Cloud deployment[/] - Connect to Skyvern Cloud") + console.print(" • Managed service with no local infrastructure") + console.print(" • Production-ready with built-in scaling") + + deployment_choice = console.input("\n[bold]Deploy locally or connect to cloud? [cloud/local] [/]").strip().lower() + run_local = deployment_choice == "local" + else: + run_local = deployment == DeploymentType.LOCAL + + with Progress( + SpinnerColumn(), + TextColumn("[progress.description]{task.description}"), + console=console + ) as progress: + if run_local: + # Step 2: Set up local infrastructure (for local deployment) + setup_task = progress.add_task("[green]Setting up local infrastructure...", total=1) + + if not no_postgres: + setup_postgresql(no_postgres) + + migrate_db() + + api_key_task = progress.add_task("[green]Generating API key...", total=1) + api_key = asyncio.run(_setup_local_organization()) + progress.update(api_key_task, completed=1) + + # Step 3: Configure LLM providers + progress.update(setup_task, completed=1) + llm_task = progress.add_task("[green]Setting up LLM providers...", total=1) + setup_llm_providers() + progress.update(llm_task, completed=1) + + # Step 4: Configure browser settings + browser_task = progress.add_task("[green]Setting up browser automation...", total=1) + browser_type, browser_location, remote_debugging_url = setup_browser_config() + update_or_add_env_var("BROWSER_TYPE", browser_type) + if browser_location: + update_or_add_env_var("CHROME_EXECUTABLE_PATH", browser_location) + if remote_debugging_url: + update_or_add_env_var("BROWSER_REMOTE_DEBUGGING_URL", remote_debugging_url) + progress.update(browser_task, completed=1) + + # Set defaults for local development + update_or_add_env_var("SKYVERN_BASE_URL", "http://localhost:8000") + else: + # Configure for cloud deployment + cloud_task = progress.add_task("[green]Setting up Skyvern Cloud connection...", total=1) + + base_url = console.input("\nEnter Skyvern base URL [https://api.skyvern.com]: ").strip() + if not base_url: + base_url = "https://api.skyvern.com" + + console.print("\nTo get your API key:") + console.print("1. Create an account at [link=https://app.skyvern.com]https://app.skyvern.com[/link]") + console.print("2. Go to Settings") + console.print("3. Copy your API key") + + api_key = console.input("\nEnter your Skyvern API key: ").strip() + while not api_key: + console.print("[bold red]API key is required[/]") + api_key = console.input("Enter your Skyvern API key: ").strip() + + update_or_add_env_var("SKYVERN_BASE_URL", base_url) + progress.update(cloud_task, completed=1) + + # Common configuration + analytics_task = progress.add_task("[green]Finalizing configuration...", total=1) + + # Ask for email or generate UUID for analytics + analytics_id = console.input("\nPlease enter your email for analytics (press enter to skip): ") + if not analytics_id: + analytics_id = str(uuid.uuid4()) + + update_or_add_env_var("ANALYTICS_ID", analytics_id) + update_or_add_env_var("SKYVERN_API_KEY", api_key) + progress.update(analytics_task, completed=1) + + # Step 5: Configure integrations + console.print(Markdown("\n## Step 5: Configure Integrations")) + configure_mcp = typer.confirm("Would you like to configure AI integrations (Claude, Cursor, Windsurf)?", default=True) + if configure_mcp: + setup_mcp() + console.print("\n[green]AI integrations configured successfully![/]") + + if run_local: + # Install required components for local deployment + console.print(Markdown("\n## Step 6: Installing Components")) + with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}"), console=console) as progress: + browser_install_task = progress.add_task("[green]Installing Chromium browser...", total=1) + subprocess.run(["playwright", "install", "chromium"], check=True) + progress.update(browser_install_task, completed=1) + + # Success message and next steps + console.print(Panel.fit( + "[bold green]Skyvern setup complete![/]", + subtitle="You're ready to start automating browsers" + )) + + if run_local: + console.print("\n[bold]Next steps:[/]") + console.print("1. Start the Skyvern server: [yellow]skyvern run server[/]") + console.print("2. Start the Skyvern UI: [yellow]skyvern run ui[/]") + else: + console.print("\n[bold]Next steps:[/]") + console.print("1. Visit the Skyvern Cloud dashboard: [link=https://app.skyvern.com]https://app.skyvern.com[/link]") + console.print("2. Try using an AI integration: [yellow]skyvern docs integrations[/]") + +#---------------------------------------------------- +# 3. Improved Documentation Integration +#---------------------------------------------------- + +@docs_app.command(name="open") +def open_docs( + section: str = typer.Argument( + "quickstart", + help="Documentation section to open" ) - return {"output": output, "run_history_url": run_history_url} +) -> None: + """ + Open Skyvern documentation in your web browser. + + Available sections: + - quickstart: Getting started guide + - tasks: Task creation and running + - workflows: Workflow creation and running + - prompting: Best practices for writing prompts + - api: API reference + """ + if section not in DOCUMENTATION: + console.print(f"[bold red]Error:[/] Documentation section '{section}' not found") + console.print("\nAvailable sections:") + for name, url in DOCUMENTATION.items(): + console.print(f" • [bold]{name}[/] - {url}") + return + + url = DOCUMENTATION[section] + console.print(f"Opening documentation section: [bold]{section}[/]") + console.print(f"URL: [link={url}]{url}[/link]") + webbrowser.open(url) + +@docs_app.command(name="prompting") +def prompting_guide() -> None: + """ + Show prompting best practices for Skyvern. + """ + console.print(Panel.fit( + "[bold blue]Skyvern Prompting Best Practices[/]", + subtitle="Tips for writing effective prompts" + )) + + console.print(Markdown(""" +## General Guidelines + +1. **Be specific and detailed** + - Specify exactly what actions should be taken + - Include any data or criteria needed for decisions + +2. **Define completion criteria** + - Use COMPLETE/TERMINATE markers to indicate success/failure conditions + - Specify what data to extract (if any) + +3. **Break complex tasks into steps** + - For multi-page flows, describe each step clearly + - Use sequencing terms (first, then, after) + +## Examples + +✅ **Good prompt:** +``` +Navigate to the products page. Find the product named "Wireless Headphones" +and add it to the cart. Proceed to checkout and fill the form with: +Name: John Doe +Email: john@example.com +When complete, extract the order confirmation number. +COMPLETE when you see a "Thank you for your order" message. +``` + +❌ **Less effective prompt:** +``` +Buy wireless headphones and check out. +``` + +## For More Information + +Run `skyvern docs open prompting` to see the complete prompting guide online. + """)) + +#---------------------------------------------------- +# 4. User-Friendly Management Commands +#---------------------------------------------------- + +@cli_app.command(name="status") +def status() -> None: + """ + Check the status of Skyvern services. + """ + console.print(Panel.fit( + "[bold blue]Skyvern Services Status[/]", + subtitle="Checking all system components" + )) + + # Check for .env file + env_path = Path(".env") + env_status = "✅ Found" if env_path.exists() else "❌ Not found" + + # Check database connection + db_status = "⏳ Checking..." + try: + load_dotenv() + # Simple check - just see if we can run a migrate command without error + migrate_db(dry_run=True) + db_status = "✅ Connected" + except Exception: + db_status = "❌ Not connected" + + # Check if server is running (port 8000) + server_status = "⏳ Checking..." + try: + import socket + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.settimeout(0.5) + s.connect(("localhost", 8000)) + s.close() + server_status = "✅ Running" + except: + server_status = "❌ Not running" + + # Check if UI is running (port 8080) + ui_status = "⏳ Checking..." + try: + import socket + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.settimeout(0.5) + s.connect(("localhost", 8080)) + s.close() + ui_status = "✅ Running" + except: + ui_status = "❌ Not running" + + # Check API key + api_key = os.getenv("SKYVERN_API_KEY", "") + api_key_status = "✅ Configured" if api_key else "❌ Not configured" + + # Display status table + table = Table(title="Skyvern Services") + table.add_column("Component", style="cyan") + table.add_column("Status", style="green") + table.add_column("Action to Fix", style="yellow") + + table.add_row("Configuration (.env)", env_status, "Run: skyvern init" if env_status.startswith("❌") else "") + table.add_row("Database", db_status, "Check DATABASE_STRING in .env" if db_status.startswith("❌") else "") + table.add_row("Server", server_status, "Run: skyvern run server" if server_status.startswith("❌") else "") + table.add_row("UI", ui_status, "Run: skyvern run ui" if ui_status.startswith("❌") else "") + table.add_row("API Key", api_key_status, "Run: skyvern init" if api_key_status.startswith("❌") else "") + + console.print(table) + + if "❌" in f"{env_status}{db_status}{server_status}{ui_status}{api_key_status}": + console.print("\n[bold yellow]Some components need attention.[/] Fix the issues above to get started.") + else: + console.print("\n[bold green]All systems operational![/] Skyvern is ready to use.") + +@tasks_app.command(name="list") +def list_tasks() -> None: + """ + List recent Skyvern tasks. + """ + console.print(Panel.fit( + "[bold blue]Recent Skyvern Tasks[/]", + subtitle="Retrieving task history" + )) + + try: + # Initialize Skyvern client + load_dotenv() + skyvern_agent = Skyvern( + base_url=settings.SKYVERN_BASE_URL, + api_key=settings.SKYVERN_API_KEY, + ) + + # Get tasks + with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}"), console=console) as progress: + task = progress.add_task("[green]Fetching recent tasks...", total=1) + tasks = asyncio.run(skyvern_agent.get_tasks()) + progress.update(task, completed=1) + + if not tasks: + console.print("[yellow]No tasks found[/]") + return + + # Display tasks + table = Table(title=f"Tasks ({len(tasks)} found)") + table.add_column("ID", style="cyan", no_wrap=True) + table.add_column("Title", style="green") + table.add_column("Status", style="yellow") + table.add_column("Created", style="blue") + + for task in tasks: + table.add_row( + str(task.id), + task.title or "Untitled", + task.status or "Unknown", + task.created_at.strftime("%Y-%m-%d %H:%M:%S") if task.created_at else "Unknown" + ) + + console.print(table) + + # Show help for next steps + console.print("\n[bold]Next steps:[/]") + console.print("• View task details: [yellow]skyvern tasks show [/]") + console.print("• Retry a task: [yellow]skyvern tasks retry [/]") + + except Exception as e: + console.print(f"[bold red]Error listing tasks:[/] {str(e)}") + console.print("[yellow]Make sure your API key is set correctly in .env[/]") + +@tasks_app.command(name="create") +def create_task( + prompt: str = typer.Option(..., "--prompt", "-p", help="Task prompt"), + url: str = typer.Option(..., "--url", "-u", help="Starting URL"), + schema: Optional[str] = typer.Option(None, "--schema", "-s", help="Data extraction schema (JSON)"), + output_json: bool = typer.Option(False, "--json", help="Output results as JSON") +) -> None: + """ + Create and run a new Skyvern task. + """ + console.print(Panel.fit( + "[bold blue]Creating New Skyvern Task[/]", + subtitle="Running browser automation" + )) + + console.print(f"[bold]Prompt:[/] {prompt}") + console.print(f"[bold]URL:[/] {url}") + if schema: + console.print(f"[bold]Schema:[/] {schema}") + + try: + # Initialize Skyvern client + load_dotenv() + skyvern_agent = Skyvern( + base_url=settings.SKYVERN_BASE_URL, + api_key=settings.SKYVERN_API_KEY, + ) + + # Create and run task + with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}"), console=console) as progress: + task = progress.add_task("[green]Running task...", total=1) + + result = asyncio.run(skyvern_agent.run_task( + prompt=prompt, + url=url, + data_extraction_schema=schema, + user_agent="skyvern-cli" + )) + + progress.update(task, completed=1) + + # Display result + if output_json: + console.print_json(json.dumps(result.model_dump())) + else: + console.print("\n[bold green]Task completed successfully![/]") + console.print(f"\n[bold]Output:[/] {result.model_dump()['output']}") + + # Display path to view results + base_url = settings.SKYVERN_BASE_URL + run_history_url = "https://app.skyvern.com/history" if "skyvern.com" in base_url else "http://localhost:8080/history" + console.print(f"\nView details at: [link={run_history_url}]{run_history_url}[/link]") + + except Exception as e: + console.print(f"[bold red]Error creating task:[/] {str(e)}") + console.print("[yellow]Make sure your API key is set correctly in .env[/]") + +@workflows_app.command(name="list") +def list_workflows() -> None: + """ + List Skyvern workflows. + """ + console.print(Panel.fit( + "[bold blue]Skyvern Workflows[/]", + subtitle="Retrieving available workflows" + )) + + try: + # Initialize Skyvern client + load_dotenv() + skyvern_agent = Skyvern( + base_url=settings.SKYVERN_BASE_URL, + api_key=settings.SKYVERN_API_KEY, + ) + + # Get workflows + with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}"), console=console) as progress: + task = progress.add_task("[green]Fetching workflows...", total=1) + workflows = asyncio.run(skyvern_agent.get_workflows()) + progress.update(task, completed=1) + + if not workflows: + console.print("[yellow]No workflows found[/]") + return + + # Display workflows + table = Table(title=f"Workflows ({len(workflows)} found)") + table.add_column("ID", style="cyan", no_wrap=True) + table.add_column("Title", style="green") + table.add_column("Status", style="yellow") + table.add_column("Created", style="blue") + + for workflow in workflows: + table.add_row( + str(workflow.id), + workflow.title or "Untitled", + workflow.status or "Unknown", + workflow.created_at.strftime("%Y-%m-%d %H:%M:%S") if hasattr(workflow, 'created_at') and workflow.created_at else "Unknown" + ) + + console.print(table) + + # Show help for next steps + console.print("\n[bold]Next steps:[/]") + console.print("• View workflow details: [yellow]skyvern workflows show [/]") + console.print("• Run a workflow: [yellow]skyvern workflows run [/]") + + except Exception as e: + console.print(f"[bold red]Error listing workflows:[/] {str(e)}") + console.print("[yellow]Make sure your API key is set correctly in .env[/]") + +#---------------------------------------------------- +# 5. Streamlined Configuration (Original functions enhanced) +#---------------------------------------------------- + +def setup_postgresql(no_postgres: bool = False) -> None: + """Set up PostgreSQL database for Skyvern with improved feedback.""" + console.print(Markdown("## Database Setup")) + + if command_exists("psql") and is_postgres_running(): + console.print("[green]✓[/] PostgreSQL is already running locally") + if database_exists("skyvern", "skyvern"): + console.print("[green]✓[/] Database and user exist") + else: + console.print("[yellow]![/] Creating database and user...") + create_database_and_user() + console.print("[green]✓[/] Database created successfully") + return + + if no_postgres: + console.print("[yellow]![/] Skipping PostgreSQL setup as requested") + console.print(" If using Docker Compose, its Postgres service will start automatically") + return + + if not is_docker_running(): + console.print("[bold red]×[/] Docker is not running or not installed") + console.print(" Please install or start Docker and try again") + exit(1) + + if is_postgres_running_in_docker(): + console.print("[green]✓[/] PostgreSQL is already running in Docker") + else: + if not no_postgres: + console.print("[yellow]![/] No local Postgres detected") + start_postgres = typer.confirm( + "Start a disposable container now? (Choose 'n' if using Docker Compose)", + default=True + ) + + if not start_postgres: + console.print("[yellow]![/] Skipping PostgreSQL container setup") + console.print(" If using Docker Compose, its Postgres service will start automatically") + return + + console.print("[yellow]![/] Attempting to install PostgreSQL via Docker...") + if not is_postgres_container_exists(): + run_command( + "docker run --name postgresql-container -e POSTGRES_HOST_AUTH_METHOD=trust -d -p 5432:5432 postgres:14" + ) + else: + run_command("docker start postgresql-container") + console.print("[green]✓[/] PostgreSQL has been installed and started using Docker") + + console.print("[yellow]![/] Waiting for PostgreSQL to start...") + time.sleep(20) + + # Set up user and database in Docker postgres if needed + _, code = run_command('docker exec postgresql-container psql -U postgres -c "\\du" | grep -q skyvern', check=False) + if code == 0: + console.print("[green]✓[/] Database user exists") + else: + console.print("[yellow]![/] Creating database user...") + run_command("docker exec postgresql-container createuser -U postgres skyvern") + + _, code = run_command( + "docker exec postgresql-container psql -U postgres -lqt | cut -d \\| -f 1 | grep -qw skyvern", check=False + ) + if code == 0: + console.print("[green]✓[/] Database exists") + else: + console.print("[yellow]![/] Creating database...") + run_command("docker exec postgresql-container createdb -U postgres skyvern -O skyvern") + console.print("[green]✓[/] Database and user created successfully") + + +def setup_llm_providers() -> None: + """Configure Large Language Model (LLM) Providers with improved UI.""" + console.print(Markdown("## LLM Provider Configuration")) + console.print("All information provided here will be stored only on your local machine.\n") + + model_options = [] + + # Create sections for each provider + providers = [ + { + "name": "OpenAI", + "env_key": "ENABLE_OPENAI", + "api_key_env": "OPENAI_API_KEY", + "models": ["OPENAI_GPT4_1", "OPENAI_GPT4_1_MINI", "OPENAI_GPT4_1_NANO", "OPENAI_GPT4O", "OPENAI_O4_MINI", "OPENAI_O3"], + "setup_message": "To enable OpenAI, you need an API key from your OpenAI account." + }, + { + "name": "Anthropic", + "env_key": "ENABLE_ANTHROPIC", + "api_key_env": "ANTHROPIC_API_KEY", + "models": ["ANTHROPIC_CLAUDE3.5_SONNET", "ANTHROPIC_CLAUDE3.7_SONNET"], + "setup_message": "To enable Anthropic, you need an API key from your Anthropic account." + }, + { + "name": "Azure OpenAI", + "env_key": "ENABLE_AZURE", + "api_key_env": "AZURE_API_KEY", + "models": ["AZURE_OPENAI_GPT4O"], + "setup_message": "To enable Azure OpenAI, you need deployment details from your Azure account.", + "extra_fields": { + "AZURE_DEPLOYMENT": "Enter your Azure deployment name", + "AZURE_API_BASE": "Enter your Azure API base URL", + "AZURE_API_VERSION": "Enter your Azure API version" + } + }, + { + "name": "Google Gemini", + "env_key": "ENABLE_GEMINI", + "api_key_env": "GEMINI_API_KEY", + "models": ["GEMINI_FLASH_2_0", "GEMINI_FLASH_2_0_LITE", "GEMINI_2.5_PRO_PREVIEW_03_25", "GEMINI_2.5_PRO_EXP_03_25"], + "setup_message": "To enable Gemini, you need an API key from Google AI Studio." + }, + { + "name": "Novita AI", + "env_key": "ENABLE_NOVITA", + "api_key_env": "NOVITA_API_KEY", + "models": [ + "NOVITA_DEEPSEEK_R1", "NOVITA_DEEPSEEK_V3", "NOVITA_LLAMA_3_3_70B", + "NOVITA_LLAMA_3_2_1B", "NOVITA_LLAMA_3_2_3B", "NOVITA_LLAMA_3_2_11B_VISION", + "NOVITA_LLAMA_3_1_8B", "NOVITA_LLAMA_3_1_70B", "NOVITA_LLAMA_3_1_405B", + "NOVITA_LLAMA_3_8B", "NOVITA_LLAMA_3_70B" + ], + "setup_message": "To enable Novita AI, you need an API key from Novita." + }, + { + "name": "OpenAI-compatible", + "env_key": "ENABLE_OPENAI_COMPATIBLE", + "models": ["OPENAI_COMPATIBLE"], + "setup_message": "To enable an OpenAI-compatible provider, you need provider-specific details.", + "extra_fields": { + "OPENAI_COMPATIBLE_MODEL_NAME": "Enter the model name (e.g., 'yi-34b', 'mistral-large')", + "OPENAI_COMPATIBLE_API_KEY": "Enter your API key", + "OPENAI_COMPATIBLE_API_BASE": "Enter the API base URL (e.g., 'https://api.together.xyz/v1')" + }, + "extra_questions": [ + { + "question": "Does this model support vision?", + "env_key": "OPENAI_COMPATIBLE_SUPPORTS_VISION", + "value_if_yes": "true", + "value_if_no": "false" + } + ], + "optional_fields": { + "OPENAI_COMPATIBLE_API_VERSION": "Enter API version (optional, press enter to skip)" + } + } + ] + + # Process each provider + for provider in providers: + console.print(f"\n[bold yellow]{provider['name']}[/]") + console.print(provider["setup_message"]) + + enable = typer.confirm(f"Enable {provider['name']}?", default=False) + update_or_add_env_var(provider["env_key"], "true" if enable else "false") + + if enable: + # Handle API key (most providers) + if "api_key_env" in provider: + api_key = typer.prompt(f"Enter your {provider['name']} API key", hide_input=True) + if not api_key: + console.print(f"[bold red]Error:[/] {provider['name']} API key is required.") + console.print(f"{provider['name']} will not be enabled.") + update_or_add_env_var(provider["env_key"], "false") + continue + update_or_add_env_var(provider["api_key_env"], api_key) + + # Handle extra fields (Azure, OpenAI-compatible) + if "extra_fields" in provider: + field_values = {} + for env_key, prompt_text in provider["extra_fields"].items(): + value = typer.prompt(prompt_text) + field_values[env_key] = value + update_or_add_env_var(env_key, value) + + # Check if all required fields are provided + if any(not v for v in field_values.values()): + console.print(f"[bold red]Error:[/] All {provider['name']} fields must be populated.") + console.print(f"{provider['name']} will not be enabled.") + update_or_add_env_var(provider["env_key"], "false") + continue + + # Handle extra yes/no questions + if "extra_questions" in provider: + for question in provider["extra_questions"]: + answer = typer.confirm(question["question"], default=False) + value = question["value_if_yes"] if answer else question["value_if_no"] + update_or_add_env_var(question["env_key"], value) + + # Handle optional fields + if "optional_fields" in provider: + for env_key, prompt_text in provider["optional_fields"].items(): + value = typer.prompt(prompt_text, default="") + if value: + update_or_add_env_var(env_key, value) + + # Add models to options + model_options.extend(provider["models"]) + console.print(f"[green]✓[/] {provider['name']} configured successfully") + + # Model Selection + if not model_options: + console.print( + "\n[bold red]Warning:[/] No LLM providers enabled. You won't be able to run Skyvern without a provider." + ) + else: + console.print("\n[bold]Available LLM models based on your selections:[/]") + for i, model in enumerate(model_options, 1): + console.print(f" {i}. [cyan]{model}[/]") + + while True: + try: + model_choice = typer.prompt( + f"Choose a model by number (1-{len(model_options)})", + type=int + ) + if 1 <= model_choice <= len(model_options): + break + console.print(f"[red]Please enter a number between 1 and {len(model_options)}[/]") + except ValueError: + console.print("[red]Please enter a valid number[/]") + + chosen_model = model_options[model_choice - 1] + console.print(f"[green]✓[/] Model selected: [bold]{chosen_model}[/]") + update_or_add_env_var("LLM_KEY", chosen_model) + + console.print("[green]✓[/] LLM provider configuration updated in .env") + + +def setup_browser_config() -> tuple[str, Optional[str], Optional[str]]: + """Configure browser settings for Skyvern with improved UI.""" + console.print(Markdown("## Browser Configuration")) + + browser_types = [ + {"id": "chromium-headless", "name": "Headless Chrome", "description": "Runs Chrome in the background (no visible window)"}, + {"id": "chromium-headful", "name": "Visible Chrome", "description": "Runs Chrome with a visible window"}, + {"id": "cdp-connect", "name": "Connect to Chrome", "description": "Connects to an existing Chrome instance with remote debugging"} + ] + + console.print("Select browser mode:") + for i, browser in enumerate(browser_types, 1): + console.print(f" {i}. [bold]{browser['name']}[/] - {browser['description']}") + + # Get browser choice + while True: + try: + choice = typer.prompt("Enter your choice (1-3)", type=int) + if 1 <= choice <= len(browser_types): + selected_browser = browser_types[choice - 1]["id"] + break + console.print(f"[red]Please enter a number between 1 and {len(browser_types)}[/]") + except ValueError: + console.print("[red]Please enter a valid number[/]") + + browser_location = None + remote_debugging_url = None + + # Additional configuration for CDP connection + if selected_browser == "cdp-connect": + host_system = detect_os() + default_location = get_default_chrome_location(host_system) + + console.print(f"\n[yellow]Default Chrome location:[/] {default_location}") + browser_location = typer.prompt("Enter Chrome executable location", default=default_location) + + if not os.path.exists(browser_location): + console.print(f"[bold yellow]Warning:[/] Chrome not found at {browser_location}") + console.print("Please verify the location is correct") + if not typer.confirm("Continue with this path anyway?", default=False): + return setup_browser_config() # Start over + + console.print("\n[bold]Chrome Remote Debugging Setup:[/]") + console.print("Chrome must be running with remote debugging enabled.") + console.print(f"Example command: [italic]chrome --remote-debugging-port=9222[/]") + + default_port = "9222" + remote_debugging_url = f"http://localhost:{default_port}" + + # Check if Chrome is already running with remote debugging + parsed_url = urlparse(remote_debugging_url) + version_url = f"{parsed_url.scheme}://{parsed_url.netloc}/json/version" + + console.print(f"\n[yellow]Checking for Chrome on port {default_port}...[/]") + chrome_running = False + + try: + response = requests.get(version_url, timeout=2) + if response.status_code == 200: + try: + browser_info = response.json() + console.print("[green]✓[/] Chrome is already running with remote debugging!") + if "Browser" in browser_info: + console.print(f" Browser: {browser_info['Browser']}") + if "webSocketDebuggerUrl" in browser_info: + console.print(f" WebSocket URL: {browser_info['webSocketDebuggerUrl']}") + chrome_running = True + except json.JSONDecodeError: + console.print("[red]Port is in use, but doesn't appear to be Chrome[/]") + except requests.RequestException: + console.print(f"[yellow]No Chrome instance detected on {remote_debugging_url}[/]") + + # If Chrome isn't running, offer to start it + if not chrome_running: + if host_system == "darwin" or host_system == "linux": + chrome_cmd = f'{browser_location} --remote-debugging-port={default_port} --user-data-dir="$HOME/chrome-cdp-profile" --no-first-run --no-default-browser-check' + elif host_system == "windows" or host_system == "wsl": + chrome_cmd = f'"{browser_location}" --remote-debugging-port={default_port} --user-data-dir="C:\\chrome-cdp-profile" --no-first-run --no-default-browser-check' + else: + console.print("[red]Unsupported OS for Chrome configuration[/]") + chrome_cmd = "" + + if chrome_cmd: + console.print(f"\nCommand to start Chrome: [yellow]{chrome_cmd}[/]") + + if typer.confirm("Start Chrome with remote debugging now?", default=True): + console.print(f"[yellow]Starting Chrome with remote debugging on port {default_port}...[/]") + try: + if host_system in ["darwin", "linux"]: + subprocess.Popen(f"nohup {chrome_cmd} > /dev/null 2>&1 &", shell=True) + elif host_system == "windows": + subprocess.Popen(f"start {chrome_cmd}", shell=True) + elif host_system == "wsl": + subprocess.Popen(f"cmd.exe /c start {chrome_cmd}", shell=True) + + console.print("Chrome starting...") + console.print(f"Connecting to {remote_debugging_url}") + + # Wait for Chrome to start and verify connection + with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}"), console=console) as progress: + wait_task = progress.add_task("[green]Waiting for Chrome to initialize...", total=1) + time.sleep(2) + progress.update(wait_task, completed=1) + + try: + verification_response = requests.get(version_url, timeout=5) + if verification_response.status_code == 200: + try: + browser_info = verification_response.json() + console.print("[green]✓[/] Connection verified! Chrome is running with remote debugging") + if "Browser" in browser_info: + console.print(f" Browser: {browser_info['Browser']}") + except json.JSONDecodeError: + console.print("[yellow]Warning:[/] Response from Chrome debugging port is not valid JSON") + else: + console.print(f"[yellow]Warning:[/] Chrome responded with status code {verification_response.status_code}") + except requests.RequestException as e: + console.print(f"[yellow]Warning:[/] Could not verify Chrome is running: {e}") + console.print("You may need to check Chrome manually or try a different port") + except Exception as e: + console.print(f"[red]Error starting Chrome:[/] {e}") + console.print("Please start Chrome manually using the command above") + + # Get the debugging URL + custom_url = typer.prompt("Enter remote debugging URL", default=remote_debugging_url) + if custom_url: + remote_debugging_url = custom_url + + console.print(f"\n[green]✓[/] Browser configuration complete: [bold]{selected_browser}[/]") + return selected_browser, browser_location, remote_debugging_url def command_exists(command: str) -> bool: + """Check if a command exists on the system.""" return shutil.which(command) is not None def run_command(command: str, check: bool = True) -> tuple[Optional[str], Optional[int]]: + """Run a shell command and return the output and return code.""" try: result = subprocess.run(command, shell=True, check=check, capture_output=True, text=True) return result.stdout.strip(), result.returncode @@ -74,6 +915,7 @@ def run_command(command: str, check: bool = True) -> tuple[Optional[str], Option def is_postgres_running() -> bool: + """Check if PostgreSQL is running locally.""" if command_exists("pg_isready"): result, _ = run_command("pg_isready") return result is not None and "accepting connections" in result @@ -81,19 +923,20 @@ def is_postgres_running() -> bool: def database_exists(dbname: str, user: str) -> bool: + """Check if a PostgreSQL database exists.""" check_db_command = f'psql {dbname} -U {user} -c "\\q"' output, _ = run_command(check_db_command, check=False) return output is not None def create_database_and_user() -> None: - print("Creating database user and database...") + """Create PostgreSQL database and user for Skyvern.""" run_command("createuser skyvern") run_command("createdb skyvern -O skyvern") - print("Database and user created successfully.") def is_docker_running() -> bool: + """Check if Docker is running.""" if not command_exists("docker"): return False _, code = run_command("docker info", check=False) @@ -101,98 +944,23 @@ def is_docker_running() -> bool: def is_postgres_running_in_docker() -> bool: + """Check if PostgreSQL is running in Docker.""" _, code = run_command("docker ps | grep -q postgresql-container", check=False) return code == 0 def is_postgres_container_exists() -> bool: + """Check if PostgreSQL Docker container exists.""" _, code = run_command("docker ps -a | grep -q postgresql-container", check=False) return code == 0 -def setup_postgresql(no_postgres: bool = False) -> None: - """Set up PostgreSQL database for Skyvern. - - This function checks if a PostgreSQL server is running locally or in Docker. - If no PostgreSQL server is found, it offers to start a Docker container - running PostgreSQL (unless explicitly opted out). - - Args: - no_postgres: When True, skips starting a PostgreSQL container even if no - local PostgreSQL server is detected. Useful when planning to - use Docker Compose, which provides its own PostgreSQL service. - """ - - if command_exists("psql") and is_postgres_running(): - print("PostgreSQL is already running locally.") - if database_exists("skyvern", "skyvern"): - print("Database and user exist.") - else: - create_database_and_user() - return - - if no_postgres: - print("Skipping PostgreSQL container setup as requested.") - print("If you plan to use Docker Compose, its Postgres service will start automatically.") - return - - if not is_docker_running(): - print("Docker is not running or not installed. Please install or start Docker and try again.") - exit(1) - - if is_postgres_running_in_docker(): - print("PostgreSQL is already running in a Docker container.") - else: - if not no_postgres: - start_postgres = ( - input( - 'No local Postgres detected. Start a disposable container now? (Y/n) [Y]\n[Tip: choose "n" if you plan to run Skyvern via Docker Compose instead of `skyvern run server`] ' - ) - .strip() - .lower() - ) - if start_postgres in ["n", "no"]: - print("Skipping PostgreSQL container setup.") - print("If you plan to use Docker Compose, its Postgres service will start automatically.") - return - - print("Attempting to install PostgreSQL via Docker...") - if not is_postgres_container_exists(): - run_command( - "docker run --name postgresql-container -e POSTGRES_HOST_AUTH_METHOD=trust -d -p 5432:5432 postgres:14" - ) - else: - run_command("docker start postgresql-container") - print("PostgreSQL has been installed and started using Docker.") - - print("Waiting for PostgreSQL to start...") - time.sleep(20) - - _, code = run_command('docker exec postgresql-container psql -U postgres -c "\\du" | grep -q skyvern', check=False) - if code == 0: - print("Database user exists.") - else: - print("Creating database user...") - run_command("docker exec postgresql-container createuser -U postgres skyvern") - - _, code = run_command( - "docker exec postgresql-container psql -U postgres -lqt | cut -d \\| -f 1 | grep -qw skyvern", check=False - ) - if code == 0: - print("Database exists.") - else: - print("Creating database...") - run_command("docker exec postgresql-container createdb -U postgres skyvern -O skyvern") - print("Database and user created successfully.") - - def update_or_add_env_var(key: str, value: str) -> None: - """Update or add environment variable in .env file.""" - + """Update or add environment variable in .env file with better handling.""" env_path = Path(".env") if not env_path.exists(): env_path.touch() - # Write default environment variables using dotenv + # Write default environment variables defaults = { "ENV": "local", "ENABLE_OPENAI": "false", @@ -204,11 +972,6 @@ def update_or_add_env_var(key: str, value: str) -> None: "AZURE_API_KEY": "", "AZURE_API_BASE": "", "AZURE_API_VERSION": "", - "ENABLE_AZURE_GPT4O_MINI": "false", - "AZURE_GPT4O_MINI_DEPLOYMENT": "", - "AZURE_GPT4O_MINI_API_KEY": "", - "AZURE_GPT4O_MINI_API_BASE": "", - "AZURE_GPT4O_MINI_API_VERSION": "", "ENABLE_GEMINI": "false", "GEMINI_API_KEY": "", "ENABLE_NOVITA": "false", @@ -229,189 +992,30 @@ def update_or_add_env_var(key: str, value: str) -> None: for k, v in defaults.items(): set_key(env_path, k, v) + # Load environment to get current values load_dotenv(env_path) - set_key(env_path, key, value) + current_value = os.getenv(key) + + # Only update if value is different + if current_value != value: + set_key(env_path, key, value) + # Also update in current environment + os.environ[key] = value -def setup_llm_providers() -> None: - """Configure Large Language Model (LLM) Providers.""" - print("Configuring Large Language Model (LLM) Providers...") - print("Note: All information provided here will be stored only on your local machine.") - model_options = [] +async def _setup_local_organization() -> str: + """Set up and return the API key for the local organization.""" + skyvern_agent = Skyvern( + base_url=settings.SKYVERN_BASE_URL, + api_key=settings.SKYVERN_API_KEY, + ) + organization = await skyvern_agent.get_organization() - # OpenAI Configuration - print("To enable OpenAI, you must have an OpenAI API key.") - enable_openai = input("Do you want to enable OpenAI (y/n)? ").lower() == "y" - if enable_openai: - openai_api_key = input("Enter your OpenAI API key: ") - if not openai_api_key: - print("Error: OpenAI API key is required.") - print("OpenAI will not be enabled.") - else: - update_or_add_env_var("OPENAI_API_KEY", openai_api_key) - update_or_add_env_var("ENABLE_OPENAI", "true") - model_options.extend( - [ - "OPENAI_GPT4_1", - "OPENAI_GPT4_1_MINI", - "OPENAI_GPT4_1_NANO", - "OPENAI_GPT4O", - "OPENAI_O4_MINI", - "OPENAI_O3", - ] - ) - else: - update_or_add_env_var("ENABLE_OPENAI", "false") - - # Anthropic Configuration - print("To enable Anthropic, you must have an Anthropic API key.") - enable_anthropic = input("Do you want to enable Anthropic (y/n)? ").lower() == "y" - if enable_anthropic: - anthropic_api_key = input("Enter your Anthropic API key: ") - if not anthropic_api_key: - print("Error: Anthropic API key is required.") - print("Anthropic will not be enabled.") - else: - update_or_add_env_var("ANTHROPIC_API_KEY", anthropic_api_key) - update_or_add_env_var("ENABLE_ANTHROPIC", "true") - model_options.extend( - [ - "ANTHROPIC_CLAUDE3.5_SONNET", - "ANTHROPIC_CLAUDE3.7_SONNET", - ] - ) - else: - update_or_add_env_var("ENABLE_ANTHROPIC", "false") - - # Azure Configuration - print("To enable Azure, you must have an Azure deployment name, API key, base URL, and API version.") - enable_azure = input("Do you want to enable Azure (y/n)? ").lower() == "y" - if enable_azure: - azure_deployment = input("Enter your Azure deployment name: ") - azure_api_key = input("Enter your Azure API key: ") - azure_api_base = input("Enter your Azure API base URL: ") - azure_api_version = input("Enter your Azure API version: ") - if not all([azure_deployment, azure_api_key, azure_api_base, azure_api_version]): - print("Error: All Azure fields must be populated.") - print("Azure will not be enabled.") - else: - update_or_add_env_var("AZURE_DEPLOYMENT", azure_deployment) - update_or_add_env_var("AZURE_API_KEY", azure_api_key) - update_or_add_env_var("AZURE_API_BASE", azure_api_base) - update_or_add_env_var("AZURE_API_VERSION", azure_api_version) - update_or_add_env_var("ENABLE_AZURE", "true") - model_options.append("AZURE_OPENAI_GPT4O") - else: - update_or_add_env_var("ENABLE_AZURE", "false") - - # Gemini Configuration - print("To enable Gemini, you must have an Gemini API key.") - enable_gemini = input("Do you want to enable Gemini (y/n)? ").lower() == "y" - if enable_gemini: - gemini_api_key = input("Enter your Gemini API key: ") - if not gemini_api_key: - print("Error: Gemini API key is required.") - print("Gemini will not be enabled.") - else: - update_or_add_env_var("GEMINI_API_KEY", gemini_api_key) - update_or_add_env_var("ENABLE_GEMINI", "true") - model_options.extend( - [ - "GEMINI_FLASH_2_0", - "GEMINI_FLASH_2_0_LITE", - "GEMINI_2.5_PRO_PREVIEW_03_25", - "GEMINI_2.5_PRO_EXP_03_25", - ] - ) - else: - update_or_add_env_var("ENABLE_GEMINI", "false") - - # Novita AI Configuration - print("To enable Novita AI, you must have an Novita AI API key.") - enable_novita = input("Do you want to enable Novita AI (y/n)? ").lower() == "y" - if enable_novita: - novita_api_key = input("Enter your Novita AI API key: ") - if not novita_api_key: - print("Error: Novita AI API key is required.") - print("Novita AI will not be enabled.") - else: - update_or_add_env_var("NOVITA_API_KEY", novita_api_key) - update_or_add_env_var("ENABLE_NOVITA", "true") - model_options.extend( - [ - "NOVITA_DEEPSEEK_R1", - "NOVITA_DEEPSEEK_V3", - "NOVITA_LLAMA_3_3_70B", - "NOVITA_LLAMA_3_2_1B", - "NOVITA_LLAMA_3_2_3B", - "NOVITA_LLAMA_3_2_11B_VISION", - "NOVITA_LLAMA_3_1_8B", - "NOVITA_LLAMA_3_1_70B", - "NOVITA_LLAMA_3_1_405B", - "NOVITA_LLAMA_3_8B", - "NOVITA_LLAMA_3_70B", - ] - ) - else: - update_or_add_env_var("ENABLE_NOVITA", "false") - - # OpenAI Compatible Configuration - print("To enable an OpenAI-compatible provider, you must have a model name, API key, and API base URL.") - enable_openai_compatible = input("Do you want to enable an OpenAI-compatible provider (y/n)? ").lower() == "y" - if enable_openai_compatible: - openai_compatible_model_name = input("Enter the model name (e.g., 'yi-34b', 'mistral-large'): ") - openai_compatible_api_key = input("Enter your API key: ") - openai_compatible_api_base = input("Enter the API base URL (e.g., 'https://api.together.xyz/v1'): ") - openai_compatible_vision = input("Does this model support vision (y/n)? ").lower() == "y" - - if not all([openai_compatible_model_name, openai_compatible_api_key, openai_compatible_api_base]): - print("Error: All required fields must be populated.") - print("OpenAI-compatible provider will not be enabled.") - else: - update_or_add_env_var("OPENAI_COMPATIBLE_MODEL_NAME", openai_compatible_model_name) - update_or_add_env_var("OPENAI_COMPATIBLE_API_KEY", openai_compatible_api_key) - update_or_add_env_var("OPENAI_COMPATIBLE_API_BASE", openai_compatible_api_base) - - # Set vision support - if openai_compatible_vision: - update_or_add_env_var("OPENAI_COMPATIBLE_SUPPORTS_VISION", "true") - else: - update_or_add_env_var("OPENAI_COMPATIBLE_SUPPORTS_VISION", "false") - - # Optional: Ask for API version - openai_compatible_api_version = input("Enter API version (optional, press enter to skip): ") - if openai_compatible_api_version: - update_or_add_env_var("OPENAI_COMPATIBLE_API_VERSION", openai_compatible_api_version) - - update_or_add_env_var("ENABLE_OPENAI_COMPATIBLE", "true") - model_options.append("OPENAI_COMPATIBLE") - else: - update_or_add_env_var("ENABLE_OPENAI_COMPATIBLE", "false") - - # Model Selection - if not model_options: - print( - "No LLM providers enabled. You won't be able to run Skyvern unless you enable at least one provider. You can re-run this script to enable providers or manually update the .env file." - ) - else: - print("Available LLM models based on your selections:") - for i, model in enumerate(model_options, 1): - print(f"{i}. {model}") - - while True: - try: - model_choice = int(input(f"Choose a model by number (e.g., 1 for {model_options[0]}): ")) - if 1 <= model_choice <= len(model_options): - break - print(f"Please enter a number between 1 and {len(model_options)}") - except ValueError: - print("Please enter a valid number") - - chosen_model = model_options[model_choice - 1] - print(f"Chosen LLM Model: {chosen_model}") - update_or_add_env_var("LLM_KEY", chosen_model) - - print("LLM provider configurations updated in .env.") + org_auth_token = await app.DATABASE.get_valid_org_auth_token( + organization_id=organization.organization_id, + token_type=OrganizationAuthTokenType.api, + ) + return org_auth_token.token if org_auth_token else "" def get_default_chrome_location(host_system: str) -> str: @@ -431,162 +1035,113 @@ def get_default_chrome_location(host_system: str) -> str: return "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" -def setup_browser_config() -> tuple[str, Optional[str], Optional[str]]: - """Configure browser settings for Skyvern.""" - print("\nConfiguring web browser for scraping...") - browser_types = ["chromium-headless", "chromium-headful", "cdp-connect"] +def setup_mcp() -> None: + """Configure MCP for different Skyvern deployments.""" + host_system = detect_os() + path_to_env = setup_mcp_config() - for i, browser_type in enumerate(browser_types, 1): - print(f"{i}. {browser_type}") - if browser_type == "chromium-headless": - print(" - Runs Chrome in headless mode (no visible window)") - elif browser_type == "chromium-headful": - print(" - Runs Chrome with visible window") - elif browser_type == "cdp-connect": - print(" - Connects to an existing Chrome instance") - print(" - Requires Chrome to be running with remote debugging enabled") + # Configure integrations + integrations = [ + { + "name": "Claude Desktop", + "check_fn": lambda: is_claude_desktop_installed(host_system), + "setup_fn": lambda: setup_claude_desktop_config(host_system, path_to_env), + "not_installed_msg": "Claude Desktop is not installed. Please install it first." + }, + { + "name": "Cursor Editor", + "check_fn": lambda: is_cursor_installed(host_system), + "setup_fn": lambda: setup_cursor_config(host_system, path_to_env), + "not_installed_msg": "Cursor Editor is not installed. Please install it first." + }, + { + "name": "Windsurf", + "check_fn": lambda: is_windsurf_installed(host_system), + "setup_fn": lambda: setup_windsurf_config(host_system, path_to_env), + "not_installed_msg": "Windsurf is not installed. Please install it first." + } + ] - while True: - try: - choice = int(input("\nChoose browser type (1-3): ")) - if 1 <= choice <= len(browser_types): - selected_browser = browser_types[choice - 1] - break - print(f"Please enter a number between 1 and {len(browser_types)}") - except ValueError: - print("Please enter a valid number") - - browser_location = None - remote_debugging_url = None - - if selected_browser == "cdp-connect": - host_system = detect_os() - default_location = get_default_chrome_location(host_system) - print(f"\nDefault Chrome location for your system: {default_location}") - browser_location = input("Enter Chrome executable location (press Enter to use default): ").strip() - if not browser_location: - browser_location = default_location - - if not os.path.exists(browser_location): - print(f"Warning: Chrome not found at {browser_location}. Please verify the location is correct.") - - print("\nTo use CDP connection, Chrome must be running with remote debugging enabled.") - print("Example: chrome --remote-debugging-port=9222") - print("Default debugging URL: http://localhost:9222") - - default_port = "9222" - if remote_debugging_url is None: - remote_debugging_url = "http://localhost:9222" - elif ":" in remote_debugging_url.split("/")[-1]: - default_port = remote_debugging_url.split(":")[-1].split("/")[0] - - parsed_url = urlparse(remote_debugging_url) - version_url = f"{parsed_url.scheme}://{parsed_url.netloc}/json/version" - - print(f"\nChecking if Chrome is already running with remote debugging on port {default_port}...") - try: - response = requests.get(version_url, timeout=2) - if response.status_code == 200: - try: - browser_info = response.json() - print("Chrome is already running with remote debugging!") - if "Browser" in browser_info: - print(f"Browser: {browser_info['Browser']}") - if "webSocketDebuggerUrl" in browser_info: - print(f"WebSocket URL: {browser_info['webSocketDebuggerUrl']}") - print(f"Connected to {remote_debugging_url}") - return selected_browser, browser_location, remote_debugging_url - except json.JSONDecodeError: - print("Port is in use, but doesn't appear to be Chrome with remote debugging.") - except requests.RequestException: - print(f"No Chrome instance detected on {remote_debugging_url}") - - print("\nExecuting Chrome with remote debugging enabled:") - - if host_system == "darwin" or host_system == "linux": - chrome_cmd = f'{browser_location} --remote-debugging-port={default_port} --user-data-dir="$HOME/chrome-cdp-profile" --no-first-run --no-default-browser-check' - print(f" {chrome_cmd}") - elif host_system == "windows" or host_system == "wsl": - chrome_cmd = f'"{browser_location}" --remote-debugging-port={default_port} --user-data-dir="C:\\chrome-cdp-profile" --no-first-run --no-default-browser-check' - print(f" {chrome_cmd}") + # Set up each integration + for integration in integrations: + console.print(f"\n[bold]Setting up {integration['name']}[/]") + + # Check if installed + if not integration["check_fn"](): + console.print(f"[yellow]![/] {integration['not_installed_msg']}") + console.print(f"Skipping {integration['name']} integration setup.") + continue + + # Ask user if they want to set up this integration + if typer.confirm(f"Configure {integration['name']} integration?", default=True): + # Set up the integration + if integration["setup_fn"](): + console.print(f"[green]✓[/] {integration['name']} integration configured successfully") + else: + console.print(f"[red]×[/] Error configuring {integration['name']} integration") else: - print("Unsupported OS for Chrome configuration. Please set it up manually.") + console.print(f"Skipping {integration['name']} integration setup") - # Ask user if they want to execute the command - execute_browser = ( - input("\nWould you like to start Chrome with remote debugging now? (y/n) [y]: ").strip().lower() + console.print("\n[green]✓[/] MCP integration setup complete") + + +def setup_mcp_config() -> str: + """Find or prompt for the Python executable path and return it.""" + # Try to find Python + python_paths = [] + for python_cmd in ["python", "python3.11"]: + python_path = shutil.which(python_cmd) + if python_path: + python_paths.append((python_cmd, python_path)) + + if not python_paths: + console.print("[yellow]![/] Could not find Python 3.11 installation") + path_to_env = typer.prompt( + "Enter the full path to your Python 3.11 environment", + default="/opt/homebrew/bin/python3.11" ) - if not execute_browser or execute_browser == "y": - print(f"Starting Chrome with remote debugging on port {default_port}...") + else: + # Show found Python installations + console.print("[green]✓[/] Found Python installations:") + for i, (cmd, path) in enumerate(python_paths, 1): + console.print(f" {i}. {cmd}: {path}") + + # Use the first one as default + _, default_path = python_paths[0] + path_to_env = default_path + + if len(python_paths) > 1: + # Let user choose if multiple were found + choice = typer.prompt( + "Which Python installation do you want to use? (Enter number)", + default="1" + ) try: - # Execute in background - different approach per OS - if host_system in ["darwin", "linux"]: - subprocess.Popen(f"nohup {chrome_cmd} > /dev/null 2>&1 &", shell=True) - elif host_system == "windows": - subprocess.Popen(f"start {chrome_cmd}", shell=True) - elif host_system == "wsl": - subprocess.Popen(f"cmd.exe /c start {chrome_cmd}", shell=True) - - print(f"Chrome started successfully. Connecting to {remote_debugging_url}") - - print("Waiting for Chrome to initialize...") - time.sleep(2) - - try: - verification_response = requests.get(version_url, timeout=5) - if verification_response.status_code == 200: - try: - browser_info = verification_response.json() - print("Connection verified! Chrome is running with remote debugging.") - if "Browser" in browser_info: - print(f"Browser: {browser_info['Browser']}") - except json.JSONDecodeError: - print("Warning: Response from Chrome debugging port is not valid JSON.") - else: - print(f"Warning: Chrome responded with status code {verification_response.status_code}") - except requests.RequestException as e: - print(f"Warning: Could not verify Chrome is running properly: {e}") - print("You may need to check Chrome manually or try a different port.") - except Exception as e: - print(f"Error starting Chrome: {e}") - print("Please start Chrome manually using the command above.") - - remote_debugging_url = input("Enter remote debugging URL (press Enter for default): ").strip() - if not remote_debugging_url: - remote_debugging_url = "http://localhost:9222" - - return selected_browser, browser_location, remote_debugging_url + index = int(choice) - 1 + if 0 <= index < len(python_paths): + _, path_to_env = python_paths[index] + except ValueError: + console.print(f"[yellow]![/] Invalid choice, using default: {path_to_env}") + + return path_to_env -async def _setup_local_organization() -> str: - """ - Returns the API key for the local organization generated - """ - skyvern_agent = Skyvern( - base_url=settings.SKYVERN_BASE_URL, - api_key=settings.SKYVERN_API_KEY, - ) - organization = await skyvern_agent.get_organization() - - org_auth_token = await app.DATABASE.get_valid_org_auth_token( - organization_id=organization.organization_id, - token_type=OrganizationAuthTokenType.api, - ) - return org_auth_token.token if org_auth_token else "" - - -@cli_app.command(name="migrate") -def migrate() -> None: - migrate_db() +def is_claude_desktop_installed(host_system: str) -> bool: + """Check if Claude Desktop is installed.""" + try: + config_path = os.path.dirname(get_claude_config_path(host_system)) + return os.path.exists(config_path) + except Exception: + return False def get_claude_config_path(host_system: str) -> str: - """Get the Claude Desktop config file path for the current OS.""" + """Get the Claude Desktop config file path.""" if host_system == "wsl": roaming_path = get_windows_appdata_roaming() if roaming_path is None: raise RuntimeError("Could not locate Windows AppData\\Roaming path from WSL") - return os.path.join(str(roaming_path), "Claude", "claude_desktop_config.json") + return os.path.join(str(roaming_path), ".cursor", "mcp.json") base_paths = { "darwin": ["~/Library/Application Support/Claude"], @@ -606,152 +1161,12 @@ def get_claude_config_path(host_system: str) -> str: raise Exception(f"Unsupported host system: {host_system}") -def get_claude_command_config( - host_system: str, path_to_env: str, path_to_server: str, env_vars: str -) -> tuple[str, list]: - """Get the command and arguments for Claude Desktop configuration.""" - base_env_vars = f"{env_vars} ENABLE_OPENAI=true LOG_LEVEL=CRITICAL" - artifacts_path = os.path.join(os.path.abspath("./"), "artifacts") - - if host_system == "wsl": - env_vars = f"{base_env_vars} ARTIFACT_STORAGE_PATH={artifacts_path} BROWSER_TYPE=chromium-headless" - return "wsl.exe", ["bash", "-c", f"{env_vars} {path_to_env} {path_to_server}"] - - if host_system in ["linux", "darwin"]: - env_vars = f"{base_env_vars} ARTIFACT_STORAGE_PATH={artifacts_path}" - return path_to_env, [path_to_server] - - raise Exception(f"Unsupported host system: {host_system}") - - -def is_claude_desktop_installed(host_system: str) -> bool: - """Check if Claude Desktop is installed by looking for its config directory.""" - try: - config_path = os.path.dirname(get_claude_config_path(host_system)) - return os.path.exists(config_path) - except Exception: - return False - - -def get_cursor_config_path(host_system: str) -> str: - """Get the Cursor config file path for the current OS.""" - if host_system == "wsl": - roaming_path = get_windows_appdata_roaming() - if roaming_path is None: - raise RuntimeError("Could not locate Windows AppData\\Roaming path from WSL") - return os.path.join(str(roaming_path), ".cursor", "mcp.json") - - # For both darwin and linux, use ~/.cursor/mcp.json - return os.path.expanduser("~/.cursor/mcp.json") - - -def is_cursor_installed(host_system: str) -> bool: - """Check if Cursor is installed by looking for its config directory.""" - try: - config_dir = os.path.expanduser("~/.cursor") - return os.path.exists(config_dir) - except Exception: - return False - - -def is_windsurf_installed(host_system: str) -> bool: - """Check if Windsurf is installed by looking for its config directory.""" - try: - config_dir = os.path.expanduser("~/.codeium/windsurf") - return os.path.exists(config_dir) - except Exception: - return False - - -def get_windsurf_config_path(host_system: str) -> str: - """Get the Windsurf config file path for the current OS.""" - return os.path.expanduser("~/.codeium/windsurf/mcp_config.json") - - -def setup_windsurf_config(host_system: str, path_to_env: str) -> bool: - """Set up Windsurf configuration for Skyvern MCP.""" - if not is_windsurf_installed(host_system): - return False - - load_dotenv(".env") - skyvern_base_url = os.environ.get("SKYVERN_BASE_URL", "") - skyvern_api_key = os.environ.get("SKYVERN_API_KEY", "") - if not skyvern_base_url or not skyvern_api_key: - print( - "Error: SKYVERN_BASE_URL and SKYVERN_API_KEY must be set in .env file to set up Windsurf MCP. Please open {path_windsurf_config} and set these variables manually." - ) - - try: - path_windsurf_config = get_windsurf_config_path(host_system) - os.makedirs(os.path.dirname(path_windsurf_config), exist_ok=True) - if not os.path.exists(path_windsurf_config): - with open(path_windsurf_config, "w") as f: - json.dump({"mcpServers": {}}, f, indent=2) - - windsurf_config: dict = {"mcpServers": {}} - - if os.path.exists(path_windsurf_config): - try: - with open(path_windsurf_config, "r") as f: - windsurf_config = json.load(f) - windsurf_config["mcpServers"].pop("Skyvern", None) - windsurf_config["mcpServers"]["Skyvern"] = { - "env": { - "SKYVERN_BASE_URL": skyvern_base_url, - "SKYVERN_API_KEY": skyvern_api_key, - }, - "command": path_to_env, - "args": ["-m", "skyvern", "run", "mcp"], - } - except json.JSONDecodeError: - print( - f"JSONDecodeError when reading Error configuring Windsurf. Please open {path_windsurf_config} and fix the json config first." - ) - return False - - with open(path_windsurf_config, "w") as f: - json.dump(windsurf_config, f, indent=2) - except Exception as e: - print(f"Error configuring Windsurf: {e}") - return False - - print(f"Windsurf MCP configuration updated successfully at {path_windsurf_config}.") - return True - - -def setup_mcp_config() -> str: - """ - return the path to the python environment - """ - # Try to find Python in this order: python, python3, python3.12, python3.11, python3.10, python3.9 - python_paths = [] - for python_cmd in ["python", "python3.11"]: - python_path = shutil.which(python_cmd) - if python_path: - python_paths.append((python_cmd, python_path)) - - if not python_paths: - print("Error: Could not find any Python installation. Please install Python 3.11 first.") - path_to_env = typer.prompt( - "Enter the full path to your python 3.11 environment. For example in MacOS if you installed it using Homebrew, it would be /opt/homebrew/bin/python3.11" - ) - else: - # Show the first found Python as default - _, default_path = python_paths[0] - path_to_env = default_path - return path_to_env - - def setup_claude_desktop_config(host_system: str, path_to_env: str) -> bool: - """Set up Claude Desktop configuration with given command and args.""" - if not is_claude_desktop_installed(host_system): - print("Claude Desktop is not installed. Please install it first.") - return False - + """Set up Claude Desktop configuration.""" try: path_claude_config = get_claude_config_path(host_system) - os.makedirs(os.path.dirname(path_claude_config), exist_ok=True) + if not os.path.exists(path_claude_config): with open(path_claude_config, "w") as f: json.dump({"mcpServers": {}}, f, indent=2) @@ -762,7 +1177,8 @@ def setup_claude_desktop_config(host_system: str, path_to_env: str) -> bool: skyvern_api_key = os.environ.get("SKYVERN_API_KEY", "") if not skyvern_base_url or not skyvern_api_key: - print("Error: SKYVERN_BASE_URL and SKYVERN_API_KEY must be set in .env file") + console.print("[red]×[/] SKYVERN_BASE_URL and SKYVERN_API_KEY must be set in .env file") + return False with open(path_claude_config, "r") as f: claude_config = json.load(f) @@ -779,233 +1195,18 @@ def setup_claude_desktop_config(host_system: str, path_to_env: str) -> bool: with open(path_claude_config, "w") as f: json.dump(claude_config, f, indent=2) - print(f"Claude Desktop MCP configuration updated successfully at {path_claude_config}.") return True - except Exception as e: - print(f"Error configuring Claude Desktop: {e}") + console.print(f"[red]×[/] Error configuring Claude Desktop: {e}") return False -def setup_cursor_config(host_system: str, path_to_env: str) -> bool: - """Set up Cursor configuration with given command and args.""" - if not is_cursor_installed(host_system): - return False - +def is_cursor_installed(host_system: str) -> bool: + """Check if Cursor is installed.""" try: - path_cursor_config = get_cursor_config_path(host_system) - - os.makedirs(os.path.dirname(path_cursor_config), exist_ok=True) - if not os.path.exists(path_cursor_config): - with open(path_cursor_config, "w") as f: - json.dump({"mcpServers": {}}, f, indent=2) - - load_dotenv(".env") - skyvern_base_url = os.environ.get("SKYVERN_BASE_URL", "") - skyvern_api_key = os.environ.get("SKYVERN_API_KEY", "") - - if not skyvern_base_url or not skyvern_api_key: - print( - f"Error: SKYVERN_BASE_URL and SKYVERN_API_KEY must be set in .env file to set up Cursor MCP. Please open {path_cursor_config} and set the these variables manually." - ) - - cursor_config: dict = {"mcpServers": {}} - - if os.path.exists(path_cursor_config): - try: - with open(path_cursor_config, "r") as f: - cursor_config = json.load(f) - cursor_config["mcpServers"].pop("Skyvern", None) - cursor_config["mcpServers"]["Skyvern"] = { - "env": { - "SKYVERN_BASE_URL": skyvern_base_url, - "SKYVERN_API_KEY": skyvern_api_key, - }, - "command": path_to_env, - "args": ["-m", "skyvern", "run", "mcp"], - } - except json.JSONDecodeError: - print( - f"JSONDecodeError when reading Error configuring Cursor. Please open {path_cursor_config} and fix the json config first." - ) - return False - - with open(path_cursor_config, "w") as f: - json.dump(cursor_config, f, indent=2) - - print(f"Cursor MCP configuration updated successfully at {path_cursor_config}") - return True - - except Exception as e: - print(f"Error configuring Cursor: {e}") - return False - - -@setup_app.command(name="mcp") -def setup_mcp() -> None: - """Configure MCP for different Skyvern deployments.""" - host_system = detect_os() - - path_to_env = setup_mcp_config() - - # Configure both Claude Desktop and Cursor - claude_response = input("Would you like to set up MCP integration for Claude Desktop? (y/n) [y]: ").strip().lower() - if not claude_response or claude_response == "y": - setup_claude_desktop_config(host_system, path_to_env) - - cursor_response = input("Would you like to set up MCP integration for Cursor? (y/n) [y]: ").strip().lower() - if not cursor_response or cursor_response == "y": - setup_cursor_config(host_system, path_to_env) - - windsurf_response = input("Would you like to set up MCP integration for Windsurf? (y/n) [y]: ").strip().lower() - if not windsurf_response or windsurf_response == "y": - setup_windsurf_config(host_system, path_to_env) - - -@run_app.command(name="server") -def run_server() -> None: - load_dotenv() - load_dotenv(".env") - from skyvern.config import settings - - port = settings.PORT - uvicorn.run( - "skyvern.forge.api_app:app", - host="0.0.0.0", - port=port, - log_level="info", - ) - - -@run_app.command(name="ui") -def run_ui() -> None: - # FIXME: This is untested and may not work - """Run the Skyvern UI server.""" - # Check for and handle any existing process on port 8080 - try: - result = subprocess.run("lsof -t -i :8080", shell=True, capture_output=True, text=True, check=False) - if result.stdout.strip(): - response = input("Process already running on port 8080. Kill it? (y/n) [y]: ").strip().lower() - if not response or response == "y": - subprocess.run("lsof -t -i :8080 | xargs kill", shell=True, check=False) - else: - print("UI server not started. Process already running on port 8080.") - return + config_dir = os.path.expanduser("~/.cursor") + return os.path.exists(config_dir) except Exception: - pass - - # Get the frontend directory path relative to this file - current_dir = Path(__file__).parent.parent.parent - frontend_dir = current_dir / "skyvern-frontend" - if not frontend_dir.exists(): - print(f"[ERROR] Skyvern Frontend directory not found at {frontend_dir}. Are you in the right repo?") - return - - if not (frontend_dir / ".env").exists(): - shutil.copy(frontend_dir / ".env.example", frontend_dir / ".env") - # Update VITE_SKYVERN_API_KEY in frontend .env with SKYVERN_API_KEY from main .env - main_env_path = current_dir / ".env" - if main_env_path.exists(): - load_dotenv(main_env_path) - skyvern_api_key = os.getenv("SKYVERN_API_KEY") - if skyvern_api_key: - frontend_env_path = frontend_dir / ".env" - set_key(str(frontend_env_path), "VITE_SKYVERN_API_KEY", skyvern_api_key) - else: - print("[ERROR] SKYVERN_API_KEY not found in .env file") - else: - print("[ERROR] .env file not found") - - print("Successfully set up frontend .env file") - - # Change to frontend directory - os.chdir(frontend_dir) - - # Run npm install and start - try: - subprocess.run("npm install --silent", shell=True, check=True) - subprocess.run("npm run start", shell=True, check=True) - except subprocess.CalledProcessError as e: - print(f"Error running UI server: {e}") - return + return False -@run_app.command(name="mcp") -def run_mcp() -> None: - """Run the MCP server.""" - mcp.run(transport="stdio") - - -@cli_app.command(name="init") -def init(no_postgres: bool = typer.Option(False, "--no-postgres", help="Skip starting PostgreSQL container")) -> None: - run_local_str = ( - input("Would you like to run Skyvern locally or in the cloud? (local/cloud) [cloud]: ").strip().lower() - ) - run_local = run_local_str == "local" if run_local_str else False - - if run_local: - setup_postgresql(no_postgres) - migrate_db() - api_key = asyncio.run(_setup_local_organization()) - - if os.path.exists(".env"): - print(".env file already exists, skipping initialization.") - redo_llm_setup = input("Do you want to go through LLM provider setup again (y/n)? ") - if redo_llm_setup.lower() != "y": - return - - print("Initializing .env file...") - setup_llm_providers() - - # Configure browser settings - browser_type, browser_location, remote_debugging_url = setup_browser_config() - update_or_add_env_var("BROWSER_TYPE", browser_type) - if browser_location: - update_or_add_env_var("CHROME_EXECUTABLE_PATH", browser_location) - if remote_debugging_url: - update_or_add_env_var("BROWSER_REMOTE_DEBUGGING_URL", remote_debugging_url) - - print("Defaulting Skyvern Base URL to: http://localhost:8000") - update_or_add_env_var("SKYVERN_BASE_URL", "http://localhost:8000") - - else: - base_url = input("Enter Skyvern base URL (press Enter for https://api.skyvern.com): ").strip() - if not base_url: - base_url = "https://api.skyvern.com" - - print("To get your API key:") - print("1. Create an account at https://app.skyvern.com") - print("2. Go to Settings") - print("3. Copy your API key") - api_key = input("Enter your Skyvern API key: ").strip() - if not api_key: - print("API key is required") - api_key = input("Enter your Skyvern API key: ").strip() - - update_or_add_env_var("SKYVERN_BASE_URL", base_url) - - # Ask for email or generate UUID - analytics_id = input("Please enter your email for analytics (press enter to skip): ") - if not analytics_id: - analytics_id = str(uuid.uuid4()) - - update_or_add_env_var("ANALYTICS_ID", analytics_id) - update_or_add_env_var("SKYVERN_API_KEY", api_key) - print(".env file has been initialized.") - - # Ask if user wants to configure MCP server - configure_mcp = input("\nWould you like to configure the MCP server (y/n)? ").lower() == "y" - if configure_mcp: - setup_mcp() - print("\nMCP server configuration completed.") - - if not run_local: - print("\nMCP configuration is complete! Your AI applications are now ready to use Skyvern Cloud.") - - if run_local: - print("\nInstalling Chromium browser...") - subprocess.run(["playwright", "install", "chromium"], check=True) - print("Chromium installation complete.") - - print("\nTo start using Skyvern, run:") - print(" skyvern run server")