Merge remote-tracking branch 'upstream/main' into minor-pickle-improvement-2
This commit is contained in:
commit
51961b975d
19
.github/ISSUE_TEMPLATE/enhancement_request.md
vendored
Normal file
19
.github/ISSUE_TEMPLATE/enhancement_request.md
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
name: Enhancement Request
|
||||
about: Suggest an enhancement for an existing Reflex feature.
|
||||
title: ''
|
||||
labels: 'enhancement'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Describe the Enhancement you want**
|
||||
A clear and concise description of what the improvement does.
|
||||
|
||||
- Which feature do you want to improve? (and what problem does it have)
|
||||
|
||||
- What is the benefit of the enhancement?
|
||||
|
||||
- Show an example/usecase were the improvement are needed.
|
||||
|
||||
**Additional context**
|
||||
Add any other context here.
|
18
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
18
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest a new feature for Reflex
|
||||
title: ''
|
||||
labels: 'feature request'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the Features**
|
||||
A clear and concise description of what the features does.
|
||||
|
||||
- What is the purpose of the feature?
|
||||
|
||||
- Show an example / use cases for the new feature.
|
||||
|
||||
**Additional context**
|
||||
Add any other context here.
|
6
.github/workflows/benchmarks.yml
vendored
6
.github/workflows/benchmarks.yml
vendored
@ -80,7 +80,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Show OS combos first in GUI
|
||||
os: [ubuntu-latest, windows-latest, macos-12]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
python-version: ['3.9.18', '3.10.13', '3.11.5', '3.12.0']
|
||||
exclude:
|
||||
- os: windows-latest
|
||||
@ -92,7 +92,7 @@ jobs:
|
||||
python-version: '3.9.18'
|
||||
- os: macos-latest
|
||||
python-version: '3.10.13'
|
||||
- os: macos-12
|
||||
- os: macos-latest
|
||||
python-version: '3.12.0'
|
||||
include:
|
||||
- os: windows-latest
|
||||
@ -155,7 +155,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Show OS combos first in GUI
|
||||
os: [ubuntu-latest, windows-latest, macos-12]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
python-version: ['3.11.5']
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
@ -58,7 +58,7 @@ jobs:
|
||||
working-directory: ./reflex-web
|
||||
run: poetry run uv pip install -r requirements.txt
|
||||
- name: Install additional dependencies for DB access
|
||||
run: poetry run uv pip install psycopg2-binary
|
||||
run: poetry run uv pip install psycopg
|
||||
- name: Init Website for reflex-web
|
||||
working-directory: ./reflex-web
|
||||
run: poetry run reflex init
|
||||
|
@ -22,9 +22,9 @@ jobs:
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
matrix:
|
||||
state_manager: ["redis", "memory"]
|
||||
state_manager: ['redis', 'memory']
|
||||
python-version: ['3.11.5', '3.12.0', '3.13.0']
|
||||
split_index: [1, 2]
|
||||
python-version: ["3.11.5", "3.12.0"]
|
||||
fail-fast: false
|
||||
runs-on: ubuntu-22.04
|
||||
services:
|
||||
|
10
.github/workflows/integration_tests.yml
vendored
10
.github/workflows/integration_tests.yml
vendored
@ -43,7 +43,7 @@ jobs:
|
||||
matrix:
|
||||
# Show OS combos first in GUI
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
python-version: ['3.9.18', '3.10.13', '3.11.5', '3.12.0']
|
||||
python-version: ['3.9.18', '3.10.13', '3.11.5', '3.12.0', '3.13.0']
|
||||
exclude:
|
||||
- os: windows-latest
|
||||
python-version: '3.10.13'
|
||||
@ -73,7 +73,7 @@ jobs:
|
||||
run: |
|
||||
poetry run uv pip install -r requirements.txt
|
||||
- name: Install additional dependencies for DB access
|
||||
run: poetry run uv pip install psycopg2-binary
|
||||
run: poetry run uv pip install psycopg
|
||||
- name: Check export --backend-only before init for counter example
|
||||
working-directory: ./reflex-examples/counter
|
||||
run: |
|
||||
@ -147,7 +147,7 @@ jobs:
|
||||
working-directory: ./reflex-web
|
||||
run: poetry run uv pip install $(grep -ivE "reflex " requirements.txt)
|
||||
- name: Install additional dependencies for DB access
|
||||
run: poetry run uv pip install psycopg2-binary
|
||||
run: poetry run uv pip install psycopg
|
||||
- name: Init Website for reflex-web
|
||||
working-directory: ./reflex-web
|
||||
run: poetry run reflex init
|
||||
@ -198,7 +198,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.11.5', '3.12.0']
|
||||
runs-on: macos-12
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup_build_env
|
||||
@ -216,7 +216,7 @@ jobs:
|
||||
working-directory: ./reflex-web
|
||||
run: poetry run uv pip install -r requirements.txt
|
||||
- name: Install additional dependencies for DB access
|
||||
run: poetry run uv pip install psycopg2-binary
|
||||
run: poetry run uv pip install psycopg
|
||||
- name: Init Website for reflex-web
|
||||
working-directory: ./reflex-web
|
||||
run: poetry run reflex init
|
||||
|
7
.github/workflows/unit_tests.yml
vendored
7
.github/workflows/unit_tests.yml
vendored
@ -28,7 +28,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
python-version: ['3.9.18', '3.10.13', '3.11.5', '3.12.0']
|
||||
python-version: ['3.9.18', '3.10.13', '3.11.5', '3.12.0', '3.13.0']
|
||||
# Windows is a bit behind on Python version availability in Github
|
||||
exclude:
|
||||
- os: windows-latest
|
||||
@ -88,8 +88,9 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.9.18', '3.10.13', '3.11.5', '3.12.0']
|
||||
runs-on: macos-12
|
||||
# Note: py39, py310 versions chosen due to available arm64 darwin builds.
|
||||
python-version: ['3.9.13', '3.10.11', '3.11.5', '3.12.0', '3.13.0']
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup_build_env
|
||||
|
@ -3,7 +3,7 @@ fail_fast: true
|
||||
repos:
|
||||
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: v0.7.4
|
||||
rev: v0.8.2
|
||||
hooks:
|
||||
- id: ruff-format
|
||||
args: [reflex, tests]
|
||||
|
@ -23,7 +23,7 @@
|
||||
# for example, pass `docker build --platform=linux/amd64 ...`
|
||||
|
||||
# Stage 1: init
|
||||
FROM python:3.11 as init
|
||||
FROM python:3.13 as init
|
||||
|
||||
ARG uv=/root/.local/bin/uv
|
||||
|
||||
@ -48,11 +48,11 @@ RUN $uv pip install -r requirements.txt
|
||||
RUN reflex init
|
||||
|
||||
# Stage 2: copy artifacts into slim image
|
||||
FROM python:3.11-slim
|
||||
FROM python:3.13-slim
|
||||
WORKDIR /app
|
||||
RUN adduser --disabled-password --home /app reflex
|
||||
COPY --chown=reflex --from=init /app /app
|
||||
# Install libpq-dev for psycopg2 (skip if not using postgres).
|
||||
# Install libpq-dev for psycopg (skip if not using postgres).
|
||||
RUN apt-get update -y && apt-get install -y libpq-dev && rm -rf /var/lib/apt/lists/*
|
||||
USER reflex
|
||||
ENV PATH="/app/.venv/bin:$PATH" PYTHONUNBUFFERED=1
|
||||
|
@ -2,7 +2,7 @@
|
||||
# instance of a Reflex app.
|
||||
|
||||
# Stage 1: init
|
||||
FROM python:3.11 as init
|
||||
FROM python:3.13 as init
|
||||
|
||||
ARG uv=/root/.local/bin/uv
|
||||
|
||||
@ -35,11 +35,11 @@ RUN rm -rf .web && mkdir .web
|
||||
RUN mv /tmp/_static .web/_static
|
||||
|
||||
# Stage 2: copy artifacts into slim image
|
||||
FROM python:3.11-slim
|
||||
FROM python:3.13-slim
|
||||
WORKDIR /app
|
||||
RUN adduser --disabled-password --home /app reflex
|
||||
COPY --chown=reflex --from=init /app /app
|
||||
# Install libpq-dev for psycopg2 (skip if not using postgres).
|
||||
# Install libpq-dev for psycopg (skip if not using postgres).
|
||||
RUN apt-get update -y && apt-get install -y libpq-dev && rm -rf /var/lib/apt/lists/*
|
||||
USER reflex
|
||||
ENV PATH="/app/.venv/bin:$PATH" PYTHONUNBUFFERED=1
|
||||
|
@ -15,7 +15,7 @@ services:
|
||||
|
||||
app:
|
||||
environment:
|
||||
DB_URL: postgresql+psycopg2://postgres:secret@db/postgres
|
||||
DB_URL: postgresql+psycopg://postgres:secret@db/postgres
|
||||
REDIS_URL: redis://redis:6379
|
||||
depends_on:
|
||||
- db
|
||||
|
3
docker-example/production-one-port/.dockerignore
Normal file
3
docker-example/production-one-port/.dockerignore
Normal file
@ -0,0 +1,3 @@
|
||||
.web
|
||||
!.web/bun.lockb
|
||||
!.web/package.json
|
14
docker-example/production-one-port/Caddyfile
Normal file
14
docker-example/production-one-port/Caddyfile
Normal file
@ -0,0 +1,14 @@
|
||||
:{$PORT}
|
||||
|
||||
encode gzip
|
||||
|
||||
@backend_routes path /_event/* /ping /_upload /_upload/*
|
||||
handle @backend_routes {
|
||||
reverse_proxy localhost:8000
|
||||
}
|
||||
|
||||
root * /srv
|
||||
route {
|
||||
try_files {path} {path}/ /404.html
|
||||
file_server
|
||||
}
|
62
docker-example/production-one-port/Dockerfile
Normal file
62
docker-example/production-one-port/Dockerfile
Normal file
@ -0,0 +1,62 @@
|
||||
# This Dockerfile is used to deploy a single-container Reflex app instance
|
||||
# to services like Render, Railway, Heroku, GCP, and others.
|
||||
|
||||
# If the service expects a different port, provide it here (f.e Render expects port 10000)
|
||||
ARG PORT=8080
|
||||
# Only set for local/direct access. When TLS is used, the API_URL is assumed to be the same as the frontend.
|
||||
ARG API_URL
|
||||
|
||||
# It uses a reverse proxy to serve the frontend statically and proxy to backend
|
||||
# from a single exposed port, expecting TLS termination to be handled at the
|
||||
# edge by the given platform.
|
||||
FROM python:3.13 as builder
|
||||
|
||||
RUN mkdir -p /app/.web
|
||||
RUN python -m venv /app/.venv
|
||||
ENV PATH="/app/.venv/bin:$PATH"
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install python app requirements and reflex in the container
|
||||
COPY requirements.txt .
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
# Install reflex helper utilities like bun/fnm/node
|
||||
COPY rxconfig.py ./
|
||||
RUN reflex init
|
||||
|
||||
# Install pre-cached frontend dependencies (if exist)
|
||||
COPY *.web/bun.lockb *.web/package.json .web/
|
||||
RUN if [ -f .web/bun.lockb ]; then cd .web && ~/.local/share/reflex/bun/bin/bun install --frozen-lockfile; fi
|
||||
|
||||
# Copy local context to `/app` inside container (see .dockerignore)
|
||||
COPY . .
|
||||
|
||||
ARG PORT API_URL
|
||||
# Download other npm dependencies and compile frontend
|
||||
RUN API_URL=${API_URL:-http://localhost:$PORT} reflex export --loglevel debug --frontend-only --no-zip && mv .web/_static/* /srv/ && rm -rf .web
|
||||
|
||||
|
||||
# Final image with only necessary files
|
||||
FROM python:3.13-slim
|
||||
|
||||
# Install Caddy and redis server inside image
|
||||
RUN apt-get update -y && apt-get install -y caddy redis-server && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ARG PORT API_URL
|
||||
ENV PATH="/app/.venv/bin:$PATH" PORT=$PORT API_URL=${API_URL:-http://localhost:$PORT} REDIS_URL=redis://localhost PYTHONUNBUFFERED=1
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app /app
|
||||
COPY --from=builder /srv /srv
|
||||
|
||||
# Needed until Reflex properly passes SIGTERM on backend.
|
||||
STOPSIGNAL SIGKILL
|
||||
|
||||
EXPOSE $PORT
|
||||
|
||||
# Apply migrations before starting the backend.
|
||||
CMD [ -d alembic ] && reflex db migrate; \
|
||||
caddy start && \
|
||||
redis-server --daemonize yes && \
|
||||
exec reflex run --env prod --backend-only
|
37
docker-example/production-one-port/README.md
Normal file
37
docker-example/production-one-port/README.md
Normal file
@ -0,0 +1,37 @@
|
||||
# production-one-port
|
||||
|
||||
This docker deployment runs Reflex in prod mode, exposing a single HTTP port:
|
||||
* `8080` (`$PORT`) - Caddy server hosting the frontend statically and proxying requests to the backend.
|
||||
|
||||
The deployment also runs a local Redis server to store state for each user.
|
||||
|
||||
Conceptually it is similar to the `simple-one-port` example except it:
|
||||
* has layer caching for python, reflex, and node dependencies
|
||||
* uses multi-stage build to reduce the size of the final image
|
||||
|
||||
Using this method may be preferable for deploying in memory constrained
|
||||
environments, because it serves a static frontend export, rather than running
|
||||
the NextJS server via node.
|
||||
|
||||
## Build
|
||||
|
||||
```console
|
||||
docker build -t reflex-production-one-port .
|
||||
```
|
||||
|
||||
## Run
|
||||
|
||||
```console
|
||||
docker run -p 8080:8080 reflex-production-one-port
|
||||
```
|
||||
|
||||
Note that this container has _no persistence_ and will lose all data when
|
||||
stopped. You can use bind mounts or named volumes to persist the database and
|
||||
uploaded_files directories as needed.
|
||||
|
||||
## Usage
|
||||
|
||||
This container should be used with an existing load balancer or reverse proxy to
|
||||
terminate TLS.
|
||||
|
||||
It is also useful for deploying to simple app platforms, such as Render or Heroku.
|
@ -4,7 +4,7 @@
|
||||
# It uses a reverse proxy to serve the frontend statically and proxy to backend
|
||||
# from a single exposed port, expecting TLS termination to be handled at the
|
||||
# edge by the given platform.
|
||||
FROM python:3.11
|
||||
FROM python:3.13
|
||||
|
||||
# If the service expects a different port, provide it here (f.e Render expects port 10000)
|
||||
ARG PORT=8080
|
||||
|
@ -1,5 +1,5 @@
|
||||
# This Dockerfile is used to deploy a simple single-container Reflex app instance.
|
||||
FROM python:3.12
|
||||
FROM python:3.13
|
||||
|
||||
RUN apt-get update && apt-get install -y redis-server && rm -rf /var/lib/apt/lists/*
|
||||
ENV REDIS_URL=redis://localhost PYTHONUNBUFFERED=1
|
||||
|
637
poetry.lock
generated
637
poetry.lock
generated
@ -32,24 +32,24 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "anyio"
|
||||
version = "4.6.2.post1"
|
||||
version = "4.7.0"
|
||||
description = "High level compatibility layer for multiple asynchronous event loop implementations"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"},
|
||||
{file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"},
|
||||
{file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"},
|
||||
{file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""}
|
||||
idna = ">=2.8"
|
||||
sniffio = ">=1.1"
|
||||
typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""}
|
||||
typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""}
|
||||
|
||||
[package.extras]
|
||||
doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
|
||||
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"]
|
||||
doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"]
|
||||
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"]
|
||||
trio = ["trio (>=0.26.1)"]
|
||||
|
||||
[[package]]
|
||||
@ -386,73 +386,73 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "coverage"
|
||||
version = "7.6.7"
|
||||
version = "7.6.9"
|
||||
description = "Code coverage measurement for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "coverage-7.6.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:108bb458827765d538abcbf8288599fee07d2743357bdd9b9dad456c287e121e"},
|
||||
{file = "coverage-7.6.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c973b2fe4dc445cb865ab369df7521df9c27bf40715c837a113edaa2aa9faf45"},
|
||||
{file = "coverage-7.6.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c6b24007c4bcd0b19fac25763a7cac5035c735ae017e9a349b927cfc88f31c1"},
|
||||
{file = "coverage-7.6.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acbb8af78f8f91b3b51f58f288c0994ba63c646bc1a8a22ad072e4e7e0a49f1c"},
|
||||
{file = "coverage-7.6.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad32a981bcdedb8d2ace03b05e4fd8dace8901eec64a532b00b15217d3677dd2"},
|
||||
{file = "coverage-7.6.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:34d23e28ccb26236718a3a78ba72744212aa383141961dd6825f6595005c8b06"},
|
||||
{file = "coverage-7.6.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e25bacb53a8c7325e34d45dddd2f2fbae0dbc230d0e2642e264a64e17322a777"},
|
||||
{file = "coverage-7.6.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:af05bbba896c4472a29408455fe31b3797b4d8648ed0a2ccac03e074a77e2314"},
|
||||
{file = "coverage-7.6.7-cp310-cp310-win32.whl", hash = "sha256:796c9b107d11d2d69e1849b2dfe41730134b526a49d3acb98ca02f4985eeff7a"},
|
||||
{file = "coverage-7.6.7-cp310-cp310-win_amd64.whl", hash = "sha256:987a8e3da7da4eed10a20491cf790589a8e5e07656b6dc22d3814c4d88faf163"},
|
||||
{file = "coverage-7.6.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7e61b0e77ff4dddebb35a0e8bb5a68bf0f8b872407d8d9f0c726b65dfabe2469"},
|
||||
{file = "coverage-7.6.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1a5407a75ca4abc20d6252efeb238377a71ce7bda849c26c7a9bece8680a5d99"},
|
||||
{file = "coverage-7.6.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df002e59f2d29e889c37abd0b9ee0d0e6e38c24f5f55d71ff0e09e3412a340ec"},
|
||||
{file = "coverage-7.6.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:673184b3156cba06154825f25af33baa2671ddae6343f23175764e65a8c4c30b"},
|
||||
{file = "coverage-7.6.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e69ad502f1a2243f739f5bd60565d14a278be58be4c137d90799f2c263e7049a"},
|
||||
{file = "coverage-7.6.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:60dcf7605c50ea72a14490d0756daffef77a5be15ed1b9fea468b1c7bda1bc3b"},
|
||||
{file = "coverage-7.6.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9c2eb378bebb2c8f65befcb5147877fc1c9fbc640fc0aad3add759b5df79d55d"},
|
||||
{file = "coverage-7.6.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c0317288f032221d35fa4cbc35d9f4923ff0dfd176c79c9b356e8ef8ef2dff4"},
|
||||
{file = "coverage-7.6.7-cp311-cp311-win32.whl", hash = "sha256:951aade8297358f3618a6e0660dc74f6b52233c42089d28525749fc8267dccd2"},
|
||||
{file = "coverage-7.6.7-cp311-cp311-win_amd64.whl", hash = "sha256:5e444b8e88339a2a67ce07d41faabb1d60d1004820cee5a2c2b54e2d8e429a0f"},
|
||||
{file = "coverage-7.6.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f07ff574986bc3edb80e2c36391678a271d555f91fd1d332a1e0f4b5ea4b6ea9"},
|
||||
{file = "coverage-7.6.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:49ed5ee4109258973630c1f9d099c7e72c5c36605029f3a91fe9982c6076c82b"},
|
||||
{file = "coverage-7.6.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3e8796434a8106b3ac025fd15417315d7a58ee3e600ad4dbcfddc3f4b14342c"},
|
||||
{file = "coverage-7.6.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3b925300484a3294d1c70f6b2b810d6526f2929de954e5b6be2bf8caa1f12c1"},
|
||||
{file = "coverage-7.6.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c42ec2c522e3ddd683dec5cdce8e62817afb648caedad9da725001fa530d354"},
|
||||
{file = "coverage-7.6.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0266b62cbea568bd5e93a4da364d05de422110cbed5056d69339bd5af5685433"},
|
||||
{file = "coverage-7.6.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e5f2a0f161d126ccc7038f1f3029184dbdf8f018230af17ef6fd6a707a5b881f"},
|
||||
{file = "coverage-7.6.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c132b5a22821f9b143f87446805e13580b67c670a548b96da945a8f6b4f2efbb"},
|
||||
{file = "coverage-7.6.7-cp312-cp312-win32.whl", hash = "sha256:7c07de0d2a110f02af30883cd7dddbe704887617d5c27cf373362667445a4c76"},
|
||||
{file = "coverage-7.6.7-cp312-cp312-win_amd64.whl", hash = "sha256:fd49c01e5057a451c30c9b892948976f5d38f2cbd04dc556a82743ba8e27ed8c"},
|
||||
{file = "coverage-7.6.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:46f21663e358beae6b368429ffadf14ed0a329996248a847a4322fb2e35d64d3"},
|
||||
{file = "coverage-7.6.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:40cca284c7c310d622a1677f105e8507441d1bb7c226f41978ba7c86979609ab"},
|
||||
{file = "coverage-7.6.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77256ad2345c29fe59ae861aa11cfc74579c88d4e8dbf121cbe46b8e32aec808"},
|
||||
{file = "coverage-7.6.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87ea64b9fa52bf395272e54020537990a28078478167ade6c61da7ac04dc14bc"},
|
||||
{file = "coverage-7.6.7-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d608a7808793e3615e54e9267519351c3ae204a6d85764d8337bd95993581a8"},
|
||||
{file = "coverage-7.6.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdd94501d65adc5c24f8a1a0eda110452ba62b3f4aeaba01e021c1ed9cb8f34a"},
|
||||
{file = "coverage-7.6.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:82c809a62e953867cf57e0548c2b8464207f5f3a6ff0e1e961683e79b89f2c55"},
|
||||
{file = "coverage-7.6.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bb684694e99d0b791a43e9fc0fa58efc15ec357ac48d25b619f207c41f2fd384"},
|
||||
{file = "coverage-7.6.7-cp313-cp313-win32.whl", hash = "sha256:963e4a08cbb0af6623e61492c0ec4c0ec5c5cf74db5f6564f98248d27ee57d30"},
|
||||
{file = "coverage-7.6.7-cp313-cp313-win_amd64.whl", hash = "sha256:14045b8bfd5909196a90da145a37f9d335a5d988a83db34e80f41e965fb7cb42"},
|
||||
{file = "coverage-7.6.7-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f2c7a045eef561e9544359a0bf5784b44e55cefc7261a20e730baa9220c83413"},
|
||||
{file = "coverage-7.6.7-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5dd4e4a49d9c72a38d18d641135d2fb0bdf7b726ca60a103836b3d00a1182acd"},
|
||||
{file = "coverage-7.6.7-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c95e0fa3d1547cb6f021ab72f5c23402da2358beec0a8e6d19a368bd7b0fb37"},
|
||||
{file = "coverage-7.6.7-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f63e21ed474edd23f7501f89b53280014436e383a14b9bd77a648366c81dce7b"},
|
||||
{file = "coverage-7.6.7-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ead9b9605c54d15be228687552916c89c9683c215370c4a44f1f217d2adcc34d"},
|
||||
{file = "coverage-7.6.7-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:0573f5cbf39114270842d01872952d301027d2d6e2d84013f30966313cadb529"},
|
||||
{file = "coverage-7.6.7-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:e2c8e3384c12dfa19fa9a52f23eb091a8fad93b5b81a41b14c17c78e23dd1d8b"},
|
||||
{file = "coverage-7.6.7-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:70a56a2ec1869e6e9fa69ef6b76b1a8a7ef709972b9cc473f9ce9d26b5997ce3"},
|
||||
{file = "coverage-7.6.7-cp313-cp313t-win32.whl", hash = "sha256:dbba8210f5067398b2c4d96b4e64d8fb943644d5eb70be0d989067c8ca40c0f8"},
|
||||
{file = "coverage-7.6.7-cp313-cp313t-win_amd64.whl", hash = "sha256:dfd14bcae0c94004baba5184d1c935ae0d1231b8409eb6c103a5fd75e8ecdc56"},
|
||||
{file = "coverage-7.6.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37a15573f988b67f7348916077c6d8ad43adb75e478d0910957394df397d2874"},
|
||||
{file = "coverage-7.6.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b6cce5c76985f81da3769c52203ee94722cd5d5889731cd70d31fee939b74bf0"},
|
||||
{file = "coverage-7.6.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ab9763d291a17b527ac6fd11d1a9a9c358280adb320e9c2672a97af346ac2c"},
|
||||
{file = "coverage-7.6.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6cf96ceaa275f071f1bea3067f8fd43bec184a25a962c754024c973af871e1b7"},
|
||||
{file = "coverage-7.6.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aee9cf6b0134d6f932d219ce253ef0e624f4fa588ee64830fcba193269e4daa3"},
|
||||
{file = "coverage-7.6.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2bc3e45c16564cc72de09e37413262b9f99167803e5e48c6156bccdfb22c8327"},
|
||||
{file = "coverage-7.6.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:623e6965dcf4e28a3debaa6fcf4b99ee06d27218f46d43befe4db1c70841551c"},
|
||||
{file = "coverage-7.6.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:850cfd2d6fc26f8346f422920ac204e1d28814e32e3a58c19c91980fa74d8289"},
|
||||
{file = "coverage-7.6.7-cp39-cp39-win32.whl", hash = "sha256:c296263093f099da4f51b3dff1eff5d4959b527d4f2f419e16508c5da9e15e8c"},
|
||||
{file = "coverage-7.6.7-cp39-cp39-win_amd64.whl", hash = "sha256:90746521206c88bdb305a4bf3342b1b7316ab80f804d40c536fc7d329301ee13"},
|
||||
{file = "coverage-7.6.7-pp39.pp310-none-any.whl", hash = "sha256:0ddcb70b3a3a57581b450571b31cb774f23eb9519c2aaa6176d3a84c9fc57671"},
|
||||
{file = "coverage-7.6.7.tar.gz", hash = "sha256:d79d4826e41441c9a118ff045e4bccb9fdbdcb1d02413e7ea6eb5c87b5439d24"},
|
||||
{file = "coverage-7.6.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:85d9636f72e8991a1706b2b55b06c27545448baf9f6dbf51c4004609aacd7dcb"},
|
||||
{file = "coverage-7.6.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:608a7fd78c67bee8936378299a6cb9f5149bb80238c7a566fc3e6717a4e68710"},
|
||||
{file = "coverage-7.6.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96d636c77af18b5cb664ddf12dab9b15a0cfe9c0bde715da38698c8cea748bfa"},
|
||||
{file = "coverage-7.6.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75cded8a3cff93da9edc31446872d2997e327921d8eed86641efafd350e1df1"},
|
||||
{file = "coverage-7.6.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7b15f589593110ae767ce997775d645b47e5cbbf54fd322f8ebea6277466cec"},
|
||||
{file = "coverage-7.6.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:44349150f6811b44b25574839b39ae35291f6496eb795b7366fef3bd3cf112d3"},
|
||||
{file = "coverage-7.6.9-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d891c136b5b310d0e702e186d70cd16d1119ea8927347045124cb286b29297e5"},
|
||||
{file = "coverage-7.6.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:db1dab894cc139f67822a92910466531de5ea6034ddfd2b11c0d4c6257168073"},
|
||||
{file = "coverage-7.6.9-cp310-cp310-win32.whl", hash = "sha256:41ff7b0da5af71a51b53f501a3bac65fb0ec311ebed1632e58fc6107f03b9198"},
|
||||
{file = "coverage-7.6.9-cp310-cp310-win_amd64.whl", hash = "sha256:35371f8438028fdccfaf3570b31d98e8d9eda8bb1d6ab9473f5a390969e98717"},
|
||||
{file = "coverage-7.6.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:932fc826442132dde42ee52cf66d941f581c685a6313feebed358411238f60f9"},
|
||||
{file = "coverage-7.6.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:085161be5f3b30fd9b3e7b9a8c301f935c8313dcf928a07b116324abea2c1c2c"},
|
||||
{file = "coverage-7.6.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ccc660a77e1c2bf24ddbce969af9447a9474790160cfb23de6be4fa88e3951c7"},
|
||||
{file = "coverage-7.6.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c69e42c892c018cd3c8d90da61d845f50a8243062b19d228189b0224150018a9"},
|
||||
{file = "coverage-7.6.9-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0824a28ec542a0be22f60c6ac36d679e0e262e5353203bea81d44ee81fe9c6d4"},
|
||||
{file = "coverage-7.6.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4401ae5fc52ad8d26d2a5d8a7428b0f0c72431683f8e63e42e70606374c311a1"},
|
||||
{file = "coverage-7.6.9-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98caba4476a6c8d59ec1eb00c7dd862ba9beca34085642d46ed503cc2d440d4b"},
|
||||
{file = "coverage-7.6.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ee5defd1733fd6ec08b168bd4f5387d5b322f45ca9e0e6c817ea6c4cd36313e3"},
|
||||
{file = "coverage-7.6.9-cp311-cp311-win32.whl", hash = "sha256:f2d1ec60d6d256bdf298cb86b78dd715980828f50c46701abc3b0a2b3f8a0dc0"},
|
||||
{file = "coverage-7.6.9-cp311-cp311-win_amd64.whl", hash = "sha256:0d59fd927b1f04de57a2ba0137166d31c1a6dd9e764ad4af552912d70428c92b"},
|
||||
{file = "coverage-7.6.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:99e266ae0b5d15f1ca8d278a668df6f51cc4b854513daab5cae695ed7b721cf8"},
|
||||
{file = "coverage-7.6.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9901d36492009a0a9b94b20e52ebfc8453bf49bb2b27bca2c9706f8b4f5a554a"},
|
||||
{file = "coverage-7.6.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abd3e72dd5b97e3af4246cdada7738ef0e608168de952b837b8dd7e90341f015"},
|
||||
{file = "coverage-7.6.9-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff74026a461eb0660366fb01c650c1d00f833a086b336bdad7ab00cc952072b3"},
|
||||
{file = "coverage-7.6.9-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65dad5a248823a4996724a88eb51d4b31587aa7aa428562dbe459c684e5787ae"},
|
||||
{file = "coverage-7.6.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:22be16571504c9ccea919fcedb459d5ab20d41172056206eb2994e2ff06118a4"},
|
||||
{file = "coverage-7.6.9-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f957943bc718b87144ecaee70762bc2bc3f1a7a53c7b861103546d3a403f0a6"},
|
||||
{file = "coverage-7.6.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0ae1387db4aecb1f485fb70a6c0148c6cdaebb6038f1d40089b1fc84a5db556f"},
|
||||
{file = "coverage-7.6.9-cp312-cp312-win32.whl", hash = "sha256:1a330812d9cc7ac2182586f6d41b4d0fadf9be9049f350e0efb275c8ee8eb692"},
|
||||
{file = "coverage-7.6.9-cp312-cp312-win_amd64.whl", hash = "sha256:b12c6b18269ca471eedd41c1b6a1065b2f7827508edb9a7ed5555e9a56dcfc97"},
|
||||
{file = "coverage-7.6.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:899b8cd4781c400454f2f64f7776a5d87bbd7b3e7f7bda0cb18f857bb1334664"},
|
||||
{file = "coverage-7.6.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:61f70dc68bd36810972e55bbbe83674ea073dd1dcc121040a08cdf3416c5349c"},
|
||||
{file = "coverage-7.6.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a289d23d4c46f1a82d5db4abeb40b9b5be91731ee19a379d15790e53031c014"},
|
||||
{file = "coverage-7.6.9-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e216d8044a356fc0337c7a2a0536d6de07888d7bcda76febcb8adc50bdbbd00"},
|
||||
{file = "coverage-7.6.9-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c026eb44f744acaa2bda7493dad903aa5bf5fc4f2554293a798d5606710055d"},
|
||||
{file = "coverage-7.6.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e77363e8425325384f9d49272c54045bbed2f478e9dd698dbc65dbc37860eb0a"},
|
||||
{file = "coverage-7.6.9-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:777abfab476cf83b5177b84d7486497e034eb9eaea0d746ce0c1268c71652077"},
|
||||
{file = "coverage-7.6.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:447af20e25fdbe16f26e84eb714ba21d98868705cb138252d28bc400381f6ffb"},
|
||||
{file = "coverage-7.6.9-cp313-cp313-win32.whl", hash = "sha256:d872ec5aeb086cbea771c573600d47944eea2dcba8be5f3ee649bfe3cb8dc9ba"},
|
||||
{file = "coverage-7.6.9-cp313-cp313-win_amd64.whl", hash = "sha256:fd1213c86e48dfdc5a0cc676551db467495a95a662d2396ecd58e719191446e1"},
|
||||
{file = "coverage-7.6.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ba9e7484d286cd5a43744e5f47b0b3fb457865baf07bafc6bee91896364e1419"},
|
||||
{file = "coverage-7.6.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e5ea1cf0872ee455c03e5674b5bca5e3e68e159379c1af0903e89f5eba9ccc3a"},
|
||||
{file = "coverage-7.6.9-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d10e07aa2b91835d6abec555ec8b2733347956991901eea6ffac295f83a30e4"},
|
||||
{file = "coverage-7.6.9-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13a9e2d3ee855db3dd6ea1ba5203316a1b1fd8eaeffc37c5b54987e61e4194ae"},
|
||||
{file = "coverage-7.6.9-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c38bf15a40ccf5619fa2fe8f26106c7e8e080d7760aeccb3722664c8656b030"},
|
||||
{file = "coverage-7.6.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d5275455b3e4627c8e7154feaf7ee0743c2e7af82f6e3b561967b1cca755a0be"},
|
||||
{file = "coverage-7.6.9-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8f8770dfc6e2c6a2d4569f411015c8d751c980d17a14b0530da2d7f27ffdd88e"},
|
||||
{file = "coverage-7.6.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8d2dfa71665a29b153a9681edb1c8d9c1ea50dfc2375fb4dac99ea7e21a0bcd9"},
|
||||
{file = "coverage-7.6.9-cp313-cp313t-win32.whl", hash = "sha256:5e6b86b5847a016d0fbd31ffe1001b63355ed309651851295315031ea7eb5a9b"},
|
||||
{file = "coverage-7.6.9-cp313-cp313t-win_amd64.whl", hash = "sha256:97ddc94d46088304772d21b060041c97fc16bdda13c6c7f9d8fcd8d5ae0d8611"},
|
||||
{file = "coverage-7.6.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:adb697c0bd35100dc690de83154627fbab1f4f3c0386df266dded865fc50a902"},
|
||||
{file = "coverage-7.6.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:be57b6d56e49c2739cdf776839a92330e933dd5e5d929966fbbd380c77f060be"},
|
||||
{file = "coverage-7.6.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1592791f8204ae9166de22ba7e6705fa4ebd02936c09436a1bb85aabca3e599"},
|
||||
{file = "coverage-7.6.9-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e12ae8cc979cf83d258acb5e1f1cf2f3f83524d1564a49d20b8bec14b637f08"},
|
||||
{file = "coverage-7.6.9-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb5555cff66c4d3d6213a296b360f9e1a8e323e74e0426b6c10ed7f4d021e464"},
|
||||
{file = "coverage-7.6.9-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b9389a429e0e5142e69d5bf4a435dd688c14478a19bb901735cdf75e57b13845"},
|
||||
{file = "coverage-7.6.9-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:592ac539812e9b46046620341498caf09ca21023c41c893e1eb9dbda00a70cbf"},
|
||||
{file = "coverage-7.6.9-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a27801adef24cc30871da98a105f77995e13a25a505a0161911f6aafbd66e678"},
|
||||
{file = "coverage-7.6.9-cp39-cp39-win32.whl", hash = "sha256:8e3c3e38930cfb729cb8137d7f055e5a473ddaf1217966aa6238c88bd9fd50e6"},
|
||||
{file = "coverage-7.6.9-cp39-cp39-win_amd64.whl", hash = "sha256:e28bf44afa2b187cc9f41749138a64435bf340adfcacb5b2290c070ce99839d4"},
|
||||
{file = "coverage-7.6.9-pp39.pp310-none-any.whl", hash = "sha256:f3ca78518bc6bc92828cd11867b121891d75cae4ea9e908d72030609b996db1b"},
|
||||
{file = "coverage-7.6.9.tar.gz", hash = "sha256:4a8d8977b0c6ef5aeadcb644da9e69ae0dcfe66ec7f368c89c72e058bd71164d"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -585,13 +585,13 @@ test = ["pytest (>=6)"]
|
||||
|
||||
[[package]]
|
||||
name = "fastapi"
|
||||
version = "0.115.5"
|
||||
version = "0.115.6"
|
||||
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "fastapi-0.115.5-py3-none-any.whl", hash = "sha256:596b95adbe1474da47049e802f9a65ab2ffa9c2b07e7efee70eb8a66c9f2f796"},
|
||||
{file = "fastapi-0.115.5.tar.gz", hash = "sha256:0e7a4d0dc0d01c68df21887cce0945e72d3c48b9f4f79dfe7a7d53aa08fbb289"},
|
||||
{file = "fastapi-0.115.6-py3-none-any.whl", hash = "sha256:e9240b29e36fa8f4bb7290316988e90c381e5092e0cbe84e7818cc3713bcf305"},
|
||||
{file = "fastapi-0.115.6.tar.gz", hash = "sha256:9ec46f7addc14ea472958a96aae5b5de65f39721a46aaf5705c480d9a8b76654"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -760,13 +760,13 @@ trio = ["trio (>=0.22.0,<1.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "httpx"
|
||||
version = "0.27.2"
|
||||
version = "0.28.1"
|
||||
description = "The next generation HTTP client."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"},
|
||||
{file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"},
|
||||
{file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"},
|
||||
{file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -774,7 +774,6 @@ anyio = "*"
|
||||
certifi = "*"
|
||||
httpcore = "==1.*"
|
||||
idna = "*"
|
||||
sniffio = "*"
|
||||
|
||||
[package.extras]
|
||||
brotli = ["brotli", "brotlicffi"]
|
||||
@ -785,13 +784,13 @@ zstd = ["zstandard (>=0.18.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "identify"
|
||||
version = "2.6.2"
|
||||
version = "2.6.3"
|
||||
description = "File identification library for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "identify-2.6.2-py2.py3-none-any.whl", hash = "sha256:c097384259f49e372f4ea00a19719d95ae27dd5ff0fd77ad630aa891306b82f3"},
|
||||
{file = "identify-2.6.2.tar.gz", hash = "sha256:fab5c716c24d7a789775228823797296a2994b075fb6080ac83a102772a98cbd"},
|
||||
{file = "identify-2.6.3-py2.py3-none-any.whl", hash = "sha256:9edba65473324c2ea9684b1f944fe3191db3345e50b6d04571d10ed164f8d7bd"},
|
||||
{file = "identify-2.6.3.tar.gz", hash = "sha256:62f5dae9b5fef52c84cc188514e9ea4f3f636b1d8799ab5ebc475471f9e47a02"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@ -985,13 +984,13 @@ test = ["pytest (>=7.4)", "pytest-cov (>=4.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "mako"
|
||||
version = "1.3.6"
|
||||
version = "1.3.8"
|
||||
description = "A super-fast templating language that borrows the best ideas from the existing templating languages."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "Mako-1.3.6-py3-none-any.whl", hash = "sha256:a91198468092a2f1a0de86ca92690fb0cfc43ca90ee17e15d93662b4c04b241a"},
|
||||
{file = "mako-1.3.6.tar.gz", hash = "sha256:9ec3a1583713479fae654f83ed9fa8c9a4c16b7bb0daba0e6bbebff50c0d983d"},
|
||||
{file = "Mako-1.3.8-py3-none-any.whl", hash = "sha256:42f48953c7eb91332040ff567eb7eea69b22e7a4affbc5ba8e845e8f730f6627"},
|
||||
{file = "mako-1.3.8.tar.gz", hash = "sha256:577b97e414580d3e088d47c2dbbe9594aa7a5146ed2875d4dfa9075af2dd3cc8"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -1120,27 +1119,34 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "nh3"
|
||||
version = "0.2.18"
|
||||
version = "0.2.19"
|
||||
description = "Python bindings to the ammonia HTML sanitization library."
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:14c5a72e9fe82aea5fe3072116ad4661af5cf8e8ff8fc5ad3450f123e4925e86"},
|
||||
{file = "nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:7b7c2a3c9eb1a827d42539aa64091640bd275b81e097cd1d8d82ef91ffa2e811"},
|
||||
{file = "nh3-0.2.18-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42c64511469005058cd17cc1537578eac40ae9f7200bedcfd1fc1a05f4f8c200"},
|
||||
{file = "nh3-0.2.18-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0411beb0589eacb6734f28d5497ca2ed379eafab8ad8c84b31bb5c34072b7164"},
|
||||
{file = "nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5f36b271dae35c465ef5e9090e1fdaba4a60a56f0bb0ba03e0932a66f28b9189"},
|
||||
{file = "nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34c03fa78e328c691f982b7c03d4423bdfd7da69cd707fe572f544cf74ac23ad"},
|
||||
{file = "nh3-0.2.18-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19aaba96e0f795bd0a6c56291495ff59364f4300d4a39b29a0abc9cb3774a84b"},
|
||||
{file = "nh3-0.2.18-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de3ceed6e661954871d6cd78b410213bdcb136f79aafe22aa7182e028b8c7307"},
|
||||
{file = "nh3-0.2.18-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6955369e4d9f48f41e3f238a9e60f9410645db7e07435e62c6a9ea6135a4907f"},
|
||||
{file = "nh3-0.2.18-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f0eca9ca8628dbb4e916ae2491d72957fdd35f7a5d326b7032a345f111ac07fe"},
|
||||
{file = "nh3-0.2.18-cp37-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:3a157ab149e591bb638a55c8c6bcb8cdb559c8b12c13a8affaba6cedfe51713a"},
|
||||
{file = "nh3-0.2.18-cp37-abi3-musllinux_1_2_i686.whl", hash = "sha256:c8b3a1cebcba9b3669ed1a84cc65bf005728d2f0bc1ed2a6594a992e817f3a50"},
|
||||
{file = "nh3-0.2.18-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:36c95d4b70530b320b365659bb5034341316e6a9b30f0b25fa9c9eff4c27a204"},
|
||||
{file = "nh3-0.2.18-cp37-abi3-win32.whl", hash = "sha256:a7f1b5b2c15866f2db413a3649a8fe4fd7b428ae58be2c0f6bca5eefd53ca2be"},
|
||||
{file = "nh3-0.2.18-cp37-abi3-win_amd64.whl", hash = "sha256:8ce0f819d2f1933953fca255db2471ad58184a60508f03e6285e5114b6254844"},
|
||||
{file = "nh3-0.2.18.tar.gz", hash = "sha256:94a166927e53972a9698af9542ace4e38b9de50c34352b962f4d9a7d4c927af4"},
|
||||
{file = "nh3-0.2.19-cp313-cp313t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:ec9c8bf86e397cb88c560361f60fdce478b5edb8b93f04ead419b72fbe937ea6"},
|
||||
{file = "nh3-0.2.19-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0adf00e2b2026fa10a42537b60d161e516f206781c7515e4e97e09f72a8c5d0"},
|
||||
{file = "nh3-0.2.19-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3805161c4e12088bd74752ba69630e915bc30fe666034f47217a2f16b16efc37"},
|
||||
{file = "nh3-0.2.19-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e3dedd7858a21312f7675841529941035a2ac91057db13402c8fe907aa19205a"},
|
||||
{file = "nh3-0.2.19-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:0b6820fc64f2ff7ef3e7253a093c946a87865c877b3889149a6d21d322ed8dbd"},
|
||||
{file = "nh3-0.2.19-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:833b3b5f1783ce95834a13030300cea00cbdfd64ea29260d01af9c4821da0aa9"},
|
||||
{file = "nh3-0.2.19-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5d4f5e2189861b352b73acb803b5f4bb409c2f36275d22717e27d4e0c217ae55"},
|
||||
{file = "nh3-0.2.19-cp313-cp313t-win32.whl", hash = "sha256:2b926f179eb4bce72b651bfdf76f8aa05d167b2b72bc2f3657fd319f40232adc"},
|
||||
{file = "nh3-0.2.19-cp313-cp313t-win_amd64.whl", hash = "sha256:ac536a4b5c073fdadd8f5f4889adabe1cbdae55305366fb870723c96ca7f49c3"},
|
||||
{file = "nh3-0.2.19-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:c2e3f0d18cc101132fe10ab7ef5c4f41411297e639e23b64b5e888ccaad63f41"},
|
||||
{file = "nh3-0.2.19-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11270b16c1b012677e3e2dd166c1aa273388776bf99a3e3677179db5097ee16a"},
|
||||
{file = "nh3-0.2.19-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fc483dd8d20f8f8c010783a25a84db3bebeadced92d24d34b40d687f8043ac69"},
|
||||
{file = "nh3-0.2.19-cp38-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d53a4577b6123ca1d7e8483fad3e13cb7eda28913d516bd0a648c1a473aa21a9"},
|
||||
{file = "nh3-0.2.19-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fdb20740d24ab9f2a1341458a00a11205294e97e905de060eeab1ceca020c09c"},
|
||||
{file = "nh3-0.2.19-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d8325d51e47cb5b11f649d55e626d56c76041ba508cd59e0cb1cf687cc7612f1"},
|
||||
{file = "nh3-0.2.19-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8eb7affc590e542fa7981ef508cd1644f62176bcd10d4429890fc629b47f0bc"},
|
||||
{file = "nh3-0.2.19-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2eb021804e9df1761abeb844bb86648d77aa118a663c82f50ea04110d87ed707"},
|
||||
{file = "nh3-0.2.19-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:a7b928862daddb29805a1010a0282f77f4b8b238a37b5f76bc6c0d16d930fd22"},
|
||||
{file = "nh3-0.2.19-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:ed06ed78f6b69d57463b46a04f68f270605301e69d80756a8adf7519002de57d"},
|
||||
{file = "nh3-0.2.19-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:df8eac98fec80bd6f5fd0ae27a65de14f1e1a65a76d8e2237eb695f9cd1121d9"},
|
||||
{file = "nh3-0.2.19-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:00810cd5275f5c3f44b9eb0e521d1a841ee2f8023622de39ffc7d88bd533d8e0"},
|
||||
{file = "nh3-0.2.19-cp38-abi3-win32.whl", hash = "sha256:7e98621856b0a911c21faa5eef8f8ea3e691526c2433f9afc2be713cb6fbdb48"},
|
||||
{file = "nh3-0.2.19-cp38-abi3-win_amd64.whl", hash = "sha256:75c7cafb840f24430b009f7368945cb5ca88b2b54bb384ebfba495f16bc9c121"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1210,66 +1216,66 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "2.1.3"
|
||||
version = "2.2.0"
|
||||
description = "Fundamental package for array computing in Python"
|
||||
optional = false
|
||||
python-versions = ">=3.10"
|
||||
files = [
|
||||
{file = "numpy-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c894b4305373b9c5576d7a12b473702afdf48ce5369c074ba304cc5ad8730dff"},
|
||||
{file = "numpy-2.1.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b47fbb433d3260adcd51eb54f92a2ffbc90a4595f8970ee00e064c644ac788f5"},
|
||||
{file = "numpy-2.1.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:825656d0743699c529c5943554d223c021ff0494ff1442152ce887ef4f7561a1"},
|
||||
{file = "numpy-2.1.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a4825252fcc430a182ac4dee5a505053d262c807f8a924603d411f6718b88fd"},
|
||||
{file = "numpy-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e711e02f49e176a01d0349d82cb5f05ba4db7d5e7e0defd026328e5cfb3226d3"},
|
||||
{file = "numpy-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78574ac2d1a4a02421f25da9559850d59457bac82f2b8d7a44fe83a64f770098"},
|
||||
{file = "numpy-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c7662f0e3673fe4e832fe07b65c50342ea27d989f92c80355658c7f888fcc83c"},
|
||||
{file = "numpy-2.1.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fa2d1337dc61c8dc417fbccf20f6d1e139896a30721b7f1e832b2bb6ef4eb6c4"},
|
||||
{file = "numpy-2.1.3-cp310-cp310-win32.whl", hash = "sha256:72dcc4a35a8515d83e76b58fdf8113a5c969ccd505c8a946759b24e3182d1f23"},
|
||||
{file = "numpy-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:ecc76a9ba2911d8d37ac01de72834d8849e55473457558e12995f4cd53e778e0"},
|
||||
{file = "numpy-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4d1167c53b93f1f5d8a139a742b3c6f4d429b54e74e6b57d0eff40045187b15d"},
|
||||
{file = "numpy-2.1.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c80e4a09b3d95b4e1cac08643f1152fa71a0a821a2d4277334c88d54b2219a41"},
|
||||
{file = "numpy-2.1.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:576a1c1d25e9e02ed7fa5477f30a127fe56debd53b8d2c89d5578f9857d03ca9"},
|
||||
{file = "numpy-2.1.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:973faafebaae4c0aaa1a1ca1ce02434554d67e628b8d805e61f874b84e136b09"},
|
||||
{file = "numpy-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:762479be47a4863e261a840e8e01608d124ee1361e48b96916f38b119cfda04a"},
|
||||
{file = "numpy-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f24b3d1ecc1eebfbf5d6051faa49af40b03be1aaa781ebdadcbc090b4539b"},
|
||||
{file = "numpy-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:17ee83a1f4fef3c94d16dc1802b998668b5419362c8a4f4e8a491de1b41cc3ee"},
|
||||
{file = "numpy-2.1.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15cb89f39fa6d0bdfb600ea24b250e5f1a3df23f901f51c8debaa6a5d122b2f0"},
|
||||
{file = "numpy-2.1.3-cp311-cp311-win32.whl", hash = "sha256:d9beb777a78c331580705326d2367488d5bc473b49a9bc3036c154832520aca9"},
|
||||
{file = "numpy-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:d89dd2b6da69c4fff5e39c28a382199ddedc3a5be5390115608345dec660b9e2"},
|
||||
{file = "numpy-2.1.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f55ba01150f52b1027829b50d70ef1dafd9821ea82905b63936668403c3b471e"},
|
||||
{file = "numpy-2.1.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13138eadd4f4da03074851a698ffa7e405f41a0845a6b1ad135b81596e4e9958"},
|
||||
{file = "numpy-2.1.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:a6b46587b14b888e95e4a24d7b13ae91fa22386c199ee7b418f449032b2fa3b8"},
|
||||
{file = "numpy-2.1.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:0fa14563cc46422e99daef53d725d0c326e99e468a9320a240affffe87852564"},
|
||||
{file = "numpy-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8637dcd2caa676e475503d1f8fdb327bc495554e10838019651b76d17b98e512"},
|
||||
{file = "numpy-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2312b2aa89e1f43ecea6da6ea9a810d06aae08321609d8dc0d0eda6d946a541b"},
|
||||
{file = "numpy-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a38c19106902bb19351b83802531fea19dee18e5b37b36454f27f11ff956f7fc"},
|
||||
{file = "numpy-2.1.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:02135ade8b8a84011cbb67dc44e07c58f28575cf9ecf8ab304e51c05528c19f0"},
|
||||
{file = "numpy-2.1.3-cp312-cp312-win32.whl", hash = "sha256:e6988e90fcf617da2b5c78902fe8e668361b43b4fe26dbf2d7b0f8034d4cafb9"},
|
||||
{file = "numpy-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:0d30c543f02e84e92c4b1f415b7c6b5326cbe45ee7882b6b77db7195fb971e3a"},
|
||||
{file = "numpy-2.1.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96fe52fcdb9345b7cd82ecd34547fca4321f7656d500eca497eb7ea5a926692f"},
|
||||
{file = "numpy-2.1.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f653490b33e9c3a4c1c01d41bc2aef08f9475af51146e4a7710c450cf9761598"},
|
||||
{file = "numpy-2.1.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dc258a761a16daa791081d026f0ed4399b582712e6fc887a95af09df10c5ca57"},
|
||||
{file = "numpy-2.1.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:016d0f6f5e77b0f0d45d77387ffa4bb89816b57c835580c3ce8e099ef830befe"},
|
||||
{file = "numpy-2.1.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c181ba05ce8299c7aa3125c27b9c2167bca4a4445b7ce73d5febc411ca692e43"},
|
||||
{file = "numpy-2.1.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5641516794ca9e5f8a4d17bb45446998c6554704d888f86df9b200e66bdcce56"},
|
||||
{file = "numpy-2.1.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ea4dedd6e394a9c180b33c2c872b92f7ce0f8e7ad93e9585312b0c5a04777a4a"},
|
||||
{file = "numpy-2.1.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0df3635b9c8ef48bd3be5f862cf71b0a4716fa0e702155c45067c6b711ddcef"},
|
||||
{file = "numpy-2.1.3-cp313-cp313-win32.whl", hash = "sha256:50ca6aba6e163363f132b5c101ba078b8cbd3fa92c7865fd7d4d62d9779ac29f"},
|
||||
{file = "numpy-2.1.3-cp313-cp313-win_amd64.whl", hash = "sha256:747641635d3d44bcb380d950679462fae44f54b131be347d5ec2bce47d3df9ed"},
|
||||
{file = "numpy-2.1.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:996bb9399059c5b82f76b53ff8bb686069c05acc94656bb259b1d63d04a9506f"},
|
||||
{file = "numpy-2.1.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:45966d859916ad02b779706bb43b954281db43e185015df6eb3323120188f9e4"},
|
||||
{file = "numpy-2.1.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:baed7e8d7481bfe0874b566850cb0b85243e982388b7b23348c6db2ee2b2ae8e"},
|
||||
{file = "numpy-2.1.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a9f7f672a3388133335589cfca93ed468509cb7b93ba3105fce780d04a6576a0"},
|
||||
{file = "numpy-2.1.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7aac50327da5d208db2eec22eb11e491e3fe13d22653dce51b0f4109101b408"},
|
||||
{file = "numpy-2.1.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4394bc0dbd074b7f9b52024832d16e019decebf86caf909d94f6b3f77a8ee3b6"},
|
||||
{file = "numpy-2.1.3-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:50d18c4358a0a8a53f12a8ba9d772ab2d460321e6a93d6064fc22443d189853f"},
|
||||
{file = "numpy-2.1.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:14e253bd43fc6b37af4921b10f6add6925878a42a0c5fe83daee390bca80bc17"},
|
||||
{file = "numpy-2.1.3-cp313-cp313t-win32.whl", hash = "sha256:08788d27a5fd867a663f6fc753fd7c3ad7e92747efc73c53bca2f19f8bc06f48"},
|
||||
{file = "numpy-2.1.3-cp313-cp313t-win_amd64.whl", hash = "sha256:2564fbdf2b99b3f815f2107c1bbc93e2de8ee655a69c261363a1172a79a257d4"},
|
||||
{file = "numpy-2.1.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4f2015dfe437dfebbfce7c85c7b53d81ba49e71ba7eadbf1df40c915af75979f"},
|
||||
{file = "numpy-2.1.3-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:3522b0dfe983a575e6a9ab3a4a4dfe156c3e428468ff08ce582b9bb6bd1d71d4"},
|
||||
{file = "numpy-2.1.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c006b607a865b07cd981ccb218a04fc86b600411d83d6fc261357f1c0966755d"},
|
||||
{file = "numpy-2.1.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e14e26956e6f1696070788252dcdff11b4aca4c3e8bd166e0df1bb8f315a67cb"},
|
||||
{file = "numpy-2.1.3.tar.gz", hash = "sha256:aa08e04e08aaf974d4458def539dece0d28146d866a39da5639596f4921fd761"},
|
||||
{file = "numpy-2.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1e25507d85da11ff5066269d0bd25d06e0a0f2e908415534f3e603d2a78e4ffa"},
|
||||
{file = "numpy-2.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a62eb442011776e4036af5c8b1a00b706c5bc02dc15eb5344b0c750428c94219"},
|
||||
{file = "numpy-2.2.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:b606b1aaf802e6468c2608c65ff7ece53eae1a6874b3765f69b8ceb20c5fa78e"},
|
||||
{file = "numpy-2.2.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:36b2b43146f646642b425dd2027730f99bac962618ec2052932157e213a040e9"},
|
||||
{file = "numpy-2.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fe8f3583e0607ad4e43a954e35c1748b553bfe9fdac8635c02058023277d1b3"},
|
||||
{file = "numpy-2.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:122fd2fcfafdefc889c64ad99c228d5a1f9692c3a83f56c292618a59aa60ae83"},
|
||||
{file = "numpy-2.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3f2f5cddeaa4424a0a118924b988746db6ffa8565e5829b1841a8a3bd73eb59a"},
|
||||
{file = "numpy-2.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7fe4bb0695fe986a9e4deec3b6857003b4cfe5c5e4aac0b95f6a658c14635e31"},
|
||||
{file = "numpy-2.2.0-cp310-cp310-win32.whl", hash = "sha256:b30042fe92dbd79f1ba7f6898fada10bdaad1847c44f2dff9a16147e00a93661"},
|
||||
{file = "numpy-2.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dc1d6d66f8d37843ed281773c7174f03bf7ad826523f73435deb88ba60d2d4"},
|
||||
{file = "numpy-2.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9874bc2ff574c40ab7a5cbb7464bf9b045d617e36754a7bc93f933d52bd9ffc6"},
|
||||
{file = "numpy-2.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0da8495970f6b101ddd0c38ace92edea30e7e12b9a926b57f5fabb1ecc25bb90"},
|
||||
{file = "numpy-2.2.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0557eebc699c1c34cccdd8c3778c9294e8196df27d713706895edc6f57d29608"},
|
||||
{file = "numpy-2.2.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:3579eaeb5e07f3ded59298ce22b65f877a86ba8e9fe701f5576c99bb17c283da"},
|
||||
{file = "numpy-2.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40deb10198bbaa531509aad0cd2f9fadb26c8b94070831e2208e7df543562b74"},
|
||||
{file = "numpy-2.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2aed8fcf8abc3020d6a9ccb31dbc9e7d7819c56a348cc88fd44be269b37427e"},
|
||||
{file = "numpy-2.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a222d764352c773aa5ebde02dd84dba3279c81c6db2e482d62a3fa54e5ece69b"},
|
||||
{file = "numpy-2.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4e58666988605e251d42c2818c7d3d8991555381be26399303053b58a5bbf30d"},
|
||||
{file = "numpy-2.2.0-cp311-cp311-win32.whl", hash = "sha256:4723a50e1523e1de4fccd1b9a6dcea750c2102461e9a02b2ac55ffeae09a4410"},
|
||||
{file = "numpy-2.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:16757cf28621e43e252c560d25b15f18a2f11da94fea344bf26c599b9cf54b73"},
|
||||
{file = "numpy-2.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cff210198bb4cae3f3c100444c5eaa573a823f05c253e7188e1362a5555235b3"},
|
||||
{file = "numpy-2.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:58b92a5828bd4d9aa0952492b7de803135038de47343b2aa3cc23f3b71a3dc4e"},
|
||||
{file = "numpy-2.2.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:ebe5e59545401fbb1b24da76f006ab19734ae71e703cdb4a8b347e84a0cece67"},
|
||||
{file = "numpy-2.2.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:e2b8cd48a9942ed3f85b95ca4105c45758438c7ed28fff1e4ce3e57c3b589d8e"},
|
||||
{file = "numpy-2.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57fcc997ffc0bef234b8875a54d4058afa92b0b0c4223fc1f62f24b3b5e86038"},
|
||||
{file = "numpy-2.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ad7d11b309bd132d74397fcf2920933c9d1dc865487128f5c03d580f2c3d03"},
|
||||
{file = "numpy-2.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cb24cca1968b21355cc6f3da1a20cd1cebd8a023e3c5b09b432444617949085a"},
|
||||
{file = "numpy-2.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0798b138c291d792f8ea40fe3768610f3c7dd2574389e37c3f26573757c8f7ef"},
|
||||
{file = "numpy-2.2.0-cp312-cp312-win32.whl", hash = "sha256:afe8fb968743d40435c3827632fd36c5fbde633b0423da7692e426529b1759b1"},
|
||||
{file = "numpy-2.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:3a4199f519e57d517ebd48cb76b36c82da0360781c6a0353e64c0cac30ecaad3"},
|
||||
{file = "numpy-2.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f8c8b141ef9699ae777c6278b52c706b653bf15d135d302754f6b2e90eb30367"},
|
||||
{file = "numpy-2.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f0986e917aca18f7a567b812ef7ca9391288e2acb7a4308aa9d265bd724bdae"},
|
||||
{file = "numpy-2.2.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:1c92113619f7b272838b8d6702a7f8ebe5edea0df48166c47929611d0b4dea69"},
|
||||
{file = "numpy-2.2.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5a145e956b374e72ad1dff82779177d4a3c62bc8248f41b80cb5122e68f22d13"},
|
||||
{file = "numpy-2.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18142b497d70a34b01642b9feabb70156311b326fdddd875a9981f34a369b671"},
|
||||
{file = "numpy-2.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7d41d1612c1a82b64697e894b75db6758d4f21c3ec069d841e60ebe54b5b571"},
|
||||
{file = "numpy-2.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a98f6f20465e7618c83252c02041517bd2f7ea29be5378f09667a8f654a5918d"},
|
||||
{file = "numpy-2.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e09d40edfdb4e260cb1567d8ae770ccf3b8b7e9f0d9b5c2a9992696b30ce2742"},
|
||||
{file = "numpy-2.2.0-cp313-cp313-win32.whl", hash = "sha256:3905a5fffcc23e597ee4d9fb3fcd209bd658c352657548db7316e810ca80458e"},
|
||||
{file = "numpy-2.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:a184288538e6ad699cbe6b24859206e38ce5fba28f3bcfa51c90d0502c1582b2"},
|
||||
{file = "numpy-2.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7832f9e8eb00be32f15fdfb9a981d6955ea9adc8574c521d48710171b6c55e95"},
|
||||
{file = "numpy-2.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f0dd071b95bbca244f4cb7f70b77d2ff3aaaba7fa16dc41f58d14854a6204e6c"},
|
||||
{file = "numpy-2.2.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:b0b227dcff8cdc3efbce66d4e50891f04d0a387cce282fe1e66199146a6a8fca"},
|
||||
{file = "numpy-2.2.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6ab153263a7c5ccaf6dfe7e53447b74f77789f28ecb278c3b5d49db7ece10d6d"},
|
||||
{file = "numpy-2.2.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e500aba968a48e9019e42c0c199b7ec0696a97fa69037bea163b55398e390529"},
|
||||
{file = "numpy-2.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:440cfb3db4c5029775803794f8638fbdbf71ec702caf32735f53b008e1eaece3"},
|
||||
{file = "numpy-2.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a55dc7a7f0b6198b07ec0cd445fbb98b05234e8b00c5ac4874a63372ba98d4ab"},
|
||||
{file = "numpy-2.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4bddbaa30d78c86329b26bd6aaaea06b1e47444da99eddac7bf1e2fab717bd72"},
|
||||
{file = "numpy-2.2.0-cp313-cp313t-win32.whl", hash = "sha256:30bf971c12e4365153afb31fc73f441d4da157153f3400b82db32d04de1e4066"},
|
||||
{file = "numpy-2.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:d35717333b39d1b6bb8433fa758a55f1081543de527171543a2b710551d40881"},
|
||||
{file = "numpy-2.2.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e12c6c1ce84628c52d6367863773f7c8c8241be554e8b79686e91a43f1733773"},
|
||||
{file = "numpy-2.2.0-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:b6207dc8fb3c8cb5668e885cef9ec7f70189bec4e276f0ff70d5aa078d32c88e"},
|
||||
{file = "numpy-2.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a50aeff71d0f97b6450d33940c7181b08be1441c6c193e678211bff11aa725e7"},
|
||||
{file = "numpy-2.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:df12a1f99b99f569a7c2ae59aa2d31724e8d835fc7f33e14f4792e3071d11221"},
|
||||
{file = "numpy-2.2.0.tar.gz", hash = "sha256:140dd80ff8981a583a60980be1a655068f8adebf7a45a06a6858c873fcdcd4a0"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1506,13 +1512,13 @@ test = ["covdefaults (>=2.3)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pyte
|
||||
|
||||
[[package]]
|
||||
name = "pkginfo"
|
||||
version = "1.10.0"
|
||||
version = "1.12.0"
|
||||
description = "Query metadata from sdists / bdists / installed packages."
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pkginfo-1.10.0-py3-none-any.whl", hash = "sha256:889a6da2ed7ffc58ab5b900d888ddce90bce912f2d2de1dc1c26f4cb9fe65097"},
|
||||
{file = "pkginfo-1.10.0.tar.gz", hash = "sha256:5df73835398d10db79f8eecd5cd86b1f6d29317589ea70796994d49399af6297"},
|
||||
{file = "pkginfo-1.12.0-py3-none-any.whl", hash = "sha256:dcd589c9be4da8973eceffa247733c144812759aa67eaf4bbf97016a02f39088"},
|
||||
{file = "pkginfo-1.12.0.tar.gz", hash = "sha256:8ad91a0445a036782b9366ef8b8c2c50291f83a553478ba8580c73d3215700cf"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@ -1536,18 +1542,18 @@ type = ["mypy (>=1.11.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "playwright"
|
||||
version = "1.48.0"
|
||||
version = "1.49.1"
|
||||
description = "A high-level API to automate web browsers"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "playwright-1.48.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:082bce2739f1078acc7d0734da8cc0e23eb91b7fae553f3316d733276f09a6b1"},
|
||||
{file = "playwright-1.48.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7da2eb51a19c7f3b523e9faa9d98e7af92e52eb983a099979ea79c9668e3cbf7"},
|
||||
{file = "playwright-1.48.0-py3-none-macosx_11_0_universal2.whl", hash = "sha256:115b988d1da322358b77bc3bf2d3cc90f8c881e691461538e7df91614c4833c9"},
|
||||
{file = "playwright-1.48.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:8dabb80e62f667fe2640a8b694e26a7b884c0b4803f7514a3954fc849126227b"},
|
||||
{file = "playwright-1.48.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ff8303409ebed76bed4c3d655340320b768817d900ba208b394fdd7d7939a5c"},
|
||||
{file = "playwright-1.48.0-py3-none-win32.whl", hash = "sha256:85598c360c590076d4f435525be991246d74a905b654ac19d26eab7ed9b98b2d"},
|
||||
{file = "playwright-1.48.0-py3-none-win_amd64.whl", hash = "sha256:e0e87b0c4dc8fce83c725dd851aec37bc4e882bb225ec8a96bd83cf32d4f1623"},
|
||||
{file = "playwright-1.49.1-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:1041ffb45a0d0bc44d698d3a5aa3ac4b67c9bd03540da43a0b70616ad52592b8"},
|
||||
{file = "playwright-1.49.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9f38ed3d0c1f4e0a6d1c92e73dd9a61f8855133249d6f0cec28648d38a7137be"},
|
||||
{file = "playwright-1.49.1-py3-none-macosx_11_0_universal2.whl", hash = "sha256:3be48c6d26dc819ca0a26567c1ae36a980a0303dcd4249feb6f59e115aaddfb8"},
|
||||
{file = "playwright-1.49.1-py3-none-manylinux1_x86_64.whl", hash = "sha256:753ca90ee31b4b03d165cfd36e477309ebf2b4381953f2a982ff612d85b147d2"},
|
||||
{file = "playwright-1.49.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd9bc8dab37aa25198a01f555f0a2e2c3813fe200fef018ac34dfe86b34994b9"},
|
||||
{file = "playwright-1.49.1-py3-none-win32.whl", hash = "sha256:43b304be67f096058e587dac453ece550eff87b8fbed28de30f4f022cc1745bb"},
|
||||
{file = "playwright-1.49.1-py3-none-win_amd64.whl", hash = "sha256:47b23cb346283278f5b4d1e1990bcb6d6302f80c0aa0ca93dd0601a1400191df"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -1656,13 +1662,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.10.1"
|
||||
version = "2.10.3"
|
||||
description = "Data validation using Python type hints"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pydantic-2.10.1-py3-none-any.whl", hash = "sha256:a8d20db84de64cf4a7d59e899c2caf0fe9d660c7cfc482528e7020d7dd189a7e"},
|
||||
{file = "pydantic-2.10.1.tar.gz", hash = "sha256:a4daca2dc0aa429555e0656d6bf94873a7dc5f54ee42b1f5873d666fb3f35560"},
|
||||
{file = "pydantic-2.10.3-py3-none-any.whl", hash = "sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d"},
|
||||
{file = "pydantic-2.10.3.tar.gz", hash = "sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -1860,13 +1866,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "8.3.3"
|
||||
version = "8.3.4"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"},
|
||||
{file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"},
|
||||
{file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"},
|
||||
{file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -1973,13 +1979,13 @@ dev = ["pre-commit", "pytest-asyncio", "tox"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-playwright"
|
||||
version = "0.5.2"
|
||||
version = "0.6.2"
|
||||
description = "A pytest wrapper with fixtures for Playwright to automate web browsers"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "pytest_playwright-0.5.2-py3-none-any.whl", hash = "sha256:2c5720591364a1cdf66610b972ff8492512bc380953e043c85f705b78b2ed582"},
|
||||
{file = "pytest_playwright-0.5.2.tar.gz", hash = "sha256:c6d603df9e6c50b35f057b0528e11d41c0963283e98c257267117f5ed6ba1924"},
|
||||
{file = "pytest_playwright-0.6.2-py3-none-any.whl", hash = "sha256:0eff73bebe497b0158befed91e2f5fe94cfa17181f8b3acf575beed84e7e9043"},
|
||||
{file = "pytest_playwright-0.6.2.tar.gz", hash = "sha256:ff4054b19aa05df096ac6f74f0572591566aaf0f6d97f6cb9674db8a4d4ed06c"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -2023,13 +2029,13 @@ docs = ["sphinx"]
|
||||
|
||||
[[package]]
|
||||
name = "python-multipart"
|
||||
version = "0.0.17"
|
||||
version = "0.0.19"
|
||||
description = "A streaming multipart parser for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "python_multipart-0.0.17-py3-none-any.whl", hash = "sha256:15dc4f487e0a9476cc1201261188ee0940165cffc94429b6fc565c4d3045cb5d"},
|
||||
{file = "python_multipart-0.0.17.tar.gz", hash = "sha256:41330d831cae6e2f22902704ead2826ea038d0419530eadff3ea80175aec5538"},
|
||||
{file = "python_multipart-0.0.19-py3-none-any.whl", hash = "sha256:f8d5b0b9c618575bf9df01c684ded1d94a338839bdd8223838afacfb4bb2082d"},
|
||||
{file = "python_multipart-0.0.19.tar.gz", hash = "sha256:905502ef39050557b7a6af411f454bc19526529ca46ae6831508438890ce12cc"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2174,13 +2180,13 @@ md = ["cmarkgfm (>=0.8.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "redis"
|
||||
version = "5.2.0"
|
||||
version = "5.2.1"
|
||||
description = "Python client for Redis database and key-value store"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "redis-5.2.0-py3-none-any.whl", hash = "sha256:ae174f2bb3b1bf2b09d54bf3e51fbc1469cf6c10aa03e21141f51969801a7897"},
|
||||
{file = "redis-5.2.0.tar.gz", hash = "sha256:0b1087665a771b1ff2e003aa5bdd354f15a70c9e25d5a7dbf9c722c16528a7b0"},
|
||||
{file = "redis-5.2.1-py3-none-any.whl", hash = "sha256:ee7e1056b9aea0f04c6c2ed59452947f34c4940ee025f5dd83e6a6418b6989e4"},
|
||||
{file = "redis-5.2.1.tar.gz", hash = "sha256:16f2e22dff21d5125e8481515e386711a34cbec50f0e44413dd7d9c060a54e0f"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -2206,13 +2212,13 @@ reflex = ">=0.6.0a"
|
||||
|
||||
[[package]]
|
||||
name = "reflex-hosting-cli"
|
||||
version = "0.1.29"
|
||||
version = "0.1.30"
|
||||
description = "Reflex Hosting CLI"
|
||||
optional = false
|
||||
python-versions = "<4.0,>=3.8"
|
||||
files = [
|
||||
{file = "reflex_hosting_cli-0.1.29-py3-none-any.whl", hash = "sha256:fcbdad829762287f32397cd8a5d46536ab0db396e7fdb8a23c7f9343d7dc8de0"},
|
||||
{file = "reflex_hosting_cli-0.1.29.tar.gz", hash = "sha256:7b421fec6936c26549c8c65c9dda34fc042eaaec79b238dce6b9c020f848563b"},
|
||||
{file = "reflex_hosting_cli-0.1.30-py3-none-any.whl", hash = "sha256:778c98d635003d8668158c22eaa0f7124d2bac92c8a1aabaed710960ca97796e"},
|
||||
{file = "reflex_hosting_cli-0.1.30.tar.gz", hash = "sha256:a0fdc73e595e6b9fd661e1307ae37267fb3815cc457b7f15938ba921c12fc0b6"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -2297,29 +2303,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"]
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.7.4"
|
||||
version = "0.8.2"
|
||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "ruff-0.7.4-py3-none-linux_armv6l.whl", hash = "sha256:a4919925e7684a3f18e18243cd6bea7cfb8e968a6eaa8437971f681b7ec51478"},
|
||||
{file = "ruff-0.7.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfb365c135b830778dda8c04fb7d4280ed0b984e1aec27f574445231e20d6c63"},
|
||||
{file = "ruff-0.7.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:63a569b36bc66fbadec5beaa539dd81e0527cb258b94e29e0531ce41bacc1f20"},
|
||||
{file = "ruff-0.7.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d06218747d361d06fd2fdac734e7fa92df36df93035db3dc2ad7aa9852cb109"},
|
||||
{file = "ruff-0.7.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e0cea28d0944f74ebc33e9f934238f15c758841f9f5edd180b5315c203293452"},
|
||||
{file = "ruff-0.7.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80094ecd4793c68b2571b128f91754d60f692d64bc0d7272ec9197fdd09bf9ea"},
|
||||
{file = "ruff-0.7.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:997512325c6620d1c4c2b15db49ef59543ef9cd0f4aa8065ec2ae5103cedc7e7"},
|
||||
{file = "ruff-0.7.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00b4cf3a6b5fad6d1a66e7574d78956bbd09abfd6c8a997798f01f5da3d46a05"},
|
||||
{file = "ruff-0.7.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7dbdc7d8274e1422722933d1edddfdc65b4336abf0b16dfcb9dedd6e6a517d06"},
|
||||
{file = "ruff-0.7.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e92dfb5f00eaedb1501b2f906ccabfd67b2355bdf117fea9719fc99ac2145bc"},
|
||||
{file = "ruff-0.7.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3bd726099f277d735dc38900b6a8d6cf070f80828877941983a57bca1cd92172"},
|
||||
{file = "ruff-0.7.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2e32829c429dd081ee5ba39aef436603e5b22335c3d3fff013cd585806a6486a"},
|
||||
{file = "ruff-0.7.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:662a63b4971807623f6f90c1fb664613f67cc182dc4d991471c23c541fee62dd"},
|
||||
{file = "ruff-0.7.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:876f5e09eaae3eb76814c1d3b68879891d6fde4824c015d48e7a7da4cf066a3a"},
|
||||
{file = "ruff-0.7.4-py3-none-win32.whl", hash = "sha256:75c53f54904be42dd52a548728a5b572344b50d9b2873d13a3f8c5e3b91f5cac"},
|
||||
{file = "ruff-0.7.4-py3-none-win_amd64.whl", hash = "sha256:745775c7b39f914238ed1f1b0bebed0b9155a17cd8bc0b08d3c87e4703b990d6"},
|
||||
{file = "ruff-0.7.4-py3-none-win_arm64.whl", hash = "sha256:11bff065102c3ae9d3ea4dc9ecdfe5a5171349cdd0787c1fc64761212fc9cf1f"},
|
||||
{file = "ruff-0.7.4.tar.gz", hash = "sha256:cd12e35031f5af6b9b93715d8c4f40360070b2041f81273d0527683d5708fce2"},
|
||||
{file = "ruff-0.8.2-py3-none-linux_armv6l.whl", hash = "sha256:c49ab4da37e7c457105aadfd2725e24305ff9bc908487a9bf8d548c6dad8bb3d"},
|
||||
{file = "ruff-0.8.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ec016beb69ac16be416c435828be702ee694c0d722505f9c1f35e1b9c0cc1bf5"},
|
||||
{file = "ruff-0.8.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f05cdf8d050b30e2ba55c9b09330b51f9f97d36d4673213679b965d25a785f3c"},
|
||||
{file = "ruff-0.8.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60f578c11feb1d3d257b2fb043ddb47501ab4816e7e221fbb0077f0d5d4e7b6f"},
|
||||
{file = "ruff-0.8.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cbd5cf9b0ae8f30eebc7b360171bd50f59ab29d39f06a670b3e4501a36ba5897"},
|
||||
{file = "ruff-0.8.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b402ddee3d777683de60ff76da801fa7e5e8a71038f57ee53e903afbcefdaa58"},
|
||||
{file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:705832cd7d85605cb7858d8a13d75993c8f3ef1397b0831289109e953d833d29"},
|
||||
{file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:32096b41aaf7a5cc095fa45b4167b890e4c8d3fd217603f3634c92a541de7248"},
|
||||
{file = "ruff-0.8.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e769083da9439508833cfc7c23e351e1809e67f47c50248250ce1ac52c21fb93"},
|
||||
{file = "ruff-0.8.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fe716592ae8a376c2673fdfc1f5c0c193a6d0411f90a496863c99cd9e2ae25d"},
|
||||
{file = "ruff-0.8.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:81c148825277e737493242b44c5388a300584d73d5774defa9245aaef55448b0"},
|
||||
{file = "ruff-0.8.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d261d7850c8367704874847d95febc698a950bf061c9475d4a8b7689adc4f7fa"},
|
||||
{file = "ruff-0.8.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1ca4e3a87496dc07d2427b7dd7ffa88a1e597c28dad65ae6433ecb9f2e4f022f"},
|
||||
{file = "ruff-0.8.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:729850feed82ef2440aa27946ab39c18cb4a8889c1128a6d589ffa028ddcfc22"},
|
||||
{file = "ruff-0.8.2-py3-none-win32.whl", hash = "sha256:ac42caaa0411d6a7d9594363294416e0e48fc1279e1b0e948391695db2b3d5b1"},
|
||||
{file = "ruff-0.8.2-py3-none-win_amd64.whl", hash = "sha256:2aae99ec70abf43372612a838d97bfe77d45146254568d94926e8ed5bbb409ea"},
|
||||
{file = "ruff-0.8.2-py3-none-win_arm64.whl", hash = "sha256:fb88e2a506b70cfbc2de6fae6681c4f944f7dd5f2fe87233a7233d888bad73e8"},
|
||||
{file = "ruff-0.8.2.tar.gz", hash = "sha256:b84f4f414dda8ac7f75075c1fa0b905ac0ff25361f42e6d5da681a465e0f78e5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2339,13 +2345,13 @@ jeepney = ">=0.6"
|
||||
|
||||
[[package]]
|
||||
name = "selenium"
|
||||
version = "4.26.1"
|
||||
version = "4.27.1"
|
||||
description = "Official Python bindings for Selenium WebDriver"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "selenium-4.26.1-py3-none-any.whl", hash = "sha256:1db3f3a0cd5bb07624fa8a3905a6fdde1595a42185a0617077c361dc53d104fb"},
|
||||
{file = "selenium-4.26.1.tar.gz", hash = "sha256:7640f3f08ae7f4e450f895678e8a10a55eb4e4ca18311ed675ecc4684b96b683"},
|
||||
{file = "selenium-4.27.1-py3-none-any.whl", hash = "sha256:b89b1f62b5cfe8025868556fe82360d6b649d464f75d2655cb966c8f8447ea18"},
|
||||
{file = "selenium-4.27.1.tar.gz", hash = "sha256:5296c425a75ff1b44d0d5199042b36a6d1ef76c04fb775b97b40be739a9caae2"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -2407,13 +2413,13 @@ docs = ["sphinx"]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
version = "1.17.0"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||
files = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||
{file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"},
|
||||
{file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2642,13 +2648,43 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.1.0"
|
||||
version = "2.2.1"
|
||||
description = "A lil' TOML parser"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391"},
|
||||
{file = "tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"},
|
||||
{file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"},
|
||||
{file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2700,19 +2736,20 @@ wsproto = ">=0.14"
|
||||
|
||||
[[package]]
|
||||
name = "twine"
|
||||
version = "5.1.1"
|
||||
version = "6.0.1"
|
||||
description = "Collection of utilities for publishing packages on PyPI"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "twine-5.1.1-py3-none-any.whl", hash = "sha256:215dbe7b4b94c2c50a7315c0275d2258399280fbb7d04182c7e55e24b5f93997"},
|
||||
{file = "twine-5.1.1.tar.gz", hash = "sha256:9aa0825139c02b3434d913545c7b847a21c835e11597f5255842d457da2322db"},
|
||||
{file = "twine-6.0.1-py3-none-any.whl", hash = "sha256:9c6025b203b51521d53e200f4a08b116dee7500a38591668c6a6033117bdc218"},
|
||||
{file = "twine-6.0.1.tar.gz", hash = "sha256:36158b09df5406e1c9c1fb8edb24fc2be387709443e7376689b938531582ee27"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
importlib-metadata = ">=3.6"
|
||||
keyring = ">=15.1"
|
||||
pkginfo = ">=1.8.1,<1.11"
|
||||
importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""}
|
||||
keyring = {version = ">=15.1", markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\""}
|
||||
packaging = "*"
|
||||
pkginfo = ">=1.8.1"
|
||||
readme-renderer = ">=35.0"
|
||||
requests = ">=2.20"
|
||||
requests-toolbelt = ">=0.8.0,<0.9.0 || >0.9.0"
|
||||
@ -2720,6 +2757,9 @@ rfc3986 = ">=1.4.0"
|
||||
rich = ">=12.0.0"
|
||||
urllib3 = ">=1.26.0"
|
||||
|
||||
[package.extras]
|
||||
keyring = ["keyring (>=15.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "typer"
|
||||
version = "0.15.1"
|
||||
@ -2800,13 +2840,13 @@ standard = ["colorama (>=0.4)", "httptools (>=0.6.3)", "python-dotenv (>=0.13)",
|
||||
|
||||
[[package]]
|
||||
name = "virtualenv"
|
||||
version = "20.27.1"
|
||||
version = "20.28.0"
|
||||
description = "Virtual Python Environment builder"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"},
|
||||
{file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"},
|
||||
{file = "virtualenv-20.28.0-py3-none-any.whl", hash = "sha256:23eae1b4516ecd610481eda647f3a7c09aea295055337331bb4e6892ecce47b0"},
|
||||
{file = "virtualenv-20.28.0.tar.gz", hash = "sha256:2c9c3262bb8e7b87ea801d715fae4495e6032450c71d2309be9550e7364049aa"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -2914,13 +2954,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "wheel"
|
||||
version = "0.45.0"
|
||||
version = "0.45.1"
|
||||
description = "A built-package format for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "wheel-0.45.0-py3-none-any.whl", hash = "sha256:52f0baa5e6522155090a09c6bd95718cc46956d1b51d537ea5454249edb671c7"},
|
||||
{file = "wheel-0.45.0.tar.gz", hash = "sha256:a57353941a3183b3d5365346b567a260a0602a0f8a635926a7dede41b94c674a"},
|
||||
{file = "wheel-0.45.1-py3-none-any.whl", hash = "sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248"},
|
||||
{file = "wheel-0.45.1.tar.gz", hash = "sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@ -2928,81 +2968,76 @@ test = ["pytest (>=6.0.0)", "setuptools (>=65)"]
|
||||
|
||||
[[package]]
|
||||
name = "wrapt"
|
||||
version = "1.16.0"
|
||||
version = "1.17.0"
|
||||
description = "Module for decorators, wrappers and monkey patching."
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"},
|
||||
{file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"},
|
||||
{file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"},
|
||||
{file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"},
|
||||
{file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"},
|
||||
{file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"},
|
||||
{file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"},
|
||||
{file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"},
|
||||
{file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"},
|
||||
{file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"},
|
||||
{file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"},
|
||||
{file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"},
|
||||
{file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"},
|
||||
{file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"},
|
||||
{file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"},
|
||||
{file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"},
|
||||
{file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"},
|
||||
{file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"},
|
||||
{file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"},
|
||||
{file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"},
|
||||
{file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"},
|
||||
{file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"},
|
||||
{file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"},
|
||||
{file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"},
|
||||
{file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"},
|
||||
{file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"},
|
||||
{file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"},
|
||||
{file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"},
|
||||
{file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"},
|
||||
{file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"},
|
||||
{file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"},
|
||||
{file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"},
|
||||
{file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"},
|
||||
{file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"},
|
||||
{file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"},
|
||||
{file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"},
|
||||
{file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"},
|
||||
{file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"},
|
||||
{file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"},
|
||||
{file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"},
|
||||
{file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"},
|
||||
{file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"},
|
||||
{file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"},
|
||||
{file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"},
|
||||
{file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"},
|
||||
{file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"},
|
||||
{file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"},
|
||||
{file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"},
|
||||
{file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"},
|
||||
{file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"},
|
||||
{file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"},
|
||||
{file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"},
|
||||
{file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"},
|
||||
{file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"},
|
||||
{file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"},
|
||||
{file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"},
|
||||
{file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"},
|
||||
{file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"},
|
||||
{file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"},
|
||||
{file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"},
|
||||
{file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"},
|
||||
{file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"},
|
||||
{file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"},
|
||||
{file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"},
|
||||
{file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"},
|
||||
{file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"},
|
||||
{file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"},
|
||||
{file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"},
|
||||
{file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"},
|
||||
{file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"},
|
||||
{file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"},
|
||||
{file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"},
|
||||
{file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"},
|
||||
{file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"},
|
||||
{file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"},
|
||||
{file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"},
|
||||
{file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"},
|
||||
{file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"},
|
||||
{file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"},
|
||||
{file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"},
|
||||
{file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"},
|
||||
{file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"},
|
||||
{file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"},
|
||||
{file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"},
|
||||
{file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"},
|
||||
{file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"},
|
||||
{file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"},
|
||||
{file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"},
|
||||
{file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"},
|
||||
{file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"},
|
||||
{file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"},
|
||||
{file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"},
|
||||
{file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"},
|
||||
{file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"},
|
||||
{file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"},
|
||||
{file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"},
|
||||
{file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"},
|
||||
{file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"},
|
||||
{file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"},
|
||||
{file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"},
|
||||
{file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"},
|
||||
{file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"},
|
||||
{file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"},
|
||||
{file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"},
|
||||
{file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"},
|
||||
{file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"},
|
||||
{file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"},
|
||||
{file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"},
|
||||
{file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"},
|
||||
{file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"},
|
||||
{file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"},
|
||||
{file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"},
|
||||
{file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"},
|
||||
{file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"},
|
||||
{file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"},
|
||||
{file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"},
|
||||
{file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"},
|
||||
{file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3041,4 +3076,4 @@ type = ["pytest-mypy"]
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "3810e99ff4d09952e62d88b2c26651a0d8e0ffe4007bc3274c2fb83b68243951"
|
||||
content-hash = "d62cd1897d8f73e9aad9e907beb82be509dc5e33d8f37b36ebf26ad1f3075a9f"
|
||||
|
@ -55,7 +55,7 @@ wheel = ">=0.42.0,<1.0"
|
||||
build = ">=1.0.3,<2.0"
|
||||
setuptools = ">=75.0"
|
||||
httpx = ">=0.25.1,<1.0"
|
||||
twine = ">=4.0.0,<6.0"
|
||||
twine = ">=4.0.0,<7.0"
|
||||
tomlkit = ">=0.12.4,<1.0"
|
||||
lazy_loader = ">=0.4"
|
||||
reflex-chakra = ">=0.6.0"
|
||||
@ -70,7 +70,7 @@ dill = ">=0.3.8"
|
||||
toml = ">=0.10.2,<1.0"
|
||||
pytest-asyncio = ">=0.24.0"
|
||||
pytest-cov = ">=4.0.0,<7.0"
|
||||
ruff = "0.7.4"
|
||||
ruff = "0.8.2"
|
||||
pandas = ">=2.1.1,<3.0"
|
||||
pillow = ">=10.0.0,<12.0"
|
||||
plotly = ">=5.13.0,<6.0"
|
||||
@ -93,8 +93,8 @@ build-backend = "poetry.core.masonry.api"
|
||||
[tool.ruff]
|
||||
target-version = "py39"
|
||||
lint.isort.split-on-trailing-comma = false
|
||||
lint.select = ["B", "D", "E", "F", "I", "SIM", "W"]
|
||||
lint.ignore = ["B008", "D205", "E501", "F403", "SIM115"]
|
||||
lint.select = ["B", "D", "E", "F", "I", "SIM", "W", "RUF", "FURB", "ERA"]
|
||||
lint.ignore = ["B008", "D205", "E501", "F403", "SIM115", "RUF006", "RUF012"]
|
||||
lint.pydocstyle.convention = "google"
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
|
@ -300,7 +300,7 @@ export const applyEvent = async (event, socket) => {
|
||||
if (socket) {
|
||||
socket.emit(
|
||||
"event",
|
||||
JSON.stringify(event, (k, v) => (v === undefined ? null : v))
|
||||
event,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
@ -407,6 +407,8 @@ export const connect = async (
|
||||
transports: transports,
|
||||
autoUnref: false,
|
||||
});
|
||||
// Ensure undefined fields in events are sent as null instead of removed
|
||||
socket.current.io.encoder.replacer = (k, v) => (v === undefined ? null : v)
|
||||
|
||||
function checkVisibility() {
|
||||
if (document.visibilityState === "visible") {
|
||||
@ -443,8 +445,7 @@ export const connect = async (
|
||||
});
|
||||
|
||||
// On each received message, queue the updates and events.
|
||||
socket.current.on("event", async (message) => {
|
||||
const update = JSON5.parse(message);
|
||||
socket.current.on("event", async (update) => {
|
||||
for (const substate in update.delta) {
|
||||
dispatch[substate](update.delta[substate]);
|
||||
}
|
||||
@ -456,7 +457,7 @@ export const connect = async (
|
||||
});
|
||||
socket.current.on("reload", async (event) => {
|
||||
event_processing = false;
|
||||
queueEvents([...initialEvents(), JSON5.parse(event)], socket);
|
||||
queueEvents([...initialEvents(), event], socket);
|
||||
});
|
||||
|
||||
document.addEventListener("visibilitychange", checkVisibility);
|
||||
@ -497,7 +498,9 @@ export const uploadFiles = async (
|
||||
// Whenever called, responseText will contain the entire response so far.
|
||||
const chunks = progressEvent.event.target.responseText.trim().split("\n");
|
||||
// So only process _new_ chunks beyond resp_idx.
|
||||
chunks.slice(resp_idx).map((chunk) => {
|
||||
chunks.slice(resp_idx).map((chunk_json) => {
|
||||
try {
|
||||
const chunk = JSON5.parse(chunk_json);
|
||||
event_callbacks.map((f, ix) => {
|
||||
f(chunk)
|
||||
.then(() => {
|
||||
@ -509,11 +512,17 @@ export const uploadFiles = async (
|
||||
.catch((e) => {
|
||||
if (progressEvent.progress === 1) {
|
||||
// Chunk may be incomplete, so only report errors when full response is available.
|
||||
console.log("Error parsing chunk", chunk, e);
|
||||
console.log("Error processing chunk", chunk, e);
|
||||
}
|
||||
return;
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
if (progressEvent.progress === 1) {
|
||||
console.log("Error parsing chunk", chunk_json, e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@ -799,7 +808,7 @@ export const useEventLoop = (
|
||||
connect(
|
||||
socket,
|
||||
dispatch,
|
||||
["websocket", "polling"],
|
||||
["websocket"],
|
||||
setConnectErrors,
|
||||
client_storage
|
||||
);
|
||||
|
@ -331,7 +331,7 @@ _MAPPING: dict = {
|
||||
"SessionStorage",
|
||||
],
|
||||
"middleware": ["middleware", "Middleware"],
|
||||
"model": ["session", "Model"],
|
||||
"model": ["asession", "session", "Model"],
|
||||
"state": [
|
||||
"var",
|
||||
"ComponentState",
|
||||
|
@ -186,6 +186,7 @@ from .istate.wrappers import get_state as get_state
|
||||
from .middleware import Middleware as Middleware
|
||||
from .middleware import middleware as middleware
|
||||
from .model import Model as Model
|
||||
from .model import asession as asession
|
||||
from .model import session as session
|
||||
from .page import page as page
|
||||
from .state import ComponentState as ComponentState
|
||||
|
@ -17,6 +17,7 @@ import sys
|
||||
import traceback
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
@ -363,6 +364,11 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
max_http_buffer_size=constants.POLLING_MAX_HTTP_BUFFER_SIZE,
|
||||
ping_interval=constants.Ping.INTERVAL,
|
||||
ping_timeout=constants.Ping.TIMEOUT,
|
||||
json=SimpleNamespace(
|
||||
dumps=staticmethod(format.json_dumps),
|
||||
loads=staticmethod(json.loads),
|
||||
),
|
||||
transports=["websocket"],
|
||||
)
|
||||
elif getattr(self.sio, "async_mode", "") != "asgi":
|
||||
raise RuntimeError(
|
||||
@ -467,7 +473,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
|
||||
def add_page(
|
||||
self,
|
||||
component: Component | ComponentCallable,
|
||||
component: Component | ComponentCallable | None = None,
|
||||
route: str | None = None,
|
||||
title: str | Var | None = None,
|
||||
description: str | Var | None = None,
|
||||
@ -490,17 +496,33 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
meta: The metadata of the page.
|
||||
|
||||
Raises:
|
||||
ValueError: When the specified route name already exists.
|
||||
PageValueError: When the component is not set for a non-404 page.
|
||||
RouteValueError: When the specified route name already exists.
|
||||
"""
|
||||
# If the route is not set, get it from the callable.
|
||||
if route is None:
|
||||
if not isinstance(component, Callable):
|
||||
raise ValueError("Route must be set if component is not a callable.")
|
||||
raise exceptions.RouteValueError(
|
||||
"Route must be set if component is not a callable."
|
||||
)
|
||||
# Format the route.
|
||||
route = format.format_route(component.__name__)
|
||||
else:
|
||||
route = format.format_route(route, format_case=False)
|
||||
|
||||
if route == constants.Page404.SLUG:
|
||||
if component is None:
|
||||
component = Default404Page.create()
|
||||
component = wait_for_client_redirect(self._generate_component(component))
|
||||
title = title or constants.Page404.TITLE
|
||||
description = description or constants.Page404.DESCRIPTION
|
||||
image = image or constants.Page404.IMAGE
|
||||
else:
|
||||
if component is None:
|
||||
raise exceptions.PageValueError(
|
||||
"Component must be set for a non-404 page."
|
||||
)
|
||||
|
||||
# Check if the route given is valid
|
||||
verify_route_validity(route)
|
||||
|
||||
@ -516,7 +538,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
if route == constants.PageNames.INDEX_ROUTE
|
||||
else f"`{route}`"
|
||||
)
|
||||
raise ValueError(
|
||||
raise exceptions.RouteValueError(
|
||||
f"Duplicate page route {route_name} already exists. Make sure you do not have two"
|
||||
f" pages with the same route"
|
||||
)
|
||||
@ -633,10 +655,14 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
on_load: The event handler(s) that will be called each time the page load.
|
||||
meta: The metadata of the page.
|
||||
"""
|
||||
if component is None:
|
||||
component = Default404Page.create()
|
||||
console.deprecate(
|
||||
feature_name="App.add_custom_404_page",
|
||||
reason=f"Use app.add_page(component, route='/{constants.Page404.SLUG}') instead.",
|
||||
deprecation_version="0.6.7",
|
||||
removal_version="0.8.0",
|
||||
)
|
||||
self.add_page(
|
||||
component=wait_for_client_redirect(self._generate_component(component)),
|
||||
component=component,
|
||||
route=constants.Page404.SLUG,
|
||||
title=title or constants.Page404.TITLE,
|
||||
image=image or constants.Page404.IMAGE,
|
||||
@ -837,7 +863,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
|
||||
# Render a default 404 page if the user didn't supply one
|
||||
if constants.Page404.SLUG not in self.unevaluated_pages:
|
||||
self.add_custom_404_page()
|
||||
self.add_page(route=constants.Page404.SLUG)
|
||||
|
||||
# Fix up the style.
|
||||
self.style = evaluate_style_namespaces(self.style)
|
||||
@ -947,12 +973,12 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
is not None
|
||||
):
|
||||
executor = concurrent.futures.ProcessPoolExecutor(
|
||||
max_workers=number_of_processes,
|
||||
max_workers=number_of_processes or None,
|
||||
mp_context=multiprocessing.get_context("fork"),
|
||||
)
|
||||
else:
|
||||
executor = concurrent.futures.ThreadPoolExecutor(
|
||||
max_workers=environment.REFLEX_COMPILE_THREADS.get()
|
||||
max_workers=environment.REFLEX_COMPILE_THREADS.get() or None
|
||||
)
|
||||
|
||||
for route, component in zip(self.pages, page_components):
|
||||
@ -965,7 +991,6 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
|
||||
def _submit_work(fn, *args, **kwargs):
|
||||
f = executor.submit(fn, *args, **kwargs)
|
||||
# f = executor.apipe(fn, *args, **kwargs)
|
||||
result_futures.append(f)
|
||||
|
||||
# Compile the pre-compiled pages.
|
||||
@ -1157,7 +1182,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
if hasattr(handler_fn, "__name__"):
|
||||
_fn_name = handler_fn.__name__
|
||||
else:
|
||||
_fn_name = handler_fn.__class__.__name__
|
||||
_fn_name = type(handler_fn).__name__
|
||||
|
||||
if isinstance(handler_fn, functools.partial):
|
||||
raise ValueError(
|
||||
@ -1523,7 +1548,7 @@ class EventNamespace(AsyncNamespace):
|
||||
"""
|
||||
# Creating a task prevents the update from being blocked behind other coroutines.
|
||||
await asyncio.create_task(
|
||||
self.emit(str(constants.SocketEvent.EVENT), update.json(), to=sid)
|
||||
self.emit(str(constants.SocketEvent.EVENT), update, to=sid)
|
||||
)
|
||||
|
||||
async def on_event(self, sid, data):
|
||||
@ -1536,7 +1561,7 @@ class EventNamespace(AsyncNamespace):
|
||||
sid: The Socket.IO session id.
|
||||
data: The event data.
|
||||
"""
|
||||
fields = json.loads(data)
|
||||
fields = data
|
||||
# Get the event.
|
||||
event = Event(
|
||||
**{k: v for k, v in fields.items() if k not in ("handler", "event_actions")}
|
||||
|
@ -5,7 +5,7 @@ from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from reflex import constants
|
||||
from reflex.utils.exec import is_backend_only
|
||||
from reflex.config import EnvironmentVariables
|
||||
|
||||
|
||||
def asset(
|
||||
@ -52,7 +52,7 @@ def asset(
|
||||
The relative URL to the asset.
|
||||
"""
|
||||
assets = constants.Dirs.APP_ASSETS
|
||||
backend_only = is_backend_only()
|
||||
backend_only = EnvironmentVariables.REFLEX_BACKEND_ONLY.get()
|
||||
|
||||
# Local asset handling
|
||||
if not shared:
|
||||
|
@ -103,8 +103,8 @@ class Bare(Component):
|
||||
def _render(self) -> Tag:
|
||||
if isinstance(self.contents, Var):
|
||||
if isinstance(self.contents, (BooleanVar, ObjectVar)):
|
||||
return Tagless(contents=f"{{{str(self.contents.to_string())}}}")
|
||||
return Tagless(contents=f"{{{str(self.contents)}}}")
|
||||
return Tagless(contents=f"{{{self.contents.to_string()!s}}}")
|
||||
return Tagless(contents=f"{{{self.contents!s}}}")
|
||||
return Tagless(contents=str(self.contents))
|
||||
|
||||
def _get_vars(self, include_children: bool = False) -> Iterator[Var]:
|
||||
|
@ -161,7 +161,7 @@ class ComponentNamespace(SimpleNamespace):
|
||||
Returns:
|
||||
The hash of the namespace.
|
||||
"""
|
||||
return hash(self.__class__.__name__)
|
||||
return hash(type(self).__name__)
|
||||
|
||||
|
||||
def evaluate_style_namespaces(style: ComponentStyle) -> dict:
|
||||
@ -583,7 +583,7 @@ class Component(BaseComponent, ABC):
|
||||
return self._create_event_chain(args_spec, value.guess_type(), key=key)
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Invalid event chain: {str(value)} of type {value._var_type}"
|
||||
f"Invalid event chain: {value!s} of type {value._var_type}"
|
||||
)
|
||||
elif isinstance(value, EventChain):
|
||||
# Trust that the caller knows what they're doing passing an EventChain directly
|
||||
@ -653,7 +653,6 @@ class Component(BaseComponent, ABC):
|
||||
|
||||
Returns:
|
||||
The event triggers.
|
||||
|
||||
"""
|
||||
default_triggers: Dict[str, types.ArgsSpec | Sequence[types.ArgsSpec]] = {
|
||||
EventTriggers.ON_FOCUS: no_args_event_spec,
|
||||
@ -1111,7 +1110,7 @@ class Component(BaseComponent, ABC):
|
||||
vars.append(prop_var)
|
||||
|
||||
# Style keeps track of its own VarData instance, so embed in a temp Var that is yielded.
|
||||
if isinstance(self.style, dict) and self.style or isinstance(self.style, Var):
|
||||
if (isinstance(self.style, dict) and self.style) or isinstance(self.style, Var):
|
||||
vars.append(
|
||||
Var(
|
||||
_js_expr="style",
|
||||
@ -1466,7 +1465,9 @@ class Component(BaseComponent, ABC):
|
||||
"""
|
||||
ref = self.get_ref()
|
||||
if ref is not None:
|
||||
return f"const {ref} = useRef(null); {str(Var(_js_expr=ref)._as_ref())} = {ref};"
|
||||
return (
|
||||
f"const {ref} = useRef(null); {Var(_js_expr=ref)._as_ref()!s} = {ref};"
|
||||
)
|
||||
|
||||
def _get_vars_hooks(self) -> dict[str, None]:
|
||||
"""Get the hooks required by vars referenced in this component.
|
||||
@ -2563,7 +2564,7 @@ class LiteralComponentVar(CachedVarOperation, LiteralVar, ComponentVar):
|
||||
Returns:
|
||||
The hash of the var.
|
||||
"""
|
||||
return hash((self.__class__.__name__, self._js_expr))
|
||||
return hash((type(self).__name__, self._js_expr))
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
|
@ -109,7 +109,7 @@ class ConnectionToaster(Toaster):
|
||||
)
|
||||
|
||||
individual_hooks = [
|
||||
f"const toast_props = {str(LiteralVar.create(props))};",
|
||||
f"const toast_props = {LiteralVar.create(props)!s};",
|
||||
"const [userDismissed, setUserDismissed] = useState(false);",
|
||||
FunctionStringVar(
|
||||
"useEffect",
|
||||
@ -124,7 +124,7 @@ class ConnectionToaster(Toaster):
|
||||
Var(
|
||||
_js_expr=f"""
|
||||
() => {{
|
||||
if ({str(has_too_many_connection_errors)}) {{
|
||||
if ({has_too_many_connection_errors!s}) {{
|
||||
if (!userDismissed) {{
|
||||
toast.error(
|
||||
`Cannot connect to server: ${{{connection_error}}}.`,
|
||||
|
@ -24,7 +24,7 @@ class ClientSideRouting(Component):
|
||||
library = "$/utils/client_side_routing"
|
||||
tag = "useClientSideRouting"
|
||||
|
||||
def add_hooks(self) -> list[str]:
|
||||
def add_hooks(self) -> list[str | Var]:
|
||||
"""Get the hooks to render.
|
||||
|
||||
Returns:
|
||||
@ -66,4 +66,4 @@ class Default404Page(Component):
|
||||
tag = "Error"
|
||||
is_default = True
|
||||
|
||||
status_code: Var[int] = 404 # type: ignore
|
||||
status_code: Var[int] = Var.create(404)
|
||||
|
@ -13,7 +13,7 @@ from reflex.vars.base import Var
|
||||
route_not_found: Var
|
||||
|
||||
class ClientSideRouting(Component):
|
||||
def add_hooks(self) -> list[str]: ...
|
||||
def add_hooks(self) -> list[str | Var]: ...
|
||||
def render(self) -> str: ...
|
||||
@overload
|
||||
@classmethod
|
||||
|
@ -51,7 +51,7 @@ class Clipboard(Fragment):
|
||||
return super().create(*children, **props)
|
||||
|
||||
def _exclude_props(self) -> list[str]:
|
||||
return super()._exclude_props() + ["on_paste", "on_paste_event_actions"]
|
||||
return [*super()._exclude_props(), "on_paste", "on_paste_event_actions"]
|
||||
|
||||
def _render(self) -> Tag:
|
||||
tag = super()._render()
|
||||
|
@ -49,9 +49,9 @@ class Cond(MemoizationLeaf):
|
||||
The conditional component.
|
||||
"""
|
||||
# Wrap everything in fragments.
|
||||
if comp1.__class__.__name__ != "Fragment":
|
||||
if type(comp1).__name__ != "Fragment":
|
||||
comp1 = Fragment.create(comp1)
|
||||
if comp2 is None or comp2.__class__.__name__ != "Fragment":
|
||||
if comp2 is None or type(comp2).__name__ != "Fragment":
|
||||
comp2 = Fragment.create(comp2) if comp2 else Fragment.create()
|
||||
return Fragment.create(
|
||||
cls(
|
||||
@ -94,7 +94,7 @@ class Cond(MemoizationLeaf):
|
||||
).set(
|
||||
props=tag.format_props(),
|
||||
),
|
||||
cond_state=f"isTrue({str(self.cond)})",
|
||||
cond_state=f"isTrue({self.cond!s})",
|
||||
)
|
||||
|
||||
def add_imports(self) -> ImportDict:
|
||||
|
@ -54,7 +54,7 @@ class Foreach(Component):
|
||||
iterable = LiteralVar.create(iterable)
|
||||
if iterable._var_type == Any:
|
||||
raise ForeachVarError(
|
||||
f"Could not foreach over var `{str(iterable)}` of type Any. "
|
||||
f"Could not foreach over var `{iterable!s}` of type Any. "
|
||||
"(If you are trying to foreach over a state var, add a type annotation to the var). "
|
||||
"See https://reflex.dev/docs/library/dynamic-rendering/foreach/"
|
||||
)
|
||||
|
@ -61,7 +61,7 @@ def upload_file(id_: str = DEFAULT_UPLOAD_ID) -> Var:
|
||||
id_var = LiteralStringVar.create(id_)
|
||||
var_name = f"""e => setFilesById(filesById => {{
|
||||
const updatedFilesById = Object.assign({{}}, filesById);
|
||||
updatedFilesById[{str(id_var)}] = e;
|
||||
updatedFilesById[{id_var!s}] = e;
|
||||
return updatedFilesById;
|
||||
}})
|
||||
"""
|
||||
@ -87,7 +87,7 @@ def selected_files(id_: str = DEFAULT_UPLOAD_ID) -> Var:
|
||||
"""
|
||||
id_var = LiteralStringVar.create(id_)
|
||||
return Var(
|
||||
_js_expr=f"(filesById[{str(id_var)}] ? filesById[{str(id_var)}].map((f) => (f.path || f.name)) : [])",
|
||||
_js_expr=f"(filesById[{id_var!s}] ? filesById[{id_var!s}].map((f) => (f.path || f.name)) : [])",
|
||||
_var_type=List[str],
|
||||
_var_data=VarData.merge(
|
||||
upload_files_context_var_data, id_var._get_all_var_data()
|
||||
@ -120,9 +120,7 @@ def cancel_upload(upload_id: str) -> EventSpec:
|
||||
Returns:
|
||||
An event spec that cancels the upload when triggered.
|
||||
"""
|
||||
return run_script(
|
||||
f"upload_controllers[{str(LiteralVar.create(upload_id))}]?.abort()"
|
||||
)
|
||||
return run_script(f"upload_controllers[{LiteralVar.create(upload_id)!s}]?.abort()")
|
||||
|
||||
|
||||
def get_upload_dir() -> Path:
|
||||
@ -301,7 +299,7 @@ class Upload(MemoizationLeaf):
|
||||
)
|
||||
|
||||
left_side = f"const {{getRootProps: {root_props_unique_name}, getInputProps: {input_props_unique_name}}} "
|
||||
right_side = f"useDropzone({str(use_dropzone_arguments)})"
|
||||
right_side = f"useDropzone({use_dropzone_arguments!s})"
|
||||
|
||||
var_data = VarData.merge(
|
||||
VarData(
|
||||
|
@ -519,13 +519,13 @@ class CodeBlock(Component, MarkdownComponentMap):
|
||||
The hook to register the language.
|
||||
"""
|
||||
return f"""
|
||||
if ({str(_LANGUAGE)}) {{
|
||||
if ({_LANGUAGE!s}) {{
|
||||
(async () => {{
|
||||
try {{
|
||||
const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${{{str(_LANGUAGE)}}}`);
|
||||
SyntaxHighlighter.registerLanguage({str(_LANGUAGE)}, module.default);
|
||||
const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${{{_LANGUAGE!s}}}`);
|
||||
SyntaxHighlighter.registerLanguage({_LANGUAGE!s}, module.default);
|
||||
}} catch (error) {{
|
||||
console.error(`Error importing language module for ${{{str(_LANGUAGE)}}}:`, error);
|
||||
console.error(`Error importing language module for ${{{_LANGUAGE!s}}}:`, error);
|
||||
}}
|
||||
}})();
|
||||
}}
|
||||
@ -547,7 +547,7 @@ class CodeBlock(Component, MarkdownComponentMap):
|
||||
The hooks for the component.
|
||||
"""
|
||||
return [
|
||||
f"const {str(_LANGUAGE)} = {str(self.language)}",
|
||||
f"const {_LANGUAGE!s} = {self.language!s}",
|
||||
self._get_language_registration_hook(),
|
||||
]
|
||||
|
||||
|
@ -51,27 +51,6 @@ class GridColumnIcons(Enum):
|
||||
VideoUri = "video_uri"
|
||||
|
||||
|
||||
# @serializer
|
||||
# def serialize_gridcolumn_icon(icon: GridColumnIcons) -> str:
|
||||
# """Serialize grid column icon.
|
||||
|
||||
# Args:
|
||||
# icon: the Icon to serialize.
|
||||
|
||||
# Returns:
|
||||
# The serialized value.
|
||||
# """
|
||||
# return "prefix" + str(icon)
|
||||
|
||||
|
||||
# class DataEditorColumn(Base):
|
||||
# """Column."""
|
||||
|
||||
# title: str
|
||||
# id: Optional[str] = None
|
||||
# type_: str = "str"
|
||||
|
||||
|
||||
class DataEditorTheme(Base):
|
||||
"""The theme for the DataEditor component."""
|
||||
|
||||
@ -229,7 +208,7 @@ class DataEditor(NoSSRComponent):
|
||||
header_height: Var[int]
|
||||
|
||||
# Additional header icons:
|
||||
# header_icons: Var[Any] # (TODO: must be a map of name: svg)
|
||||
# header_icons: Var[Any] # (TODO: must be a map of name: svg) #noqa: ERA001
|
||||
|
||||
# The maximum width a column can be automatically sized to.
|
||||
max_column_auto_width: Var[int]
|
||||
@ -406,10 +385,8 @@ class DataEditor(NoSSRComponent):
|
||||
props["rows"] = data.length() if isinstance(data, Var) else len(data)
|
||||
|
||||
if not isinstance(columns, Var) and len(columns):
|
||||
if (
|
||||
types.is_dataframe(type(data))
|
||||
or isinstance(data, Var)
|
||||
and types.is_dataframe(data._var_type)
|
||||
if types.is_dataframe(type(data)) or (
|
||||
isinstance(data, Var) and types.is_dataframe(data._var_type)
|
||||
):
|
||||
raise ValueError(
|
||||
"Cannot pass in both a pandas dataframe and columns to the data_editor component."
|
||||
|
@ -288,7 +288,7 @@ class DataEditor(NoSSRComponent):
|
||||
freeze_columns: The number of columns which should remain in place when scrolling horizontally. Doesn't include rowMarkers.
|
||||
group_header_height: Controls the header of the group header row.
|
||||
header_height: Controls the height of the header row.
|
||||
max_column_auto_width: Additional header icons: header_icons: Var[Any] # (TODO: must be a map of name: svg) The maximum width a column can be automatically sized to.
|
||||
max_column_auto_width: The maximum width a column can be automatically sized to.
|
||||
max_column_width: The maximum width a column can be resized to.
|
||||
min_column_width: The minimum width a column can be resized to.
|
||||
row_height: Determins the height of each row.
|
||||
|
@ -490,17 +490,17 @@ class ShikiJsTransformer(ShikiBaseTransformers):
|
||||
},
|
||||
# White Space
|
||||
# ".tab, .space": {
|
||||
# "position": "relative",
|
||||
# "position": "relative", # noqa: ERA001
|
||||
# },
|
||||
# ".tab::before": {
|
||||
# "content": "'⇥'",
|
||||
# "position": "absolute",
|
||||
# "opacity": "0.3",
|
||||
# "content": "'⇥'", # noqa: ERA001
|
||||
# "position": "absolute", # noqa: ERA001
|
||||
# "opacity": "0.3",# noqa: ERA001
|
||||
# },
|
||||
# ".space::before": {
|
||||
# "content": "'·'",
|
||||
# "position": "absolute",
|
||||
# "opacity": "0.3",
|
||||
# "content": "'·'", # noqa: ERA001
|
||||
# "position": "absolute", # noqa: ERA001
|
||||
# "opacity": "0.3", # noqa: ERA001
|
||||
# },
|
||||
}
|
||||
)
|
||||
|
@ -173,7 +173,7 @@ def load_dynamic_serializer():
|
||||
f"const [{unique_var_name}, set_{unique_var_name}] = useState(null);": None,
|
||||
"useEffect(() => {"
|
||||
"let isMounted = true;"
|
||||
f"evalReactComponent({str(js_string)})"
|
||||
f"evalReactComponent({js_string!s})"
|
||||
".then((component) => {"
|
||||
"if (isMounted) {"
|
||||
f"set_{unique_var_name}(component);"
|
||||
@ -183,7 +183,7 @@ def load_dynamic_serializer():
|
||||
"isMounted = false;"
|
||||
"};"
|
||||
"}"
|
||||
f", [{str(js_string)}]);": None,
|
||||
f", [{js_string!s}]);": None,
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Base classes."""
|
||||
|
||||
from typing import Union
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Forms classes."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@ -84,7 +84,6 @@ class Datalist(BaseHTML):
|
||||
"""Display the datalist element."""
|
||||
|
||||
tag = "datalist"
|
||||
# No unique attributes, only common ones are inherited
|
||||
|
||||
|
||||
class Fieldset(Element):
|
||||
@ -241,16 +240,15 @@ class Form(BaseHTML):
|
||||
if ref.startswith("refs_"):
|
||||
ref_var = Var(_js_expr=ref[:-3])._as_ref()
|
||||
form_refs[ref[len("refs_") : -3]] = Var(
|
||||
_js_expr=f"getRefValues({str(ref_var)})",
|
||||
_js_expr=f"getRefValues({ref_var!s})",
|
||||
_var_data=VarData.merge(ref_var._get_all_var_data()),
|
||||
)
|
||||
else:
|
||||
ref_var = Var(_js_expr=ref)._as_ref()
|
||||
form_refs[ref[4:]] = Var(
|
||||
_js_expr=f"getRefValue({str(ref_var)})",
|
||||
_js_expr=f"getRefValue({ref_var!s})",
|
||||
_var_data=VarData.merge(ref_var._get_all_var_data()),
|
||||
)
|
||||
# print(repr(form_refs))
|
||||
return form_refs
|
||||
|
||||
def _get_vars(self, include_children: bool = True) -> Iterator[Var]:
|
||||
@ -258,7 +256,8 @@ class Form(BaseHTML):
|
||||
yield from self._get_form_refs().values()
|
||||
|
||||
def _exclude_props(self) -> list[str]:
|
||||
return super()._exclude_props() + [
|
||||
return [
|
||||
*super()._exclude_props(),
|
||||
"reset_on_submit",
|
||||
"handle_submit_unique_name",
|
||||
]
|
||||
@ -400,7 +399,6 @@ class Legend(BaseHTML):
|
||||
"""Display the legend element."""
|
||||
|
||||
tag = "legend"
|
||||
# No unique attributes, only common ones are inherited
|
||||
|
||||
|
||||
class Meter(BaseHTML):
|
||||
@ -652,19 +650,20 @@ class Textarea(BaseHTML):
|
||||
"Cannot combine `enter_key_submit` with `on_key_down`.",
|
||||
)
|
||||
custom_attrs["on_key_down"] = Var(
|
||||
_js_expr=f"(e) => enterKeySubmitOnKeyDown(e, {str(enter_key_submit)})",
|
||||
_js_expr=f"(e) => enterKeySubmitOnKeyDown(e, {enter_key_submit!s})",
|
||||
_var_data=VarData.merge(enter_key_submit._get_all_var_data()),
|
||||
)
|
||||
if auto_height is not None:
|
||||
auto_height = Var.create(auto_height)
|
||||
custom_attrs["on_input"] = Var(
|
||||
_js_expr=f"(e) => autoHeightOnInput(e, {str(auto_height)})",
|
||||
_js_expr=f"(e) => autoHeightOnInput(e, {auto_height!s})",
|
||||
_var_data=VarData.merge(auto_height._get_all_var_data()),
|
||||
)
|
||||
return super().create(*children, **props)
|
||||
|
||||
def _exclude_props(self) -> list[str]:
|
||||
return super()._exclude_props() + [
|
||||
return [
|
||||
*super()._exclude_props(),
|
||||
"auto_height",
|
||||
"enter_key_submit",
|
||||
]
|
||||
|
@ -189,7 +189,7 @@ class Datalist(BaseHTML):
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: No unique attributes, only common ones are inherited Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -730,7 +730,7 @@ class Legend(BaseHTML):
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: No unique attributes, only common ones are inherited Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Inline classes."""
|
||||
|
||||
from typing import Union
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Media classes."""
|
||||
|
||||
from typing import Any, Union
|
||||
|
||||
@ -129,7 +129,6 @@ class Img(BaseHTML):
|
||||
|
||||
Returns:
|
||||
The component.
|
||||
|
||||
"""
|
||||
return (
|
||||
super().create(src=children[0], **props)
|
||||
@ -274,14 +273,12 @@ class Picture(BaseHTML):
|
||||
"""Display the picture element."""
|
||||
|
||||
tag = "picture"
|
||||
# No unique attributes, only common ones are inherited
|
||||
|
||||
|
||||
class Portal(BaseHTML):
|
||||
"""Display the portal element."""
|
||||
|
||||
tag = "portal"
|
||||
# No unique attributes, only common ones are inherited
|
||||
|
||||
|
||||
class Source(BaseHTML):
|
||||
|
@ -340,7 +340,6 @@ class Img(BaseHTML):
|
||||
|
||||
Returns:
|
||||
The component.
|
||||
|
||||
"""
|
||||
...
|
||||
|
||||
@ -987,7 +986,7 @@ class Picture(BaseHTML):
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: No unique attributes, only common ones are inherited Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -1073,7 +1072,7 @@ class Portal(BaseHTML):
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: No unique attributes, only common ones are inherited Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Metadata classes."""
|
||||
|
||||
from typing import List, Union
|
||||
|
||||
@ -8,7 +8,7 @@ from reflex.vars.base import Var
|
||||
from .base import BaseHTML
|
||||
|
||||
|
||||
class Base(BaseHTML): # noqa: E742
|
||||
class Base(BaseHTML):
|
||||
"""Display the base element."""
|
||||
|
||||
tag = "base"
|
||||
@ -18,13 +18,13 @@ class Base(BaseHTML): # noqa: E742
|
||||
target: Var[Union[str, int, bool]]
|
||||
|
||||
|
||||
class Head(BaseHTML): # noqa: E742
|
||||
class Head(BaseHTML):
|
||||
"""Display the head element."""
|
||||
|
||||
tag = "head"
|
||||
|
||||
|
||||
class Link(BaseHTML): # noqa: E742
|
||||
class Link(BaseHTML):
|
||||
"""Display the link element."""
|
||||
|
||||
tag = "link"
|
||||
@ -75,14 +75,14 @@ class Meta(BaseHTML): # Inherits common attributes from BaseHTML
|
||||
name: Var[Union[str, int, bool]]
|
||||
|
||||
|
||||
class Title(Element): # noqa: E742
|
||||
class Title(Element):
|
||||
"""Display the title element."""
|
||||
|
||||
tag = "title"
|
||||
|
||||
|
||||
# Had to be named with an underscore so it doesnt conflict with reflex.style Style in pyi
|
||||
class StyleEl(Element): # noqa: E742
|
||||
class StyleEl(Element):
|
||||
"""Display the style element."""
|
||||
|
||||
tag = "style"
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Other classes."""
|
||||
|
||||
from typing import Union
|
||||
|
||||
@ -26,31 +26,39 @@ class Dialog(BaseHTML):
|
||||
|
||||
|
||||
class Summary(BaseHTML):
|
||||
"""Display the summary element."""
|
||||
"""Display the summary element.
|
||||
|
||||
Used as a summary or caption for a <details> element.
|
||||
"""
|
||||
|
||||
tag = "summary"
|
||||
# No unique attributes, only common ones are inherited; used as a summary or caption for a <details> element
|
||||
|
||||
|
||||
class Slot(BaseHTML):
|
||||
"""Display the slot element."""
|
||||
"""Display the slot element.
|
||||
|
||||
Used as a placeholder inside a web component.
|
||||
"""
|
||||
|
||||
tag = "slot"
|
||||
# No unique attributes, only common ones are inherited; used as a placeholder inside a web component
|
||||
|
||||
|
||||
class Template(BaseHTML):
|
||||
"""Display the template element."""
|
||||
"""Display the template element.
|
||||
|
||||
Used for declaring fragments of HTML that can be cloned and inserted in the document.
|
||||
"""
|
||||
|
||||
tag = "template"
|
||||
# No unique attributes, only common ones are inherited; used for declaring fragments of HTML that can be cloned and inserted in the document
|
||||
|
||||
|
||||
class Math(BaseHTML):
|
||||
"""Display the math element."""
|
||||
"""Display the math element.
|
||||
|
||||
Represents a mathematical expression.
|
||||
"""
|
||||
|
||||
tag = "math"
|
||||
# No unique attributes, only common ones are inherited; used for displaying mathematical expressions
|
||||
|
||||
|
||||
class Html(BaseHTML):
|
||||
|
@ -244,7 +244,7 @@ class Summary(BaseHTML):
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: No unique attributes, only common ones are inherited; used as a summary or caption for a <details> element Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -330,7 +330,7 @@ class Slot(BaseHTML):
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: No unique attributes, only common ones are inherited; used as a placeholder inside a web component Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -416,7 +416,7 @@ class Template(BaseHTML):
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: No unique attributes, only common ones are inherited; used for declaring fragments of HTML that can be cloned and inserted in the document Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -502,7 +502,7 @@ class Math(BaseHTML):
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: No unique attributes, only common ones are inherited; used for displaying mathematical expressions Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Scripts classes."""
|
||||
|
||||
from typing import Union
|
||||
|
||||
@ -17,7 +17,6 @@ class Noscript(BaseHTML):
|
||||
"""Display the noscript element."""
|
||||
|
||||
tag = "noscript"
|
||||
# No unique attributes, only common ones are inherited
|
||||
|
||||
|
||||
class Script(BaseHTML):
|
||||
|
@ -154,7 +154,7 @@ class Noscript(BaseHTML):
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: No unique attributes, only common ones are inherited Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
|
@ -1,93 +1,93 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Sectioning classes."""
|
||||
|
||||
from .base import BaseHTML
|
||||
|
||||
|
||||
class Body(BaseHTML): # noqa: E742
|
||||
class Body(BaseHTML):
|
||||
"""Display the body element."""
|
||||
|
||||
tag = "body"
|
||||
|
||||
|
||||
class Address(BaseHTML): # noqa: E742
|
||||
class Address(BaseHTML):
|
||||
"""Display the address element."""
|
||||
|
||||
tag = "address"
|
||||
|
||||
|
||||
class Article(BaseHTML): # noqa: E742
|
||||
class Article(BaseHTML):
|
||||
"""Display the article element."""
|
||||
|
||||
tag = "article"
|
||||
|
||||
|
||||
class Aside(BaseHTML): # noqa: E742
|
||||
class Aside(BaseHTML):
|
||||
"""Display the aside element."""
|
||||
|
||||
tag = "aside"
|
||||
|
||||
|
||||
class Footer(BaseHTML): # noqa: E742
|
||||
class Footer(BaseHTML):
|
||||
"""Display the footer element."""
|
||||
|
||||
tag = "footer"
|
||||
|
||||
|
||||
class Header(BaseHTML): # noqa: E742
|
||||
class Header(BaseHTML):
|
||||
"""Display the header element."""
|
||||
|
||||
tag = "header"
|
||||
|
||||
|
||||
class H1(BaseHTML): # noqa: E742
|
||||
class H1(BaseHTML):
|
||||
"""Display the h1 element."""
|
||||
|
||||
tag = "h1"
|
||||
|
||||
|
||||
class H2(BaseHTML): # noqa: E742
|
||||
class H2(BaseHTML):
|
||||
"""Display the h1 element."""
|
||||
|
||||
tag = "h2"
|
||||
|
||||
|
||||
class H3(BaseHTML): # noqa: E742
|
||||
class H3(BaseHTML):
|
||||
"""Display the h1 element."""
|
||||
|
||||
tag = "h3"
|
||||
|
||||
|
||||
class H4(BaseHTML): # noqa: E742
|
||||
class H4(BaseHTML):
|
||||
"""Display the h1 element."""
|
||||
|
||||
tag = "h4"
|
||||
|
||||
|
||||
class H5(BaseHTML): # noqa: E742
|
||||
class H5(BaseHTML):
|
||||
"""Display the h1 element."""
|
||||
|
||||
tag = "h5"
|
||||
|
||||
|
||||
class H6(BaseHTML): # noqa: E742
|
||||
class H6(BaseHTML):
|
||||
"""Display the h1 element."""
|
||||
|
||||
tag = "h6"
|
||||
|
||||
|
||||
class Main(BaseHTML): # noqa: E742
|
||||
class Main(BaseHTML):
|
||||
"""Display the main element."""
|
||||
|
||||
tag = "main"
|
||||
|
||||
|
||||
class Nav(BaseHTML): # noqa: E742
|
||||
class Nav(BaseHTML):
|
||||
"""Display the nav element."""
|
||||
|
||||
tag = "nav"
|
||||
|
||||
|
||||
class Section(BaseHTML): # noqa: E742
|
||||
class Section(BaseHTML):
|
||||
"""Display the section element."""
|
||||
|
||||
tag = "section"
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Tables classes."""
|
||||
|
||||
from typing import Union
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Typography classes."""
|
||||
|
||||
from typing import Union
|
||||
|
||||
|
@ -283,7 +283,7 @@ class Markdown(Component):
|
||||
# Format the code to handle inline and block code.
|
||||
formatted_code = f"""
|
||||
const match = (className || '').match(/language-(?<lang>.*)/);
|
||||
const {str(_LANGUAGE)} = match ? match[1] : '';
|
||||
const {_LANGUAGE!s} = match ? match[1] : '';
|
||||
{codeblock_custom_code};
|
||||
return inline ? (
|
||||
{self.format_component("code")}
|
||||
@ -340,7 +340,7 @@ const {str(_LANGUAGE)} = match ? match[1] : '';
|
||||
# If the children are set as a prop, don't pass them as children.
|
||||
children_prop = props.pop("children", None)
|
||||
if children_prop is not None:
|
||||
special_props.append(Var(_js_expr=f"children={{{str(children_prop)}}}"))
|
||||
special_props.append(Var(_js_expr=f"children={{{children_prop!s}}}"))
|
||||
children = []
|
||||
# Get the component.
|
||||
component = self.component_map[tag](*children, **props).set(
|
||||
@ -429,7 +429,7 @@ const {str(_LANGUAGE)} = match ? match[1] : '';
|
||||
function {self._get_component_map_name()} () {{
|
||||
{formatted_hooks}
|
||||
return (
|
||||
{str(LiteralVar.create(self.format_component_map()))}
|
||||
{LiteralVar.create(self.format_component_map())!s}
|
||||
)
|
||||
}}
|
||||
"""
|
||||
|
@ -47,7 +47,7 @@ class Image(NextComponent):
|
||||
placeholder: Var[str]
|
||||
|
||||
# Allows passing CSS styles to the underlying image element.
|
||||
# style: Var[Any]
|
||||
# style: Var[Any] #noqa: ERA001
|
||||
|
||||
# The loading behavior of the image. Defaults to lazy. Can hurt performance, recommended to use `priority` instead.
|
||||
loading: Var[Literal["lazy", "eager"]]
|
||||
|
@ -70,7 +70,7 @@ class Image(NextComponent):
|
||||
quality: The quality of the optimized image, an integer between 1 and 100, where 100 is the best quality and therefore largest file size. Defaults to 75.
|
||||
priority: When true, the image will be considered high priority and preload. Lazy loading is automatically disabled for images using priority.
|
||||
placeholder: A placeholder to use while the image is loading. Possible values are blur, empty, or data:image/.... Defaults to empty.
|
||||
loading: Allows passing CSS styles to the underlying image element. style: Var[Any] The loading behavior of the image. Defaults to lazy. Can hurt performance, recommended to use `priority` instead.
|
||||
loading: The loading behavior of the image. Defaults to lazy. Can hurt performance, recommended to use `priority` instead.
|
||||
blurDataURL: A Data URL to be used as a placeholder image before the src image successfully loads. Only takes effect when combined with placeholder="blur".
|
||||
on_load: Fires when the image has loaded.
|
||||
on_error: Fires when the image has an error.
|
||||
|
@ -270,11 +270,11 @@ const extractPoints = (points) => {
|
||||
tag.special_props.append(
|
||||
# Merge all dictionaries and spread the result over props.
|
||||
Var(
|
||||
_js_expr=f"{{...mergician({str(figure)},"
|
||||
_js_expr=f"{{...mergician({figure!s},"
|
||||
f"{','.join(str(md) for md in merge_dicts)})}}",
|
||||
),
|
||||
)
|
||||
else:
|
||||
# Spread the figure dict over props, nothing to merge.
|
||||
tag.special_props.append(Var(_js_expr=f"{{...{str(figure)}}}"))
|
||||
tag.special_props.append(Var(_js_expr=f"{{...{figure!s}}}"))
|
||||
return tag
|
||||
|
@ -129,7 +129,8 @@ class AccordionRoot(AccordionComponent):
|
||||
on_value_change: EventHandler[on_value_change]
|
||||
|
||||
def _exclude_props(self) -> list[str]:
|
||||
return super()._exclude_props() + [
|
||||
return [
|
||||
*super()._exclude_props(),
|
||||
"radius",
|
||||
"duration",
|
||||
"easing",
|
||||
|
@ -188,7 +188,7 @@ class Slider(ComponentNamespace):
|
||||
else:
|
||||
children = [
|
||||
track,
|
||||
# Foreach.create(props.get("value"), lambda e: SliderThumb.create()), # foreach doesn't render Thumbs properly
|
||||
# Foreach.create(props.get("value"), lambda e: SliderThumb.create()), # foreach doesn't render Thumbs properly # noqa: ERA001
|
||||
]
|
||||
|
||||
return SliderRoot.create(*children, **props)
|
||||
|
@ -53,7 +53,7 @@ LiteralAccentColor = Literal[
|
||||
class CommonMarginProps(Component):
|
||||
"""Many radix-themes elements accept shorthand margin props."""
|
||||
|
||||
# Margin: "0" - "9"
|
||||
# Margin: "0" - "9" # noqa: ERA001
|
||||
m: Var[LiteralSpacing]
|
||||
|
||||
# Margin horizontal: "0" - "9"
|
||||
@ -78,7 +78,7 @@ class CommonMarginProps(Component):
|
||||
class CommonPaddingProps(Component):
|
||||
"""Many radix-themes elements accept shorthand padding props."""
|
||||
|
||||
# Padding: "0" - "9"
|
||||
# Padding: "0" - "9" # noqa: ERA001
|
||||
p: Var[Responsive[LiteralSpacing]]
|
||||
|
||||
# Padding horizontal: "0" - "9"
|
||||
@ -139,14 +139,7 @@ class RadixThemesComponent(Component):
|
||||
component = super().create(*children, **props)
|
||||
if component.library is None:
|
||||
component.library = RadixThemesComponent.__fields__["library"].default
|
||||
component.alias = "RadixThemes" + (
|
||||
component.tag or component.__class__.__name__
|
||||
)
|
||||
# value = props.get("value")
|
||||
# if value is not None and component.alias == "RadixThemesSelect.Root":
|
||||
# lv = LiteralVar.create(value)
|
||||
# print(repr(lv))
|
||||
# print(f"Warning: Value {value} is not used in {component.alias}.")
|
||||
component.alias = "RadixThemes" + (component.tag or type(component).__name__)
|
||||
return component
|
||||
|
||||
@staticmethod
|
||||
@ -268,6 +261,7 @@ class Theme(RadixThemesComponent):
|
||||
_js_expr="{...theme.styles.global[':root'], ...theme.styles.global.body}"
|
||||
),
|
||||
)
|
||||
tag.remove_props("appearance")
|
||||
return tag
|
||||
|
||||
|
||||
|
@ -427,7 +427,7 @@ class ColorModeSwitch(Switch):
|
||||
color_scheme: Override theme color for switch
|
||||
high_contrast: Whether to render the switch with higher contrast color against background
|
||||
radius: Override theme radius for switch: "none" | "small" | "full"
|
||||
on_change: Props to rename Fired when the value of the switch changes
|
||||
on_change: Fired when the value of the switch changes
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
|
@ -153,7 +153,7 @@ class Checkbox(RadixThemesComponent):
|
||||
required: Whether the checkbox is required
|
||||
name: The name of the checkbox control when submitting the form.
|
||||
value: The value of the checkbox control when submitting the form.
|
||||
on_change: Props to rename Fired when the checkbox is checked or unchecked.
|
||||
on_change: Fired when the checkbox is checked or unchecked.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
@ -302,7 +302,7 @@ class HighLevelCheckbox(RadixThemesComponent):
|
||||
required: Whether the checkbox is required
|
||||
name: The name of the checkbox control when submitting the form.
|
||||
value: The value of the checkbox control when submitting the form.
|
||||
on_change: Props to rename Fired when the checkbox is checked or unchecked.
|
||||
on_change: Fired when the checkbox is checked or unchecked.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
@ -449,7 +449,7 @@ class CheckboxNamespace(ComponentNamespace):
|
||||
required: Whether the checkbox is required
|
||||
name: The name of the checkbox control when submitting the form.
|
||||
value: The value of the checkbox control when submitting the form.
|
||||
on_change: Props to rename Fired when the checkbox is checked or unchecked.
|
||||
on_change: Fired when the checkbox is checked or unchecked.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
|
@ -140,10 +140,8 @@ class HighLevelRadioGroup(RadixThemesComponent):
|
||||
color_scheme = props.pop("color_scheme", None)
|
||||
default_value = props.pop("default_value", "")
|
||||
|
||||
if (
|
||||
not isinstance(items, (list, Var))
|
||||
or isinstance(items, Var)
|
||||
and not types._issubclass(items._var_type, list)
|
||||
if not isinstance(items, (list, Var)) or (
|
||||
isinstance(items, Var) and not types._issubclass(items._var_type, list)
|
||||
):
|
||||
items_type = type(items) if not isinstance(items, Var) else items._var_type
|
||||
raise TypeError(
|
||||
|
@ -148,7 +148,7 @@ class RadioGroupRoot(RadixThemesComponent):
|
||||
disabled: Whether the radio group is disabled
|
||||
name: The name of the group. Submitted with its owning form as part of a name/value pair.
|
||||
required: Whether the radio group is required
|
||||
on_change: Props to rename Fired when the value of the radio group changes.
|
||||
on_change: Fired when the value of the radio group changes.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
|
@ -81,7 +81,7 @@ class SelectRoot(RadixThemesComponent):
|
||||
name: The name of the select control when submitting the form.
|
||||
disabled: When True, prevents the user from interacting with select.
|
||||
required: When True, indicates that the user must select a value before the owning form can be submitted.
|
||||
on_change: Props to rename Fired when the value of the select changes.
|
||||
on_change: Fired when the value of the select changes.
|
||||
on_open_change: Fired when the select is opened or closed.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
@ -732,7 +732,7 @@ class HighLevelSelect(SelectRoot):
|
||||
name: The name of the select control when submitting the form.
|
||||
disabled: When True, prevents the user from interacting with select.
|
||||
required: When True, indicates that the user must select a value before the owning form can be submitted.
|
||||
on_change: Props to rename Fired when the value of the select changes.
|
||||
on_change: Fired when the value of the select changes.
|
||||
on_open_change: Fired when the select is opened or closed.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
@ -912,7 +912,7 @@ class Select(ComponentNamespace):
|
||||
name: The name of the select control when submitting the form.
|
||||
disabled: When True, prevents the user from interacting with select.
|
||||
required: When True, indicates that the user must select a value before the owning form can be submitted.
|
||||
on_change: Props to rename Fired when the value of the select changes.
|
||||
on_change: Fired when the value of the select changes.
|
||||
on_open_change: Fired when the select is opened or closed.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
|
@ -195,7 +195,7 @@ class Slider(RadixThemesComponent):
|
||||
step: The step value of the slider.
|
||||
disabled: Whether the slider is disabled
|
||||
orientation: The orientation of the slider.
|
||||
on_change: Props to rename Fired when the value of the slider changes.
|
||||
on_change: Fired when the value of the slider changes.
|
||||
on_value_commit: Fired when a thumb is released after being dragged.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
|
@ -157,7 +157,7 @@ class Switch(RadixThemesComponent):
|
||||
color_scheme: Override theme color for switch
|
||||
high_contrast: Whether to render the switch with higher contrast color against background
|
||||
radius: Override theme radius for switch: "none" | "small" | "full"
|
||||
on_change: Props to rename Fired when the value of the switch changes
|
||||
on_change: Fired when the value of the switch changes
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
|
@ -72,7 +72,7 @@ class TabsRoot(RadixThemesComponent):
|
||||
orientation: The orientation of the tabs.
|
||||
dir: Reading direction of the tabs.
|
||||
activation_mode: The mode of activation for the tabs. "automatic" will activate the tab when focused. "manual" will activate the tab when clicked.
|
||||
on_change: Props to rename Fired when the value of the tabs changes.
|
||||
on_change: Fired when the value of the tabs changes.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
@ -374,7 +374,7 @@ class Tabs(ComponentNamespace):
|
||||
orientation: The orientation of the tabs.
|
||||
dir: Reading direction of the tabs.
|
||||
activation_mode: The mode of activation for the tabs. "automatic" will activate the tab when focused. "manual" will activate the tab when clicked.
|
||||
on_change: Props to rename Fired when the value of the tabs changes.
|
||||
on_change: Fired when the value of the tabs changes.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
|
@ -64,7 +64,6 @@ class BaseList(Component, MarkdownComponentMap):
|
||||
|
||||
Returns:
|
||||
The list component.
|
||||
|
||||
"""
|
||||
items = props.pop("items", None)
|
||||
list_style_type = props.pop("list_style_type", "none")
|
||||
@ -114,7 +113,6 @@ class UnorderedList(BaseList, Ul):
|
||||
|
||||
Returns:
|
||||
The list component.
|
||||
|
||||
"""
|
||||
items = props.pop("items", None)
|
||||
list_style_type = props.pop("list_style_type", "disc")
|
||||
@ -144,7 +142,6 @@ class OrderedList(BaseList, Ol):
|
||||
|
||||
Returns:
|
||||
The list component.
|
||||
|
||||
"""
|
||||
items = props.pop("items", None)
|
||||
list_style_type = props.pop("list_style_type", "decimal")
|
||||
@ -168,7 +165,6 @@ class ListItem(Li, MarkdownComponentMap):
|
||||
|
||||
Returns:
|
||||
The list item component.
|
||||
|
||||
"""
|
||||
for child in children:
|
||||
if isinstance(child, Text):
|
||||
|
@ -118,7 +118,6 @@ class BaseList(Component, MarkdownComponentMap):
|
||||
|
||||
Returns:
|
||||
The list component.
|
||||
|
||||
"""
|
||||
...
|
||||
|
||||
@ -252,7 +251,6 @@ class UnorderedList(BaseList, Ul):
|
||||
|
||||
Returns:
|
||||
The list component.
|
||||
|
||||
"""
|
||||
...
|
||||
|
||||
@ -390,7 +388,6 @@ class OrderedList(BaseList, Ol):
|
||||
|
||||
Returns:
|
||||
The list component.
|
||||
|
||||
"""
|
||||
...
|
||||
|
||||
@ -477,7 +474,6 @@ class ListItem(Li, MarkdownComponentMap):
|
||||
|
||||
Returns:
|
||||
The list item component.
|
||||
|
||||
"""
|
||||
...
|
||||
|
||||
@ -571,7 +567,6 @@ class List(ComponentNamespace):
|
||||
|
||||
Returns:
|
||||
The list component.
|
||||
|
||||
"""
|
||||
...
|
||||
|
||||
|
@ -77,13 +77,14 @@ class Link(RadixThemesComponent, A, MemoizationLeaf, MarkdownComponentMap):
|
||||
Component: The link component
|
||||
"""
|
||||
props.setdefault(":hover", {"color": color("accent", 8)})
|
||||
href = props.get("href")
|
||||
|
||||
is_external = props.pop("is_external", None)
|
||||
|
||||
if is_external is not None:
|
||||
props["target"] = cond(is_external, "_blank", "")
|
||||
|
||||
if props.get("href") is not None:
|
||||
if href is not None:
|
||||
if not len(children):
|
||||
raise ValueError("Link without a child will not display")
|
||||
|
||||
@ -101,6 +102,9 @@ class Link(RadixThemesComponent, A, MemoizationLeaf, MarkdownComponentMap):
|
||||
as_child=True,
|
||||
**props,
|
||||
)
|
||||
else:
|
||||
props["href"] = "#"
|
||||
|
||||
return super().create(*children, **props)
|
||||
|
||||
|
||||
|
@ -416,7 +416,7 @@ class Bar(Cartesian):
|
||||
radius: Var[Union[int, List[int]]]
|
||||
|
||||
# The active bar is shown when a user enters a bar chart and this chart has tooltip. If set to false, no active bar will be drawn. If set to true, active bar will be drawn with the props calculated internally. If passed an object, active bar will be drawn, and the internally calculated props will be merged with the key value pairs of the passed object.
|
||||
# active_bar: Var[Union[bool, Dict[str, Any]]]
|
||||
# active_bar: Var[Union[bool, Dict[str, Any]]] #noqa: ERA001
|
||||
|
||||
# Valid children components
|
||||
_valid_children: List[str] = ["Cell", "LabelList", "ErrorBar"]
|
||||
|
@ -136,7 +136,7 @@ class Radar(Recharts):
|
||||
# Fill color. Default: rx.color("accent", 3)
|
||||
fill: Var[str] = LiteralVar.create(Color("accent", 3))
|
||||
|
||||
# opacity. Default: 0.6
|
||||
# The opacity to fill the chart. Default: 0.6
|
||||
fill_opacity: Var[float] = LiteralVar.create(0.6)
|
||||
|
||||
# The type of icon in legend. If set to 'none', no legend item will be rendered. Default: "rect"
|
||||
|
@ -204,7 +204,7 @@ class Radar(Recharts):
|
||||
dot: If false set, dots will not be drawn. Default: True
|
||||
stroke: Stoke color. Default: rx.color("accent", 9)
|
||||
fill: Fill color. Default: rx.color("accent", 3)
|
||||
fill_opacity: opacity. Default: 0.6
|
||||
fill_opacity: The opacity to fill the chart. Default: 0.6
|
||||
legend_type: The type of icon in legend. If set to 'none', no legend item will be rendered. Default: "rect"
|
||||
label: If false set, labels will not be drawn. Default: True
|
||||
is_animation_active: If set false, animation of polygon will be disabled. Default: True in CSR, and False in SSR
|
||||
|
@ -64,7 +64,7 @@ def _toast_callback_signature(toast: Var) -> list[Var]:
|
||||
"""
|
||||
return [
|
||||
Var(
|
||||
_js_expr=f"(() => {{let {{action, cancel, onDismiss, onAutoClose, ...rest}} = {str(toast)}; return rest}})()"
|
||||
_js_expr=f"(() => {{let {{action, cancel, onDismiss, onAutoClose, ...rest}} = {toast!s}; return rest}})()"
|
||||
)
|
||||
]
|
||||
|
||||
@ -98,7 +98,7 @@ class ToastProps(PropsBase, NoExtrasAllowedProps):
|
||||
|
||||
# TODO: fix serialization of icons for toast? (might not be possible yet)
|
||||
# Icon displayed in front of toast's text, aligned vertically.
|
||||
# icon: Optional[Icon] = None
|
||||
# icon: Optional[Icon] = None # noqa: ERA001
|
||||
|
||||
# TODO: fix implementation for action / cancel buttons
|
||||
# Renders a primary button, clicking it will close the toast.
|
||||
@ -338,7 +338,7 @@ class Toaster(Component):
|
||||
dismiss_var_data = None
|
||||
|
||||
if isinstance(id, Var):
|
||||
dismiss = f"{toast_ref}.dismiss({str(id)})"
|
||||
dismiss = f"{toast_ref}.dismiss({id!s})"
|
||||
dismiss_var_data = id._get_all_var_data()
|
||||
elif isinstance(id, str):
|
||||
dismiss = f"{toast_ref}.dismiss('{id}')"
|
||||
@ -364,9 +364,7 @@ class Toaster(Component):
|
||||
return super().create(*children, **props)
|
||||
|
||||
|
||||
# TODO: figure out why loading toast stay open forever
|
||||
# def toast_loading(message: str, **kwargs):
|
||||
# return _toast(message, level="loading", **kwargs)
|
||||
# TODO: figure out why loading toast stay open forever when using level="loading" in toast()
|
||||
|
||||
|
||||
class ToastNamespace(ComponentNamespace):
|
||||
@ -379,7 +377,6 @@ class ToastNamespace(ComponentNamespace):
|
||||
error = staticmethod(Toaster.toast_error)
|
||||
success = staticmethod(Toaster.toast_success)
|
||||
dismiss = staticmethod(Toaster.toast_dismiss)
|
||||
# loading = staticmethod(toast_loading)
|
||||
__call__ = staticmethod(Toaster.send_toast)
|
||||
|
||||
|
||||
|
@ -116,7 +116,7 @@ class Editor(NoSSRComponent):
|
||||
# Please refer to the library docs for this.
|
||||
# options: "en" | "da" | "de" | "es" | "fr" | "ja" | "ko" | "pt_br" |
|
||||
# "ru" | "zh_cn" | "ro" | "pl" | "ckb" | "lv" | "se" | "ua" | "he" | "it"
|
||||
# default : "en"
|
||||
# default: "en".
|
||||
lang: Var[
|
||||
Union[
|
||||
Literal[
|
||||
@ -172,7 +172,7 @@ class Editor(NoSSRComponent):
|
||||
set_options: Var[Dict]
|
||||
|
||||
# Whether all SunEditor plugins should be loaded.
|
||||
# default: True
|
||||
# default: True.
|
||||
set_all_plugins: Var[bool]
|
||||
|
||||
# Set the content of the editor.
|
||||
@ -191,19 +191,19 @@ class Editor(NoSSRComponent):
|
||||
set_default_style: Var[str]
|
||||
|
||||
# Disable the editor
|
||||
# default: False
|
||||
# default: False.
|
||||
disable: Var[bool]
|
||||
|
||||
# Hide the editor
|
||||
# default: False
|
||||
# default: False.
|
||||
hide: Var[bool]
|
||||
|
||||
# Hide the editor toolbar
|
||||
# default: False
|
||||
# default: False.
|
||||
hide_toolbar: Var[bool]
|
||||
|
||||
# Disable the editor toolbar
|
||||
# default: False
|
||||
# default: False.
|
||||
disable_toolbar: Var[bool]
|
||||
|
||||
# Fired when the editor content changes.
|
||||
|
@ -172,7 +172,7 @@ class Editor(NoSSRComponent):
|
||||
|
||||
Args:
|
||||
set_options(Optional[EditorOptions]): Configuration object to further configure the instance.
|
||||
lang: Language of the editor. Alternatively to a string, a dict of your language can be passed to this prop. Please refer to the library docs for this. options: "en" | "da" | "de" | "es" | "fr" | "ja" | "ko" | "pt_br" | "ru" | "zh_cn" | "ro" | "pl" | "ckb" | "lv" | "se" | "ua" | "he" | "it" default : "en"
|
||||
lang: Language of the editor. Alternatively to a string, a dict of your language can be passed to this prop. Please refer to the library docs for this. options: "en" | "da" | "de" | "es" | "fr" | "ja" | "ko" | "pt_br" | "ru" | "zh_cn" | "ro" | "pl" | "ckb" | "lv" | "se" | "ua" | "he" | "it" default: "en".
|
||||
name: This is used to set the HTML form name of the editor. This means on HTML form submission, it will be submitted together with contents of the editor by the name provided.
|
||||
default_value: Sets the default value of the editor. This is useful if you don't want the on_change method to be called on render. If you want the on_change method to be called on render please use the set_contents prop
|
||||
width: Sets the width of the editor. px and percentage values are accepted, eg width="100%" or width="500px" default: 100%
|
||||
@ -180,14 +180,14 @@ class Editor(NoSSRComponent):
|
||||
placeholder: Sets the placeholder of the editor.
|
||||
auto_focus: Should the editor receive focus when initialized?
|
||||
set_options: Pass an EditorOptions instance to modify the behaviour of Editor even more.
|
||||
set_all_plugins: Whether all SunEditor plugins should be loaded. default: True
|
||||
set_all_plugins: Whether all SunEditor plugins should be loaded. default: True.
|
||||
set_contents: Set the content of the editor. Note: To set the initial contents of the editor without calling the on_change event, please use the default_value prop. set_contents is used to set the contents of the editor programmatically. You must be aware that, when the set_contents's prop changes, the on_change event is triggered.
|
||||
append_contents: Append editor content
|
||||
set_default_style: Sets the default style of the editor's edit area
|
||||
disable: Disable the editor default: False
|
||||
hide: Hide the editor default: False
|
||||
hide_toolbar: Hide the editor toolbar default: False
|
||||
disable_toolbar: Disable the editor toolbar default: False
|
||||
disable: Disable the editor default: False.
|
||||
hide: Hide the editor default: False.
|
||||
hide_toolbar: Hide the editor toolbar default: False.
|
||||
disable_toolbar: Disable the editor toolbar default: False.
|
||||
on_change: Fired when the editor content changes.
|
||||
on_input: Fired when the something is inputted in the editor.
|
||||
on_blur: Fired when the editor loses focus.
|
||||
|
@ -82,7 +82,7 @@ class DBConfig(Base):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def postgresql_psycopg2(
|
||||
def postgresql_psycopg(
|
||||
cls,
|
||||
database: str,
|
||||
username: str,
|
||||
@ -90,7 +90,7 @@ class DBConfig(Base):
|
||||
host: str | None = None,
|
||||
port: int | None = 5432,
|
||||
) -> DBConfig:
|
||||
"""Create an instance with postgresql+psycopg2 engine.
|
||||
"""Create an instance with postgresql+psycopg engine.
|
||||
|
||||
Args:
|
||||
database: Database name.
|
||||
@ -103,7 +103,7 @@ class DBConfig(Base):
|
||||
DBConfig instance.
|
||||
"""
|
||||
return cls(
|
||||
engine="postgresql+psycopg2",
|
||||
engine="postgresql+psycopg",
|
||||
username=username,
|
||||
password=password,
|
||||
host=host,
|
||||
@ -512,6 +512,9 @@ class EnvironmentVariables:
|
||||
# Whether to print the SQL queries if the log level is INFO or lower.
|
||||
SQLALCHEMY_ECHO: EnvVar[bool] = env_var(False)
|
||||
|
||||
# Whether to check db connections before using them.
|
||||
SQLALCHEMY_POOL_PRE_PING: EnvVar[bool] = env_var(True)
|
||||
|
||||
# Whether to ignore the redis config error. Some redis servers only allow out-of-band configuration.
|
||||
REFLEX_IGNORE_REDIS_CONFIG_ERROR: EnvVar[bool] = env_var(False)
|
||||
|
||||
@ -568,6 +571,10 @@ class EnvironmentVariables:
|
||||
environment = EnvironmentVariables()
|
||||
|
||||
|
||||
# These vars are not logged because they may contain sensitive information.
|
||||
_sensitive_env_vars = {"DB_URL", "ASYNC_DB_URL", "REDIS_URL"}
|
||||
|
||||
|
||||
class Config(Base):
|
||||
"""The config defines runtime settings for the app.
|
||||
|
||||
@ -621,6 +628,9 @@ class Config(Base):
|
||||
# The database url used by rx.Model.
|
||||
db_url: Optional[str] = "sqlite:///reflex.db"
|
||||
|
||||
# The async database url used by rx.Model.
|
||||
async_db_url: Optional[str] = None
|
||||
|
||||
# The redis url
|
||||
redis_url: Optional[str] = None
|
||||
|
||||
@ -748,18 +758,20 @@ class Config(Base):
|
||||
|
||||
# If the env var is set, override the config value.
|
||||
if env_var is not None:
|
||||
if key.upper() != "DB_URL":
|
||||
console.info(
|
||||
f"Overriding config value {key} with env var {key.upper()}={env_var}",
|
||||
dedupe=True,
|
||||
)
|
||||
|
||||
# Interpret the value.
|
||||
value = interpret_env_var_value(env_var, field.outer_type_, field.name)
|
||||
|
||||
# Set the value.
|
||||
updated_values[key] = value
|
||||
|
||||
if key.upper() in _sensitive_env_vars:
|
||||
env_var = "***"
|
||||
|
||||
console.info(
|
||||
f"Overriding config value {key} with env var {key.upper()}={env_var}",
|
||||
dedupe=True,
|
||||
)
|
||||
|
||||
return updated_values
|
||||
|
||||
def get_event_namespace(self) -> str:
|
||||
|
@ -447,7 +447,7 @@ class JavascriptHTMLInputElement:
|
||||
class JavascriptInputEvent:
|
||||
"""Interface for a Javascript InputEvent https://developer.mozilla.org/en-US/docs/Web/API/InputEvent."""
|
||||
|
||||
target: JavascriptHTMLInputElement = JavascriptHTMLInputElement()
|
||||
target: JavascriptHTMLInputElement = JavascriptHTMLInputElement() # noqa: RUF009
|
||||
|
||||
|
||||
@dataclasses.dataclass(
|
||||
@ -1222,7 +1222,7 @@ def call_event_handler(
|
||||
except TypeError:
|
||||
# TODO: In 0.7.0, remove this block and raise the exception
|
||||
# raise TypeError(
|
||||
# f"Could not compare types {args_types_without_vars[i]} and {type_hints_of_provided_callback[arg]} for argument {arg} of {event_handler.fn.__qualname__} provided for {key}."
|
||||
# f"Could not compare types {args_types_without_vars[i]} and {type_hints_of_provided_callback[arg]} for argument {arg} of {event_handler.fn.__qualname__} provided for {key}." # noqa: ERA001
|
||||
# ) from e
|
||||
console.warn(
|
||||
f"Could not compare types {args_types_without_vars[i]} and {type_hints_of_provided_callback[arg]} for argument {arg} of {event_callback.fn.__qualname__} provided for {key}."
|
||||
@ -1556,7 +1556,7 @@ class LiteralEventVar(VarOperationCall, LiteralVar, EventVar):
|
||||
Returns:
|
||||
The hash of the var.
|
||||
"""
|
||||
return hash((self.__class__.__name__, self._js_expr))
|
||||
return hash((type(self).__name__, self._js_expr))
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
@ -1620,7 +1620,7 @@ class LiteralEventChainVar(ArgsFunctionOperationBuilder, LiteralVar, EventChainV
|
||||
Returns:
|
||||
The hash of the var.
|
||||
"""
|
||||
return hash((self.__class__.__name__, self._js_expr))
|
||||
return hash((type(self).__name__, self._js_expr))
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
|
@ -106,7 +106,7 @@ class ClientStateVar(Var):
|
||||
default_var = default
|
||||
setter_name = f"set{var_name.capitalize()}"
|
||||
hooks = {
|
||||
f"const [{var_name}, {setter_name}] = useState({str(default_var)})": None,
|
||||
f"const [{var_name}, {setter_name}] = useState({default_var!s})": None,
|
||||
}
|
||||
imports = {
|
||||
"react": [ImportVar(tag="useState")],
|
||||
@ -242,4 +242,5 @@ class ClientStateVar(Var):
|
||||
"""
|
||||
if not self._global_ref:
|
||||
raise ValueError("ClientStateVar must be global to push the value.")
|
||||
value = Var.create(value)
|
||||
return run_script(f"{_client_state_ref(self._setter_name)}({value})")
|
||||
|
@ -33,12 +33,6 @@ class Sidebar(Box, MemoizationLeaf):
|
||||
Returns:
|
||||
The sidebar component.
|
||||
"""
|
||||
# props.setdefault("border_right", f"1px solid {color('accent', 12)}")
|
||||
# props.setdefault("background_color", color("accent", 1))
|
||||
# props.setdefault("width", "20vw")
|
||||
# props.setdefault("height", "100vh")
|
||||
# props.setdefault("position", "fixed")
|
||||
|
||||
return super().create(
|
||||
Box.create(*children, **props), # sidebar for content
|
||||
Box.create(width=props.get("width")), # spacer for layout
|
||||
|
126
reflex/model.py
126
reflex/model.py
@ -2,6 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from typing import Any, ClassVar, Optional, Type, Union
|
||||
|
||||
@ -14,6 +15,7 @@ import alembic.script
|
||||
import alembic.util
|
||||
import sqlalchemy
|
||||
import sqlalchemy.exc
|
||||
import sqlalchemy.ext.asyncio
|
||||
import sqlalchemy.orm
|
||||
|
||||
from reflex.base import Base
|
||||
@ -21,6 +23,48 @@ from reflex.config import environment, get_config
|
||||
from reflex.utils import console
|
||||
from reflex.utils.compat import sqlmodel, sqlmodel_field_has_primary_key
|
||||
|
||||
_ENGINE: dict[str, sqlalchemy.engine.Engine] = {}
|
||||
_ASYNC_ENGINE: dict[str, sqlalchemy.ext.asyncio.AsyncEngine] = {}
|
||||
_AsyncSessionLocal: dict[str | None, sqlalchemy.ext.asyncio.async_sessionmaker] = {}
|
||||
|
||||
# Import AsyncSession _after_ reflex.utils.compat
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession # noqa: E402
|
||||
|
||||
|
||||
def _safe_db_url_for_logging(url: str) -> str:
|
||||
"""Remove username and password from the database URL for logging.
|
||||
|
||||
Args:
|
||||
url: The database URL.
|
||||
|
||||
Returns:
|
||||
The database URL with the username and password removed.
|
||||
"""
|
||||
return re.sub(r"://[^@]+@", "://<username>:<password>@", url)
|
||||
|
||||
|
||||
def get_engine_args(url: str | None = None) -> dict[str, Any]:
|
||||
"""Get the database engine arguments.
|
||||
|
||||
Args:
|
||||
url: The database url.
|
||||
|
||||
Returns:
|
||||
The database engine arguments as a dict.
|
||||
"""
|
||||
kwargs: dict[str, Any] = dict(
|
||||
# Print the SQL queries if the log level is INFO or lower.
|
||||
echo=environment.SQLALCHEMY_ECHO.get(),
|
||||
# Check connections before returning them.
|
||||
pool_pre_ping=environment.SQLALCHEMY_POOL_PRE_PING.get(),
|
||||
)
|
||||
conf = get_config()
|
||||
url = url or conf.db_url
|
||||
if url is not None and url.startswith("sqlite"):
|
||||
# Needed for the admin dash on sqlite.
|
||||
kwargs["connect_args"] = {"check_same_thread": False}
|
||||
return kwargs
|
||||
|
||||
|
||||
def get_engine(url: str | None = None) -> sqlalchemy.engine.Engine:
|
||||
"""Get the database engine.
|
||||
@ -38,15 +82,62 @@ def get_engine(url: str | None = None) -> sqlalchemy.engine.Engine:
|
||||
url = url or conf.db_url
|
||||
if url is None:
|
||||
raise ValueError("No database url configured")
|
||||
|
||||
global _ENGINE
|
||||
if url in _ENGINE:
|
||||
return _ENGINE[url]
|
||||
|
||||
if not environment.ALEMBIC_CONFIG.get().exists():
|
||||
console.warn(
|
||||
"Database is not initialized, run [bold]reflex db init[/bold] first."
|
||||
)
|
||||
# Print the SQL queries if the log level is INFO or lower.
|
||||
echo_db_query = environment.SQLALCHEMY_ECHO.get()
|
||||
# Needed for the admin dash on sqlite.
|
||||
connect_args = {"check_same_thread": False} if url.startswith("sqlite") else {}
|
||||
return sqlmodel.create_engine(url, echo=echo_db_query, connect_args=connect_args)
|
||||
_ENGINE[url] = sqlmodel.create_engine(
|
||||
url,
|
||||
**get_engine_args(url),
|
||||
)
|
||||
return _ENGINE[url]
|
||||
|
||||
|
||||
def get_async_engine(url: str | None) -> sqlalchemy.ext.asyncio.AsyncEngine:
|
||||
"""Get the async database engine.
|
||||
|
||||
Args:
|
||||
url: The database url.
|
||||
|
||||
Returns:
|
||||
The async database engine.
|
||||
|
||||
Raises:
|
||||
ValueError: If the async database url is None.
|
||||
"""
|
||||
if url is None:
|
||||
conf = get_config()
|
||||
url = conf.async_db_url
|
||||
if url is not None and conf.db_url is not None:
|
||||
async_db_url_tail = url.partition("://")[2]
|
||||
db_url_tail = conf.db_url.partition("://")[2]
|
||||
if async_db_url_tail != db_url_tail:
|
||||
console.warn(
|
||||
f"async_db_url `{_safe_db_url_for_logging(url)}` "
|
||||
"should reference the same database as "
|
||||
f"db_url `{_safe_db_url_for_logging(conf.db_url)}`."
|
||||
)
|
||||
if url is None:
|
||||
raise ValueError("No async database url configured")
|
||||
|
||||
global _ASYNC_ENGINE
|
||||
if url in _ASYNC_ENGINE:
|
||||
return _ASYNC_ENGINE[url]
|
||||
|
||||
if not environment.ALEMBIC_CONFIG.get().exists():
|
||||
console.warn(
|
||||
"Database is not initialized, run [bold]reflex db init[/bold] first."
|
||||
)
|
||||
_ASYNC_ENGINE[url] = sqlalchemy.ext.asyncio.create_async_engine(
|
||||
url,
|
||||
**get_engine_args(url),
|
||||
)
|
||||
return _ASYNC_ENGINE[url]
|
||||
|
||||
|
||||
async def get_db_status() -> bool:
|
||||
@ -425,6 +516,31 @@ def session(url: str | None = None) -> sqlmodel.Session:
|
||||
return sqlmodel.Session(get_engine(url))
|
||||
|
||||
|
||||
def asession(url: str | None = None) -> AsyncSession:
|
||||
"""Get an async sqlmodel session to interact with the database.
|
||||
|
||||
async with rx.asession() as asession:
|
||||
...
|
||||
|
||||
Most operations against the `asession` must be awaited.
|
||||
|
||||
Args:
|
||||
url: The database url.
|
||||
|
||||
Returns:
|
||||
An async database session.
|
||||
"""
|
||||
global _AsyncSessionLocal
|
||||
if url not in _AsyncSessionLocal:
|
||||
_AsyncSessionLocal[url] = sqlalchemy.ext.asyncio.async_sessionmaker(
|
||||
bind=get_async_engine(url),
|
||||
class_=AsyncSession,
|
||||
autocommit=False,
|
||||
autoflush=False,
|
||||
)
|
||||
return _AsyncSessionLocal[url]()
|
||||
|
||||
|
||||
def sqla_session(url: str | None = None) -> sqlalchemy.orm.Session:
|
||||
"""Get a bare sqlalchemy session to interact with the database.
|
||||
|
||||
|
@ -446,7 +446,7 @@ def deploy(
|
||||
list(),
|
||||
"-r",
|
||||
"--region",
|
||||
help="The regions to deploy to. `reflex apps regions` For multiple envs, repeat this option, e.g. --region sjc --region iad",
|
||||
help="The regions to deploy to. `reflex cloud regions` For multiple envs, repeat this option, e.g. --region sjc --region iad",
|
||||
),
|
||||
envs: List[str] = typer.Option(
|
||||
list(),
|
||||
@ -456,7 +456,7 @@ def deploy(
|
||||
vmtype: Optional[str] = typer.Option(
|
||||
None,
|
||||
"--vmtype",
|
||||
help="Vm type id. Run `reflex apps vmtypes` to get options.",
|
||||
help="Vm type id. Run `reflex cloud vmtypes` to get options.",
|
||||
),
|
||||
hostname: Optional[str] = typer.Option(
|
||||
None,
|
||||
|
@ -97,6 +97,7 @@ from reflex.utils.exceptions import (
|
||||
ReflexRuntimeError,
|
||||
SetUndefinedStateVarError,
|
||||
StateSchemaMismatchError,
|
||||
StateSerializationError,
|
||||
StateTooLargeError,
|
||||
)
|
||||
from reflex.utils.exec import is_testing_env
|
||||
@ -104,6 +105,7 @@ from reflex.utils.serializers import serializer
|
||||
from reflex.utils.types import (
|
||||
_isinstance,
|
||||
get_origin,
|
||||
is_optional,
|
||||
is_union,
|
||||
override,
|
||||
value_inside_optional,
|
||||
@ -278,6 +280,22 @@ if TYPE_CHECKING:
|
||||
from pydantic.v1.fields import ModelField
|
||||
|
||||
|
||||
def _unwrap_field_type(type_: Type) -> Type:
|
||||
"""Unwrap rx.Field type annotations.
|
||||
|
||||
Args:
|
||||
type_: The type to unwrap.
|
||||
|
||||
Returns:
|
||||
The unwrapped type.
|
||||
"""
|
||||
from reflex.vars import Field
|
||||
|
||||
if get_origin(type_) is Field:
|
||||
return get_args(type_)[0]
|
||||
return type_
|
||||
|
||||
|
||||
def get_var_for_field(cls: Type[BaseState], f: ModelField):
|
||||
"""Get a Var instance for a Pydantic field.
|
||||
|
||||
@ -288,16 +306,12 @@ def get_var_for_field(cls: Type[BaseState], f: ModelField):
|
||||
Returns:
|
||||
The Var instance.
|
||||
"""
|
||||
from reflex.vars import Field
|
||||
|
||||
field_name = format.format_state_name(cls.get_full_name()) + "." + f.name
|
||||
|
||||
return dispatch(
|
||||
field_name=field_name,
|
||||
var_data=VarData.from_state(cls, f.name),
|
||||
result_var_type=f.outer_type_
|
||||
if get_origin(f.outer_type_) is not Field
|
||||
else get_args(f.outer_type_)[0],
|
||||
result_var_type=_unwrap_field_type(f.outer_type_),
|
||||
)
|
||||
|
||||
|
||||
@ -425,7 +439,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
Returns:
|
||||
The string representation of the state.
|
||||
"""
|
||||
return f"{self.__class__.__name__}({self.dict()})"
|
||||
return f"{type(self).__name__}({self.dict()})"
|
||||
|
||||
@classmethod
|
||||
def _get_computed_vars(cls) -> list[ComputedVar]:
|
||||
@ -436,7 +450,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
"""
|
||||
return [
|
||||
v
|
||||
for mixin in cls._mixins() + [cls]
|
||||
for mixin in [*cls._mixins(), cls]
|
||||
for name, v in mixin.__dict__.items()
|
||||
if is_computed_var(v) and name not in cls.inherited_vars
|
||||
]
|
||||
@ -1288,6 +1302,9 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
return
|
||||
|
||||
if name in self.backend_vars:
|
||||
# abort if unchanged
|
||||
if self._backend_vars.get(name) == value:
|
||||
return
|
||||
self._backend_vars.__setitem__(name, value)
|
||||
self.dirty_vars.add(name)
|
||||
self._mark_dirty()
|
||||
@ -1310,8 +1327,8 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
|
||||
if name in fields:
|
||||
field = fields[name]
|
||||
field_type = field.outer_type_
|
||||
if field.allow_none:
|
||||
field_type = _unwrap_field_type(field.outer_type_)
|
||||
if field.allow_none and not is_optional(field_type):
|
||||
field_type = Union[field_type, None]
|
||||
if not _isinstance(value, field_type):
|
||||
console.deprecate(
|
||||
@ -2193,8 +2210,12 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
|
||||
Returns:
|
||||
The serialized state.
|
||||
|
||||
Raises:
|
||||
StateSerializationError: If the state cannot be serialized.
|
||||
"""
|
||||
payload = b""
|
||||
error = ""
|
||||
try:
|
||||
payload = pickle.dumps((self._to_schema(), self))
|
||||
except HANDLED_PICKLE_ERRORS as og_pickle_error:
|
||||
@ -2214,8 +2235,13 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
except HANDLED_PICKLE_ERRORS as ex:
|
||||
error += f"Dill was also unable to pickle the state: {ex}"
|
||||
console.warn(error)
|
||||
|
||||
if environment.REFLEX_PERF_MODE.get() != PerformanceMode.OFF:
|
||||
self._check_state_size(len(payload))
|
||||
|
||||
if not payload:
|
||||
raise StateSerializationError(error)
|
||||
|
||||
return payload
|
||||
|
||||
@classmethod
|
||||
@ -3612,6 +3638,14 @@ class MutableProxy(wrapt.ObjectProxy):
|
||||
self._self_state = state
|
||||
self._self_field_name = field_name
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""Get the representation of the wrapped object.
|
||||
|
||||
Returns:
|
||||
The representation of the wrapped object.
|
||||
"""
|
||||
return f"{type(self).__name__}({self.__wrapped__})"
|
||||
|
||||
def _mark_dirty(
|
||||
self,
|
||||
wrapped=None,
|
||||
|
@ -74,7 +74,7 @@ def set_color_mode(
|
||||
new_color_mode = LiteralVar.create(new_color_mode)
|
||||
|
||||
return Var(
|
||||
f"() => {str(base_setter)}({str(new_color_mode)})",
|
||||
f"() => {base_setter!s}({new_color_mode!s})",
|
||||
_var_data=VarData.merge(
|
||||
base_setter._get_all_var_data(), new_color_mode._get_all_var_data()
|
||||
),
|
||||
@ -138,9 +138,6 @@ def convert_item(
|
||||
if isinstance(style_item, Var):
|
||||
return style_item, style_item._get_all_var_data()
|
||||
|
||||
# if isinstance(style_item, str) and REFLEX_VAR_OPENING_TAG not in style_item:
|
||||
# return style_item, None
|
||||
|
||||
# Otherwise, convert to Var to collapse VarData encoded in f-string.
|
||||
new_var = LiteralVar.create(style_item)
|
||||
var_data = new_var._get_all_var_data() if new_var is not None else None
|
||||
|
@ -206,7 +206,7 @@ class AppHarness:
|
||||
The full state name
|
||||
"""
|
||||
# NOTE: using State.get_name() somehow causes trouble here
|
||||
# path = [State.get_name()] + [self.get_state_name(p) for p in path]
|
||||
# path = [State.get_name()] + [self.get_state_name(p) for p in path] # noqa: ERA001
|
||||
path = ["reflex___state____state"] + [self.get_state_name(p) for p in path]
|
||||
return ".".join(path)
|
||||
|
||||
@ -436,7 +436,6 @@ class AppHarness:
|
||||
|
||||
Returns:
|
||||
The rendered app global code.
|
||||
|
||||
"""
|
||||
if not inspect.isclass(value) and not inspect.isfunction(value):
|
||||
return f"{key} = {value!r}"
|
||||
@ -879,7 +878,7 @@ class Subdir404TCPServer(socketserver.TCPServer):
|
||||
|
||||
Args:
|
||||
request: the requesting socket
|
||||
client_address: (host, port) referring to the client’s address.
|
||||
client_address: (host, port) referring to the client's address.
|
||||
"""
|
||||
self.RequestHandlerClass(
|
||||
request,
|
||||
|
@ -63,6 +63,10 @@ class UploadValueError(ReflexError, ValueError):
|
||||
"""Custom ValueError for upload related errors."""
|
||||
|
||||
|
||||
class PageValueError(ReflexError, ValueError):
|
||||
"""Custom ValueError for page related errors."""
|
||||
|
||||
|
||||
class RouteValueError(ReflexError, ValueError):
|
||||
"""Custom ValueError for route related errors."""
|
||||
|
||||
@ -155,6 +159,10 @@ class StateTooLargeError(ReflexError):
|
||||
"""Raised when the state is too large to be serialized."""
|
||||
|
||||
|
||||
class StateSerializationError(ReflexError):
|
||||
"""Raised when the state cannot be serialized."""
|
||||
|
||||
|
||||
class SystemPackageMissingError(ReflexError):
|
||||
"""Raised when a system package is missing."""
|
||||
|
||||
|
@ -206,7 +206,9 @@ def get_granian_target():
|
||||
|
||||
app_module_path = Path(reflex.__file__).parent / "app_module_for_backend.py"
|
||||
|
||||
return f"{str(app_module_path)}:{constants.CompileVars.APP}.{constants.CompileVars.API}"
|
||||
return (
|
||||
f"{app_module_path!s}:{constants.CompileVars.APP}.{constants.CompileVars.API}"
|
||||
)
|
||||
|
||||
|
||||
def run_backend(
|
||||
@ -440,10 +442,8 @@ def output_system_info():
|
||||
|
||||
system = platform.system()
|
||||
|
||||
if (
|
||||
system != "Windows"
|
||||
or system == "Windows"
|
||||
and prerequisites.is_windows_bun_supported()
|
||||
if system != "Windows" or (
|
||||
system == "Windows" and prerequisites.is_windows_bun_supported()
|
||||
):
|
||||
dependencies.extend(
|
||||
[
|
||||
|
@ -329,12 +329,12 @@ def format_match(
|
||||
return_value = case[-1]
|
||||
|
||||
case_conditions = " ".join(
|
||||
[f"case JSON.stringify({str(condition)}):" for condition in conditions]
|
||||
[f"case JSON.stringify({condition!s}):" for condition in conditions]
|
||||
)
|
||||
case_code = f"{case_conditions} return ({str(return_value)}); break;"
|
||||
case_code = f"{case_conditions} return ({return_value!s}); break;"
|
||||
switch_code += case_code
|
||||
|
||||
switch_code += f"default: return ({str(default)}); break;"
|
||||
switch_code += f"default: return ({default!s}); break;"
|
||||
switch_code += "};})()"
|
||||
|
||||
return switch_code
|
||||
@ -413,7 +413,7 @@ def format_props(*single_props, **key_value_props) -> list[str]:
|
||||
)
|
||||
for name, prop in sorted(key_value_props.items())
|
||||
if prop is not None
|
||||
] + [(f"{str(LiteralVar.create(prop))}") for prop in single_props]
|
||||
] + [(f"{LiteralVar.create(prop)!s}") for prop in single_props]
|
||||
|
||||
|
||||
def get_event_handler_parts(handler: EventHandler) -> tuple[str, str]:
|
||||
@ -664,18 +664,22 @@ def format_library_name(library_fullname: str):
|
||||
return lib
|
||||
|
||||
|
||||
def json_dumps(obj: Any) -> str:
|
||||
def json_dumps(obj: Any, **kwargs) -> str:
|
||||
"""Takes an object and returns a jsonified string.
|
||||
|
||||
Args:
|
||||
obj: The object to be serialized.
|
||||
kwargs: Additional keyword arguments to pass to json.dumps.
|
||||
|
||||
Returns:
|
||||
A string
|
||||
"""
|
||||
from reflex.utils import serializers
|
||||
|
||||
return json.dumps(obj, ensure_ascii=False, default=serializers.serialize)
|
||||
kwargs.setdefault("ensure_ascii", False)
|
||||
kwargs.setdefault("default", serializers.serialize)
|
||||
|
||||
return json.dumps(obj, **kwargs)
|
||||
|
||||
|
||||
def collect_form_dict_names(form_dict: dict[str, Any]) -> dict[str, Any]:
|
||||
@ -712,8 +716,7 @@ def format_array_ref(refs: str, idx: Var | None) -> str:
|
||||
"""
|
||||
clean_ref = re.sub(r"[^\w]+", "_", refs)
|
||||
if idx is not None:
|
||||
# idx._var_is_local = True
|
||||
return f"refs_{clean_ref}[{str(idx)}]"
|
||||
return f"refs_{clean_ref}[{idx!s}]"
|
||||
return f"refs_{clean_ref}"
|
||||
|
||||
|
||||
|
@ -219,9 +219,8 @@ def get_install_package_manager(on_failure_return_none: bool = False) -> str | N
|
||||
Returns:
|
||||
The path to the package manager.
|
||||
"""
|
||||
if (
|
||||
constants.IS_WINDOWS
|
||||
and not is_windows_bun_supported()
|
||||
if constants.IS_WINDOWS and (
|
||||
not is_windows_bun_supported()
|
||||
or windows_check_onedrive_in_path()
|
||||
or windows_npm_escape_hatch()
|
||||
):
|
||||
@ -496,7 +495,7 @@ def initialize_requirements_txt():
|
||||
try:
|
||||
other_requirements_exist = False
|
||||
with open(fp, "r", encoding=encoding) as f:
|
||||
for req in f.readlines():
|
||||
for req in f:
|
||||
# Check if we have a package name that is reflex
|
||||
if re.match(r"^reflex[^a-zA-Z0-9]", req):
|
||||
console.debug(f"{fp} already has reflex as dependency.")
|
||||
@ -834,7 +833,7 @@ def install_bun():
|
||||
"""Install bun onto the user's system."""
|
||||
win_supported = is_windows_bun_supported()
|
||||
one_drive_in_path = windows_check_onedrive_in_path()
|
||||
if constants.IS_WINDOWS and not win_supported or one_drive_in_path:
|
||||
if constants.IS_WINDOWS and (not win_supported or one_drive_in_path):
|
||||
if not win_supported:
|
||||
console.warn(
|
||||
"Bun for Windows is currently only available for x86 64-bit Windows. Installation will fall back on npm."
|
||||
@ -926,7 +925,7 @@ def cached_procedure(cache_file: str, payload_fn: Callable[..., str]):
|
||||
|
||||
@cached_procedure(
|
||||
cache_file=str(get_web_dir() / "reflex.install_frontend_packages.cached"),
|
||||
payload_fn=lambda p, c: f"{repr(sorted(list(p)))},{c.json()}",
|
||||
payload_fn=lambda p, c: f"{sorted(list(p))!r},{c.json()}",
|
||||
)
|
||||
def install_frontend_packages(packages: set[str], config: Config):
|
||||
"""Installs the base and custom frontend packages.
|
||||
@ -946,9 +945,12 @@ def install_frontend_packages(packages: set[str], config: Config):
|
||||
get_package_manager(on_failure_return_none=True)
|
||||
if (
|
||||
not constants.IS_WINDOWS
|
||||
or constants.IS_WINDOWS
|
||||
and is_windows_bun_supported()
|
||||
and not windows_check_onedrive_in_path()
|
||||
or (
|
||||
constants.IS_WINDOWS
|
||||
and (
|
||||
is_windows_bun_supported() and not windows_check_onedrive_in_path()
|
||||
)
|
||||
)
|
||||
)
|
||||
else None
|
||||
)
|
||||
|
@ -364,7 +364,7 @@ def get_command_with_loglevel(command: list[str]) -> list[str]:
|
||||
npm_path = str(Path(npm_path).resolve()) if npm_path else npm_path
|
||||
|
||||
if command[0] == npm_path:
|
||||
return command + ["--loglevel", "silly"]
|
||||
return [*command, "--loglevel", "silly"]
|
||||
return command
|
||||
|
||||
|
||||
|
@ -24,7 +24,7 @@ from reflex.vars.base import Var
|
||||
|
||||
logger = logging.getLogger("pyi_generator")
|
||||
|
||||
PWD = Path(".").resolve()
|
||||
PWD = Path.cwd()
|
||||
|
||||
EXCLUDED_FILES = [
|
||||
"app.py",
|
||||
@ -196,12 +196,7 @@ def _get_type_hint(value, type_hint_globals, is_optional=True) -> str:
|
||||
elif isinstance(value, str):
|
||||
ev = eval(value, type_hint_globals)
|
||||
if rx_types.is_optional(ev):
|
||||
# hints = {
|
||||
# _get_type_hint(arg, type_hint_globals, is_optional=False)
|
||||
# for arg in ev.__args__
|
||||
# }
|
||||
return _get_type_hint(ev, type_hint_globals, is_optional=False)
|
||||
# return f"Optional[{', '.join(hints)}]"
|
||||
|
||||
if rx_types.is_union(ev):
|
||||
res = [
|
||||
@ -260,8 +255,15 @@ def _generate_docstrings(clzs: list[Type[Component]], props: list[str]) -> str:
|
||||
# We've reached the functions, so stop.
|
||||
break
|
||||
|
||||
if line == "":
|
||||
# We hit a blank line, so clear comments to avoid commented out prop appearing in next prop docs.
|
||||
comments.clear()
|
||||
continue
|
||||
|
||||
# Get comments for prop
|
||||
if line.strip().startswith("#"):
|
||||
# Remove noqa from the comments.
|
||||
line = line.partition(" # noqa")[0]
|
||||
comments.append(line)
|
||||
continue
|
||||
|
||||
@ -835,7 +837,7 @@ class StubGenerator(ast.NodeTransformer):
|
||||
self.inserted_imports = True
|
||||
default_imports = _generate_imports(self.typing_imports)
|
||||
self.import_statements.extend(ast.unparse(i) for i in default_imports)
|
||||
return default_imports + [node]
|
||||
return [*default_imports, node]
|
||||
return node
|
||||
|
||||
def visit_ImportFrom(
|
||||
|
@ -97,7 +97,6 @@ StateIterVar = Union[list, set, tuple]
|
||||
if TYPE_CHECKING:
|
||||
from reflex.vars.base import Var
|
||||
|
||||
# ArgsSpec = Callable[[Var], list[Var]]
|
||||
ArgsSpec = (
|
||||
Callable[[], Sequence[Var]]
|
||||
| Callable[[Var], Sequence[Var]]
|
||||
@ -331,7 +330,11 @@ def get_attribute_access_type(cls: GenericType, name: str) -> GenericType | None
|
||||
type_ = field.outer_type_
|
||||
if isinstance(type_, ModelField):
|
||||
type_ = type_.type_
|
||||
if not field.required and field.default is None:
|
||||
if (
|
||||
not field.required
|
||||
and field.default is None
|
||||
and field.default_factory is None
|
||||
):
|
||||
# Ensure frontend uses null coalescing when accessing.
|
||||
type_ = Optional[type_]
|
||||
return type_
|
||||
@ -783,7 +786,7 @@ def validate_literal(key: str, value: Any, expected_type: Type, comp_name: str):
|
||||
)
|
||||
value_str = f"'{value}'" if isinstance(value, str) else value
|
||||
raise ValueError(
|
||||
f"prop value for {str(key)} of the `{comp_name}` component should be one of the following: {allowed_value_str}. Got {value_str} instead"
|
||||
f"prop value for {key!s} of the `{comp_name}` component should be one of the following: {allowed_value_str}. Got {value_str} instead"
|
||||
)
|
||||
|
||||
|
||||
|
@ -1057,7 +1057,7 @@ class Var(Generic[VAR_TYPE]):
|
||||
|
||||
if self._var_type is Any:
|
||||
raise TypeError(
|
||||
f"You must provide an annotation for the state var `{str(self)}`. Annotation cannot be `{self._var_type}`."
|
||||
f"You must provide an annotation for the state var `{self!s}`. Annotation cannot be `{self._var_type}`."
|
||||
)
|
||||
|
||||
if name in REPLACED_NAMES:
|
||||
@ -1569,7 +1569,7 @@ class CachedVarOperation:
|
||||
if name == "_js_expr":
|
||||
return self._cached_var_name
|
||||
|
||||
parent_classes = inspect.getmro(self.__class__)
|
||||
parent_classes = inspect.getmro(type(self))
|
||||
|
||||
next_class = parent_classes[parent_classes.index(CachedVarOperation) + 1]
|
||||
|
||||
@ -1611,7 +1611,7 @@ class CachedVarOperation:
|
||||
"""
|
||||
return hash(
|
||||
(
|
||||
self.__class__.__name__,
|
||||
type(self).__name__,
|
||||
*[
|
||||
getattr(self, field.name)
|
||||
for field in dataclasses.fields(self) # type: ignore
|
||||
@ -1733,7 +1733,7 @@ class CallableVar(Var):
|
||||
Returns:
|
||||
The hash of the object.
|
||||
"""
|
||||
return hash((self.__class__.__name__, self.original_var))
|
||||
return hash((type(self).__name__, self.original_var))
|
||||
|
||||
|
||||
RETURN_TYPE = TypeVar("RETURN_TYPE")
|
||||
@ -2117,7 +2117,7 @@ class ComputedVar(Var[RETURN_TYPE]):
|
||||
ref_obj = None
|
||||
if instruction.argval in invalid_names:
|
||||
raise VarValueError(
|
||||
f"Cached var {str(self)} cannot access arbitrary state via `{instruction.argval}`."
|
||||
f"Cached var {self!s} cannot access arbitrary state via `{instruction.argval}`."
|
||||
)
|
||||
if callable(ref_obj):
|
||||
# recurse into callable attributes
|
||||
@ -2492,7 +2492,7 @@ class StateOperation(CachedVarOperation, Var):
|
||||
Returns:
|
||||
The cached var name.
|
||||
"""
|
||||
return f"{str(self._state_name)}.{str(self._field)}"
|
||||
return f"{self._state_name!s}.{self._field!s}"
|
||||
|
||||
def __getattr__(self, name: str) -> Any:
|
||||
"""Get an attribute of the var.
|
||||
@ -2804,9 +2804,9 @@ def dispatch(
|
||||
|
||||
if result_origin_var_type in dispatchers:
|
||||
fn = dispatchers[result_origin_var_type]
|
||||
fn_first_arg_type = list(inspect.signature(fn).parameters.values())[
|
||||
0
|
||||
].annotation
|
||||
fn_first_arg_type = next(
|
||||
iter(inspect.signature(fn).parameters.values())
|
||||
).annotation
|
||||
|
||||
fn_return = inspect.signature(fn).return_annotation
|
||||
|
||||
|
@ -240,7 +240,7 @@ class VarOperationCall(Generic[P, R], CachedVarOperation, Var[R]):
|
||||
Returns:
|
||||
The name of the var.
|
||||
"""
|
||||
return f"({str(self._func)}({', '.join([str(LiteralVar.create(arg)) for arg in self._args])}))"
|
||||
return f"({self._func!s}({', '.join([str(LiteralVar.create(arg)) for arg in self._args])}))"
|
||||
|
||||
@cached_property_no_lock
|
||||
def _cached_get_all_var_data(self) -> VarData | None:
|
||||
|
@ -1012,7 +1012,7 @@ class LiteralNumberVar(LiteralVar, NumberVar):
|
||||
Returns:
|
||||
int: The hash value of the object.
|
||||
"""
|
||||
return hash((self.__class__.__name__, self._var_value))
|
||||
return hash((type(self).__name__, self._var_value))
|
||||
|
||||
@classmethod
|
||||
def create(cls, value: float | int, _var_data: VarData | None = None):
|
||||
@ -1064,7 +1064,7 @@ class LiteralBooleanVar(LiteralVar, BooleanVar):
|
||||
Returns:
|
||||
int: The hash value of the object.
|
||||
"""
|
||||
return hash((self.__class__.__name__, self._var_value))
|
||||
return hash((type(self).__name__, self._var_value))
|
||||
|
||||
@classmethod
|
||||
def create(cls, value: bool, _var_data: VarData | None = None):
|
||||
|
@ -272,7 +272,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
|
||||
attribute_type = get_attribute_access_type(var_type, name)
|
||||
if attribute_type is None:
|
||||
raise VarAttributeError(
|
||||
f"The State var `{str(self)}` has no attribute '{name}' or may have been annotated "
|
||||
f"The State var `{self!s}` has no attribute '{name}' or may have been annotated "
|
||||
f"wrongly."
|
||||
)
|
||||
return ObjectItemOperation.create(self, name, attribute_type).guess_type()
|
||||
@ -332,7 +332,7 @@ class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
|
||||
"({ "
|
||||
+ ", ".join(
|
||||
[
|
||||
f"[{str(LiteralVar.create(key))}] : {str(LiteralVar.create(value))}"
|
||||
f"[{LiteralVar.create(key)!s}] : {LiteralVar.create(value)!s}"
|
||||
for key, value in self._var_value.items()
|
||||
]
|
||||
)
|
||||
@ -362,7 +362,7 @@ class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
|
||||
Returns:
|
||||
The hash of the var.
|
||||
"""
|
||||
return hash((self.__class__.__name__, self._js_expr))
|
||||
return hash((type(self).__name__, self._js_expr))
|
||||
|
||||
@cached_property_no_lock
|
||||
def _cached_get_all_var_data(self) -> VarData | None:
|
||||
@ -494,8 +494,8 @@ class ObjectItemOperation(CachedVarOperation, Var):
|
||||
The name of the operation.
|
||||
"""
|
||||
if types.is_optional(self._object._var_type):
|
||||
return f"{str(self._object)}?.[{str(self._key)}]"
|
||||
return f"{str(self._object)}[{str(self._key)}]"
|
||||
return f"{self._object!s}?.[{self._key!s}]"
|
||||
return f"{self._object!s}[{self._key!s}]"
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
|
@ -667,7 +667,7 @@ class LiteralStringVar(LiteralVar, StringVar[str]):
|
||||
Returns:
|
||||
The hash of the var.
|
||||
"""
|
||||
return hash((self.__class__.__name__, self._var_value))
|
||||
return hash((type(self).__name__, self._var_value))
|
||||
|
||||
def json(self) -> str:
|
||||
"""Get the JSON representation of the var.
|
||||
@ -1349,7 +1349,7 @@ class ArraySliceOperation(CachedVarOperation, ArrayVar):
|
||||
LiteralVar.create(end) if end is not None else Var(_js_expr="undefined")
|
||||
)
|
||||
if step is None:
|
||||
return f"{str(self._array)}.slice({str(normalized_start)}, {str(normalized_end)})"
|
||||
return f"{self._array!s}.slice({normalized_start!s}, {normalized_end!s})"
|
||||
if not isinstance(step, Var):
|
||||
if step < 0:
|
||||
actual_start = end + 1 if end is not None else 0
|
||||
@ -1357,12 +1357,12 @@ class ArraySliceOperation(CachedVarOperation, ArrayVar):
|
||||
return str(self._array[actual_start:actual_end].reverse()[::-step])
|
||||
if step == 0:
|
||||
raise ValueError("slice step cannot be zero")
|
||||
return f"{str(self._array)}.slice({str(normalized_start)}, {str(normalized_end)}).filter((_, i) => i % {str(step)} === 0)"
|
||||
return f"{self._array!s}.slice({normalized_start!s}, {normalized_end!s}).filter((_, i) => i % {step!s} === 0)"
|
||||
|
||||
actual_start_reverse = end + 1 if end is not None else 0
|
||||
actual_end_reverse = start + 1 if start is not None else self._array.length()
|
||||
|
||||
return f"{str(self.step)} > 0 ? {str(self._array)}.slice({str(normalized_start)}, {str(normalized_end)}).filter((_, i) => i % {str(step)} === 0) : {str(self._array)}.slice({str(actual_start_reverse)}, {str(actual_end_reverse)}).reverse().filter((_, i) => i % {str(-step)} === 0)"
|
||||
return f"{self.step!s} > 0 ? {self._array!s}.slice({normalized_start!s}, {normalized_end!s}).filter((_, i) => i % {step!s} === 0) : {self._array!s}.slice({actual_start_reverse!s}, {actual_end_reverse!s}).reverse().filter((_, i) => i % {-step!s} === 0)"
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
@ -1535,7 +1535,7 @@ def array_item_operation(array: ArrayVar, index: NumberVar | int):
|
||||
element_type = unionize(*args)
|
||||
|
||||
return var_operation_return(
|
||||
js_expression=f"{str(array)}.at({str(index)})",
|
||||
js_expression=f"{array!s}.at({index!s})",
|
||||
var_type=element_type,
|
||||
)
|
||||
|
||||
@ -1555,7 +1555,7 @@ def array_range_operation(
|
||||
The range of numbers.
|
||||
"""
|
||||
return var_operation_return(
|
||||
js_expression=f"Array.from({{ length: ({str(stop)} - {str(start)}) / {str(step)} }}, (_, i) => {str(start)} + i * {str(step)})",
|
||||
js_expression=f"Array.from({{ length: ({stop!s} - {start!s}) / {step!s} }}, (_, i) => {start!s} + i * {step!s})",
|
||||
var_type=List[int],
|
||||
)
|
||||
|
||||
|
@ -160,7 +160,7 @@ def CallScript():
|
||||
@rx.event
|
||||
def call_with_var_str_cast(self):
|
||||
return rx.call_script(
|
||||
f"{str(rx.Var('inline_counter'))} + {str(rx.Var('external_counter'))}",
|
||||
f"{rx.Var('inline_counter')!s} + {rx.Var('external_counter')!s}",
|
||||
callback=CallScriptState.set_last_result, # type: ignore
|
||||
)
|
||||
|
||||
@ -175,7 +175,7 @@ def CallScript():
|
||||
def call_with_var_str_cast_wrapped(self):
|
||||
return rx.call_script(
|
||||
rx.Var(
|
||||
f"{str(rx.Var('inline_counter'))} + {str(rx.Var('external_counter'))}"
|
||||
f"{rx.Var('inline_counter')!s} + {rx.Var('external_counter')!s}"
|
||||
),
|
||||
callback=CallScriptState.set_last_result, # type: ignore
|
||||
)
|
||||
@ -315,7 +315,7 @@ def CallScript():
|
||||
rx.button(
|
||||
"call_with_var_str_cast_inline",
|
||||
on_click=rx.call_script(
|
||||
f"{str(rx.Var('inline_counter'))} + {str(rx.Var('external_counter'))}",
|
||||
f"{rx.Var('inline_counter')!s} + {rx.Var('external_counter')!s}",
|
||||
callback=CallScriptState.set_last_result, # type: ignore
|
||||
),
|
||||
id="call_with_var_str_cast_inline",
|
||||
@ -334,7 +334,7 @@ def CallScript():
|
||||
"call_with_var_str_cast_wrapped_inline",
|
||||
on_click=rx.call_script(
|
||||
rx.Var(
|
||||
f"{str(rx.Var('inline_counter'))} + {str(rx.Var('external_counter'))}"
|
||||
f"{rx.Var('inline_counter')!s} + {rx.Var('external_counter')!s}"
|
||||
),
|
||||
callback=CallScriptState.set_last_result, # type: ignore
|
||||
),
|
||||
|
@ -106,7 +106,6 @@ def ComputedVars():
|
||||
),
|
||||
)
|
||||
|
||||
# raise Exception(State.count3._deps(objclass=State))
|
||||
app = rx.App()
|
||||
app.add_page(index)
|
||||
|
||||
|
@ -183,6 +183,6 @@ async def test_fully_controlled_input(fully_controlled_input: AppHarness):
|
||||
clear_button.click()
|
||||
assert AppHarness._poll_for(lambda: on_change_input.get_attribute("value") == "")
|
||||
# potential bug: clearing the on_change field doesn't itself trigger on_change
|
||||
# assert backend_state.text == ""
|
||||
# assert debounce_input.get_attribute("value") == ""
|
||||
# assert value_input.get_attribute("value") == ""
|
||||
# assert backend_state.text == "" #noqa: ERA001
|
||||
# assert debounce_input.get_attribute("value") == "" #noqa: ERA001
|
||||
# assert value_input.get_attribute("value") == "" #noqa: ERA001
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user