Compare commits
193 Commits
sweep/bug_
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c754da978 | ||
|
|
74306c77c6 | ||
|
|
2b91e26dca | ||
|
|
113312115c | ||
|
|
242fac4a07 | ||
|
|
12d36c6c68 | ||
|
|
11c1cf3839 | ||
|
|
95d3c85c8f | ||
|
|
c2183af5c3 | ||
|
|
ee354ff0ba | ||
|
|
57a72db354 | ||
|
|
7402590f85 | ||
|
|
8e7de57813 | ||
|
|
70b74934bf | ||
|
|
9163aade66 | ||
|
|
40859efe37 | ||
|
|
b94dd89eb4 | ||
|
|
887d5339d2 | ||
|
|
9dd6b7c264 | ||
|
|
92f43f4da6 | ||
|
|
bb9a1b1223 | ||
|
|
91ec1faafb | ||
|
|
00a0f4d106 | ||
|
|
8b66f33b1f | ||
|
|
ef9d2fcf99 | ||
|
|
b578af5a06 | ||
|
|
798d2dcf37 | ||
|
|
b14a527640 | ||
|
|
9c3f836cc7 | ||
|
|
774d5e2108 | ||
|
|
8e332a69d2 | ||
|
|
69fc6f85dc | ||
|
|
7b06ddfb9d | ||
|
|
80833600eb | ||
|
|
1c6f744c13 | ||
|
|
93f7b1ddbc | ||
|
|
68bcc230c4 | ||
|
|
1dfe3bf159 | ||
|
|
0f31fa9138 | ||
|
|
4df44ef650 | ||
|
|
a4dc56ab90 | ||
|
|
53f2496988 | ||
|
|
3c6c94dc12 | ||
|
|
f029358942 | ||
|
|
97e5b37339 | ||
|
|
c2a6d42d62 | ||
|
|
1e7273f323 | ||
|
|
23e051b6b3 | ||
|
|
c956bca8fe | ||
|
|
36b3f104ff | ||
|
|
e5c61d5da3 | ||
|
|
b19ce0b83a | ||
|
|
9612ef93a1 | ||
|
|
97ae4741a7 | ||
|
|
b5f07aa158 | ||
|
|
91ac3886c8 | ||
|
|
d48fc7dd16 | ||
|
|
0dc3097d59 | ||
|
|
5e8809774a | ||
|
|
9b8883b95d | ||
|
|
0936005954 | ||
|
|
d24b253347 | ||
|
|
74b1699e2b | ||
|
|
2cb2402bb3 | ||
|
|
d039269a70 | ||
|
|
fd1b5a8beb | ||
|
|
46dca83fe1 | ||
|
|
f0d522b59b | ||
|
|
31364016f9 | ||
|
|
03514a128d | ||
|
|
5fb8a2e2a6 | ||
|
|
3b113a2a54 | ||
|
|
5cdaf38d57 | ||
|
|
d50b8fee54 | ||
|
|
c3e791533b | ||
|
|
3375040dfb | ||
|
|
c4b6cef52a | ||
|
|
d37605ba5d | ||
|
|
60ce166580 | ||
|
|
e4ae2e25ed | ||
|
|
0538f60889 | ||
|
|
3e20c80392 | ||
|
|
9977bf62ab | ||
|
|
47792bd6e1 | ||
|
|
946e60b02f | ||
|
|
4e75de3b2c | ||
|
|
d1809135ea | ||
|
|
c3501327af | ||
|
|
af53d08eb1 | ||
|
|
6df7d561e5 | ||
|
|
f8d1a137ea | ||
|
|
c7fcb89020 | ||
|
|
1c6a0770c3 | ||
|
|
f888c3c9ff | ||
|
|
87be75832a | ||
|
|
88df852be3 | ||
|
|
aaa1596703 | ||
|
|
1cc58cd4b1 | ||
|
|
19d55bc61d | ||
|
|
843cacd8a0 | ||
|
|
ebe217ea92 | ||
|
|
dcb0c417ec | ||
|
|
ba0f14a9fc | ||
|
|
3322cc1610 | ||
|
|
ba3de805f4 | ||
|
|
c63f91ad4f | ||
|
|
00b86643e9 | ||
|
|
3acfdbb6be | ||
|
|
d33961744f | ||
|
|
8fbd209c1c | ||
|
|
e00c8bc587 | ||
|
|
4f063d2050 | ||
|
|
816814389a | ||
|
|
39581b28d1 | ||
|
|
2767649197 | ||
|
|
79502146dc | ||
|
|
3fae443357 | ||
|
|
ba78377b54 | ||
|
|
8d23cee4bf | ||
|
|
ecde63630a | ||
|
|
d0d394a5ec | ||
|
|
27acfe039c | ||
|
|
f6f46bb6eb | ||
|
|
c4ac908baa | ||
|
|
0a2010c841 | ||
|
|
b8c35abe9b | ||
|
|
fcf10c499f | ||
|
|
7a04540ddd | ||
|
|
7b4517c86a | ||
|
|
8cdcbfd8f5 | ||
|
|
b5cb9c53bf | ||
|
|
28d5dc59fd | ||
|
|
d06e6f8936 | ||
|
|
6d02e10899 | ||
|
|
a8a34bba42 | ||
|
|
5802c6c5a0 | ||
|
|
e7800f218d | ||
|
|
d846f73abb | ||
|
|
e705851ded | ||
|
|
bc9bed277c | ||
|
|
4b9e538f2c | ||
|
|
c7903184e2 | ||
|
|
4059c4bac7 | ||
|
|
0c7e12ab83 | ||
|
|
bcecb0ef29 | ||
|
|
da6f83003b | ||
|
|
1342441b8f | ||
|
|
fd4cdaf1ce | ||
|
|
0c59eb9714 | ||
|
|
7a39c61b60 | ||
|
|
2b0645b6ac | ||
|
|
99605863c8 | ||
|
|
0141ade134 | ||
|
|
f2272f2386 | ||
|
|
4724d1ce1c | ||
|
|
63bdc70f1d | ||
|
|
30bc410d8b | ||
|
|
80e8196b8d | ||
|
|
020f4c6684 | ||
|
|
df60518e93 | ||
|
|
cd53d5c5ce | ||
|
|
5ebca213b4 | ||
|
|
22a3bdf86e | ||
|
|
f120d2a257 | ||
|
|
dda9efbbb3 | ||
|
|
d9de45996e | ||
|
|
dd97962b11 | ||
|
|
eef97ac4cf | ||
|
|
d616c0a45e | ||
|
|
223d4142fa | ||
|
|
3b6266d7de | ||
|
|
3aa2853217 | ||
|
|
18d4dcbfe4 | ||
|
|
7cd0cacc62 | ||
|
|
04d5f04489 | ||
|
|
e721df7a40 | ||
|
|
fa1c3065b2 | ||
|
|
db5855ed86 | ||
|
|
f0afb16d19 | ||
|
|
aa86b5a705 | ||
|
|
9adbeb9797 | ||
|
|
410aca65d3 | ||
|
|
a762906612 | ||
|
|
846fcbd1f0 | ||
|
|
89c7866bf7 | ||
|
|
0e2e48bde4 | ||
|
|
0fcd36eaa4 | ||
|
|
4ee39716b0 | ||
|
|
d2b251164e | ||
|
|
bff2f8ca0a | ||
|
|
89fe141e24 | ||
|
|
eff47925be | ||
|
|
7151af023f |
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -52,6 +52,7 @@ jobs:
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
cache: 'pip' # caching pip dependencies
|
||||
- name: Install dependencies with poetry
|
||||
working-directory: ./api
|
||||
run: |
|
||||
@ -60,7 +61,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
working-directory: ./api
|
||||
run: |
|
||||
poetry run python -m pytest
|
||||
poetry run python -m pytest -v --color=yes
|
||||
check-sh-files:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@ -79,6 +80,7 @@ jobs:
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
cache: 'pip' # caching pip dependencies
|
||||
- name: Run ruff check
|
||||
uses: chartboost/ruff-action@v1
|
||||
with:
|
||||
|
||||
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
@ -58,7 +58,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and Publish Docker Image
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
4
.github/workflows/helm-test.yml
vendored
4
.github/workflows/helm-test.yml
vendored
@ -37,7 +37,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Helm
|
||||
uses: azure/setup-helm@v3
|
||||
uses: azure/setup-helm@v4
|
||||
with:
|
||||
version: v3.12.3
|
||||
|
||||
@ -63,7 +63,7 @@ jobs:
|
||||
|
||||
- name: Create kind cluster
|
||||
if: steps.list-changed.outputs.changed == 'true'
|
||||
uses: helm/kind-action@v1.9.0
|
||||
uses: helm/kind-action@v1.10.0
|
||||
|
||||
- name: Run chart-testing (install)
|
||||
if: steps.list-changed.outputs.changed == 'true'
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -12,3 +12,4 @@ api/static/*
|
||||
**/node_modules/
|
||||
**/dist
|
||||
**/.mypy_cache/
|
||||
.vscode
|
||||
@ -34,7 +34,7 @@ COPY vendor/requirements.txt /usr/src/app/requirements.txt
|
||||
|
||||
# Install api dependencies
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends dumb-init \
|
||||
&& apt-get install -y --no-install-recommends dumb-init libgomp1 musl-dev \
|
||||
&& pip install --no-cache-dir ./api \
|
||||
&& pip install -r /usr/src/app/requirements.txt \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* \
|
||||
@ -45,7 +45,8 @@ RUN apt-get update \
|
||||
&& mkdir -p /data/db \
|
||||
&& mkdir -p /usr/src/app/weights \
|
||||
&& echo "appendonly yes" >> /etc/redis/redis.conf \
|
||||
&& echo "dir /data/db/" >> /etc/redis/redis.conf
|
||||
&& echo "dir /data/db/" >> /etc/redis/redis.conf \
|
||||
&& ln -s /usr/lib/x86_64-linux-musl/libc.so /lib/libc.musl-x86_64.so.1
|
||||
|
||||
EXPOSE 8008
|
||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||
|
||||
@ -17,7 +17,7 @@ ENV NODE_ENV='development'
|
||||
|
||||
# Install dependencies
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends dumb-init
|
||||
&& apt-get install -y --no-install-recommends dumb-init musl-dev
|
||||
|
||||
# Copy database, source code, and scripts
|
||||
COPY --from=redis /usr/local/bin/redis-server /usr/local/bin/redis-server
|
||||
@ -36,7 +36,8 @@ RUN npm ci \
|
||||
&& mkdir -p /data/db \
|
||||
&& mkdir -p /usr/src/app/weights \
|
||||
&& echo "appendonly yes" >> /etc/redis/redis.conf \
|
||||
&& echo "dir /data/db/" >> /etc/redis/redis.conf
|
||||
&& echo "dir /data/db/" >> /etc/redis/redis.conf \
|
||||
&& ln -s /usr/lib/x86_64-linux-musl/libc.so /lib/libc.musl-x86_64.so.1
|
||||
|
||||
EXPOSE 8008
|
||||
EXPOSE 9124
|
||||
|
||||
63
README.md
63
README.md
@ -45,12 +45,21 @@ volumes:
|
||||
|
||||
Then, just visit http://localhost:8008, You can find the API documentation at http://localhost:8008/api/docs
|
||||
|
||||
### 🌍 Environment Variables
|
||||
|
||||
The following Environment Variables are available:
|
||||
|
||||
| Variable Name | Description | Default Value |
|
||||
|-----------------------|---------------------------------------------------------|--------------------------------------|
|
||||
| `SERGE_DATABASE_URL` | Database connection string | `sqlite:////data/db/sql_app.db` |
|
||||
| `SERGE_JWT_SECRET` | Key for auth token encryption. Use a random string | `uF7FGN5uzfGdFiPzR` |
|
||||
| `SERGE_SESSION_EXPIRY`| Duration in minutes before a user must reauthenticate | `60` |
|
||||
| `NODE_ENV` | Node.js running environment | `production` |
|
||||
|
||||
## 🖥️ Windows
|
||||
|
||||
Ensure you have Docker Desktop installed, WSL2 configured, and enough free RAM to run models.
|
||||
To configure Serge to recognize .gguf model files, modify the `values.yaml` file for Helm deployments or set the appropriate environment variables. For Docker deployments, ensure your `docker run` or `docker-compose.yml` includes volume mappings for directories containing .gguf model files.
|
||||
Ensure you have Docker Desktop installed, WSL2 configured, and enough free RAM to run models.
|
||||
|
||||
```
|
||||
## ☁️ Kubernetes
|
||||
|
||||
Instructions for setting up Serge on Kubernetes can be found in the [wiki](https://github.com/serge-chat/serge/wiki/Integrating-Serge-in-your-orchestration#kubernetes-example).
|
||||
@ -60,21 +69,21 @@ Instructions for setting up Serge on Kubernetes can be found in the [wiki](https
|
||||
| Category | Models |
|
||||
|:-------------:|:-------|
|
||||
| **Alfred** | 40B-1023 |
|
||||
| **BioMistral | 7B |
|
||||
The `model_loader.py` script plays a crucial role in enabling Serge to support multiple model file extensions, including .gguf. It validates and loads model files based on the configured extensions, ensuring compatibility and flexibility in model usage.
|
||||
|
||||
```
|
||||
| **Kunoichi** | 7B-GGUF |
|
||||
| **BioMistral** | 7B |
|
||||
| **Code** | 13B, 33B |
|
||||
| **CodeLLaMA** | 7B, 7B-Instruct, 7B-Python, 13B, 13B-Instruct, 13B-Python, 34B, 34B-Instruct, 34B-Python |
|
||||
| **Gemma** | 2B, 2B-Instruct, 7B, 7B-Instruct |
|
||||
| **Codestral** | 22B v0.1 |
|
||||
| **Gemma** | 2B, 1.1-2B-Instruct, 7B, 1.1-7B-Instruct |
|
||||
| **Gorilla** | Falcon-7B-HF-v0, 7B-HF-v1, Openfunctions-v1, Openfunctions-v2 |
|
||||
| **Falcon** | 7B, 7B-Instruct, 40B, 40B-Instruct |
|
||||
| **LLaMA 2** | 7B, 7B-Chat, 7B-Coder, 13B, 13B-Chat, 70B, 70B-Chat, 70B-OASST |
|
||||
| **LLaMA 2** | 7B, 7B-Chat, 7B-Coder, 13B, 13B-Chat, 70B, 70B-Chat, 70B-OASST |
|
||||
| **LLaMA 3** | 11B-Instruct, 13B-Instruct, 16B-Instruct |
|
||||
| **LLaMA Pro** | 8B, 8B-Instruct |
|
||||
| **Med42** | 70B |
|
||||
| **Medalpaca** | 13B |
|
||||
| **Medicine** | Chat, LLM |
|
||||
| **Meditron** | 7B, 7B-Chat, 70B |
|
||||
| **Meta-LlaMA-3** | 8B, 8B-Instruct, 70B, 70B-Instruct |
|
||||
| **Mistral** | 7B-V0.1, 7B-Instruct-v0.2, 7B-OpenOrca |
|
||||
| **MistralLite** | 7B |
|
||||
| **Mixtral** | 8x7B-v0.1, 8x7B-Dolphin-2.7, 8x7B-Instruct-v0.1 |
|
||||
@ -83,22 +92,26 @@ The `model_loader.py` script plays a crucial role in enabling Serge to support m
|
||||
| **Notux** | 8x7b-v1 |
|
||||
| **Nous-Hermes 2** | Mistral-7B-DPO, Mixtral-8x7B-DPO, Mistral-8x7B-SFT |
|
||||
| **OpenChat** | 7B-v3.5-1210 |
|
||||
| **OpenCodeInterpreter** | DS-6.7B, DS-33B, CL-7B, CL-13B, CL-70B |
|
||||
| **OpenLLaMA** | 3B-v2, 7B-v2, 13B-v2 |
|
||||
| **Orca 2** | 7B, 13B |
|
||||
| **Phi 2** | 2.7B |
|
||||
| **Phi 3** | mini-4k-instruct, medium-4k-instruct, medium-128k-instruct |
|
||||
| **Python Code** | 13B, 33B |
|
||||
| **PsyMedRP** | 13B-v1, 20B-v1 |
|
||||
| **Starling LM** | 7B-Alpha |
|
||||
| **SOLAR** | 10.7B-v1.0, 10.7B-instruct-v1.0 |
|
||||
| **TinyLlama** | 1.1B |
|
||||
| **Vicuna** | 7B-v1.5, 13B-v1.5, 33B-v1.3, 33B-Coder |
|
||||
| **WizardLM** | 7B-v1.0, 13B-v1.2, 70B-v1.0 |
|
||||
| **WizardLM** | 2-7B, 13B-v1.2, 70B-v1.0 |
|
||||
| **Zephyr** | 3B, 7B-Alpha, 7B-Beta |
|
||||
|
||||
Additional models can be requested by opening a GitHub issue. Other models are also available at [Serge Models](https://github.com/Smartappli/serge-models).
|
||||
|
||||
## ⚠️ Memory Usage
|
||||
|
||||
LLaMA will crash if you don't have enough available memory for the model:
|
||||
LLaMA will crash if you don't have enough available memory for the model
|
||||
|
||||
## 💬 Support
|
||||
|
||||
Need help? Join our [Discord](https://discord.gg/62Hc6FEYQH)
|
||||
@ -117,3 +130,29 @@ git clone https://github.com/serge-chat/serge.git
|
||||
cd serge/
|
||||
docker compose -f docker-compose.dev.yml up --build
|
||||
```
|
||||
|
||||
The solution will accept a python debugger session on port 5678. Example launch.json for VSCode:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Remote Debug",
|
||||
"type": "python",
|
||||
"request": "attach",
|
||||
"connect": {
|
||||
"host": "localhost",
|
||||
"port": 5678
|
||||
},
|
||||
"pathMappings": [
|
||||
{
|
||||
"localRoot": "${workspaceFolder}/api",
|
||||
"remoteRoot": "/usr/src/app/api/"
|
||||
}
|
||||
],
|
||||
"justMyCode": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
4
api/.gitignore
vendored
4
api/.gitignore
vendored
@ -157,4 +157,6 @@ cython_debug/
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
#.idea/
|
||||
|
||||
*.db
|
||||
653
api/poetry.lock
generated
653
api/poetry.lock
generated
@ -1,88 +1,99 @@
|
||||
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "aiofiles"
|
||||
version = "24.1.0"
|
||||
description = "File support for asyncio."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5"},
|
||||
{file = "aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aiohttp"
|
||||
version = "3.9.3"
|
||||
version = "3.9.4"
|
||||
description = "Async http client/server framework (asyncio)"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:939677b61f9d72a4fa2a042a5eee2a99a24001a67c13da113b2e30396567db54"},
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1f5cd333fcf7590a18334c90f8c9147c837a6ec8a178e88d90a9b96ea03194cc"},
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:82e6aa28dd46374f72093eda8bcd142f7771ee1eb9d1e223ff0fa7177a96b4a5"},
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f56455b0c2c7cc3b0c584815264461d07b177f903a04481dfc33e08a89f0c26b"},
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bca77a198bb6e69795ef2f09a5f4c12758487f83f33d63acde5f0d4919815768"},
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e083c285857b78ee21a96ba1eb1b5339733c3563f72980728ca2b08b53826ca5"},
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab40e6251c3873d86ea9b30a1ac6d7478c09277b32e14745d0d3c6e76e3c7e29"},
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df822ee7feaaeffb99c1a9e5e608800bd8eda6e5f18f5cfb0dc7eeb2eaa6bbec"},
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:acef0899fea7492145d2bbaaaec7b345c87753168589cc7faf0afec9afe9b747"},
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cd73265a9e5ea618014802ab01babf1940cecb90c9762d8b9e7d2cc1e1969ec6"},
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a78ed8a53a1221393d9637c01870248a6f4ea5b214a59a92a36f18151739452c"},
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6b0e029353361f1746bac2e4cc19b32f972ec03f0f943b390c4ab3371840aabf"},
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7cf5c9458e1e90e3c390c2639f1017a0379a99a94fdfad3a1fd966a2874bba52"},
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-win32.whl", hash = "sha256:3e59c23c52765951b69ec45ddbbc9403a8761ee6f57253250c6e1536cacc758b"},
|
||||
{file = "aiohttp-3.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:055ce4f74b82551678291473f66dc9fb9048a50d8324278751926ff0ae7715e5"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6b88f9386ff1ad91ace19d2a1c0225896e28815ee09fc6a8932fded8cda97c3d"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c46956ed82961e31557b6857a5ca153c67e5476972e5f7190015018760938da2"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07b837ef0d2f252f96009e9b8435ec1fef68ef8b1461933253d318748ec1acdc"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad46e6f620574b3b4801c68255492e0159d1712271cc99d8bdf35f2043ec266"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ed3e046ea7b14938112ccd53d91c1539af3e6679b222f9469981e3dac7ba1ce"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:039df344b45ae0b34ac885ab5b53940b174530d4dd8a14ed8b0e2155b9dddccb"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7943c414d3a8d9235f5f15c22ace69787c140c80b718dcd57caaade95f7cd93b"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84871a243359bb42c12728f04d181a389718710129b36b6aad0fc4655a7647d4"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5eafe2c065df5401ba06821b9a054d9cb2848867f3c59801b5d07a0be3a380ae"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9d3c9b50f19704552f23b4eaea1fc082fdd82c63429a6506446cbd8737823da3"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:f033d80bc6283092613882dfe40419c6a6a1527e04fc69350e87a9df02bbc283"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:2c895a656dd7e061b2fd6bb77d971cc38f2afc277229ce7dd3552de8313a483e"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1f5a71d25cd8106eab05f8704cd9167b6e5187bcdf8f090a66c6d88b634802b4"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-win32.whl", hash = "sha256:50fca156d718f8ced687a373f9e140c1bb765ca16e3d6f4fe116e3df7c05b2c5"},
|
||||
{file = "aiohttp-3.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:5fe9ce6c09668063b8447f85d43b8d1c4e5d3d7e92c63173e6180b2ac5d46dd8"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:38a19bc3b686ad55804ae931012f78f7a534cce165d089a2059f658f6c91fa60"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:770d015888c2a598b377bd2f663adfd947d78c0124cfe7b959e1ef39f5b13869"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee43080e75fc92bf36219926c8e6de497f9b247301bbf88c5c7593d931426679"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52df73f14ed99cee84865b95a3d9e044f226320a87af208f068ecc33e0c35b96"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc9b311743a78043b26ffaeeb9715dc360335e5517832f5a8e339f8a43581e4d"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b955ed993491f1a5da7f92e98d5dad3c1e14dc175f74517c4e610b1f2456fb11"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:504b6981675ace64c28bf4a05a508af5cde526e36492c98916127f5a02354d53"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6fe5571784af92b6bc2fda8d1925cccdf24642d49546d3144948a6a1ed58ca5"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ba39e9c8627edc56544c8628cc180d88605df3892beeb2b94c9bc857774848ca"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e5e46b578c0e9db71d04c4b506a2121c0cb371dd89af17a0586ff6769d4c58c1"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:938a9653e1e0c592053f815f7028e41a3062e902095e5a7dc84617c87267ebd5"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:c3452ea726c76e92f3b9fae4b34a151981a9ec0a4847a627c43d71a15ac32aa6"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ff30218887e62209942f91ac1be902cc80cddb86bf00fbc6783b7a43b2bea26f"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-win32.whl", hash = "sha256:38f307b41e0bea3294a9a2a87833191e4bcf89bb0365e83a8be3a58b31fb7f38"},
|
||||
{file = "aiohttp-3.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:b791a3143681a520c0a17e26ae7465f1b6f99461a28019d1a2f425236e6eedb5"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0ed621426d961df79aa3b963ac7af0d40392956ffa9be022024cd16297b30c8c"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7f46acd6a194287b7e41e87957bfe2ad1ad88318d447caf5b090012f2c5bb528"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:feeb18a801aacb098220e2c3eea59a512362eb408d4afd0c242044c33ad6d542"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f734e38fd8666f53da904c52a23ce517f1b07722118d750405af7e4123933511"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b40670ec7e2156d8e57f70aec34a7216407848dfe6c693ef131ddf6e76feb672"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fdd215b7b7fd4a53994f238d0f46b7ba4ac4c0adb12452beee724ddd0743ae5d"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:017a21b0df49039c8f46ca0971b3a7fdc1f56741ab1240cb90ca408049766168"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e99abf0bba688259a496f966211c49a514e65afa9b3073a1fcee08856e04425b"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:648056db9a9fa565d3fa851880f99f45e3f9a771dd3ff3bb0c048ea83fb28194"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8aacb477dc26797ee089721536a292a664846489c49d3ef9725f992449eda5a8"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:522a11c934ea660ff8953eda090dcd2154d367dec1ae3c540aff9f8a5c109ab4"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:5bce0dc147ca85caa5d33debc4f4d65e8e8b5c97c7f9f660f215fa74fc49a321"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b4af9f25b49a7be47c0972139e59ec0e8285c371049df1a63b6ca81fdd216a2"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-win32.whl", hash = "sha256:298abd678033b8571995650ccee753d9458dfa0377be4dba91e4491da3f2be63"},
|
||||
{file = "aiohttp-3.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:69361bfdca5468c0488d7017b9b1e5ce769d40b46a9f4a2eed26b78619e9396c"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0fa43c32d1643f518491d9d3a730f85f5bbaedcbd7fbcae27435bb8b7a061b29"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:835a55b7ca49468aaaac0b217092dfdff370e6c215c9224c52f30daaa735c1c1"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06a9b2c8837d9a94fae16c6223acc14b4dfdff216ab9b7202e07a9a09541168f"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abf151955990d23f84205286938796c55ff11bbfb4ccfada8c9c83ae6b3c89a3"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59c26c95975f26e662ca78fdf543d4eeaef70e533a672b4113dd888bd2423caa"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f95511dd5d0e05fd9728bac4096319f80615aaef4acbecb35a990afebe953b0e"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:595f105710293e76b9dc09f52e0dd896bd064a79346234b521f6b968ffdd8e58"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7c8b816c2b5af5c8a436df44ca08258fc1a13b449393a91484225fcb7545533"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f1088fa100bf46e7b398ffd9904f4808a0612e1d966b4aa43baa535d1b6341eb"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f59dfe57bb1ec82ac0698ebfcdb7bcd0e99c255bd637ff613760d5f33e7c81b3"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:361a1026c9dd4aba0109e4040e2aecf9884f5cfe1b1b1bd3d09419c205e2e53d"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:363afe77cfcbe3a36353d8ea133e904b108feea505aa4792dad6585a8192c55a"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e2c45c208c62e955e8256949eb225bd8b66a4c9b6865729a786f2aa79b72e9d"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-win32.whl", hash = "sha256:f7217af2e14da0856e082e96ff637f14ae45c10a5714b63c77f26d8884cf1051"},
|
||||
{file = "aiohttp-3.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:27468897f628c627230dba07ec65dc8d0db566923c48f29e084ce382119802bc"},
|
||||
{file = "aiohttp-3.9.3.tar.gz", hash = "sha256:90842933e5d1ff760fae6caca4b2b3edba53ba8f4b71e95dacf2818a2aca06f7"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:76d32588ef7e4a3f3adff1956a0ba96faabbdee58f2407c122dd45aa6e34f372"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:56181093c10dbc6ceb8a29dfeea1e815e1dfdc020169203d87fd8d37616f73f9"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7a5b676d3c65e88b3aca41816bf72831898fcd73f0cbb2680e9d88e819d1e4d"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1df528a85fb404899d4207a8d9934cfd6be626e30e5d3a5544a83dbae6d8a7e"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f595db1bceabd71c82e92df212dd9525a8a2c6947d39e3c994c4f27d2fe15b11"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c0b09d76e5a4caac3d27752027fbd43dc987b95f3748fad2b924a03fe8632ad"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:689eb4356649ec9535b3686200b231876fb4cab4aca54e3bece71d37f50c1d13"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3666cf4182efdb44d73602379a66f5fdfd5da0db5e4520f0ac0dcca644a3497"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b65b0f8747b013570eea2f75726046fa54fa8e0c5db60f3b98dd5d161052004a"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1885d2470955f70dfdd33a02e1749613c5a9c5ab855f6db38e0b9389453dce7"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0593822dcdb9483d41f12041ff7c90d4d1033ec0e880bcfaf102919b715f47f1"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:47f6eb74e1ecb5e19a78f4a4228aa24df7fbab3b62d4a625d3f41194a08bd54f"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c8b04a3dbd54de6ccb7604242fe3ad67f2f3ca558f2d33fe19d4b08d90701a89"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-win32.whl", hash = "sha256:8a78dfb198a328bfb38e4308ca8167028920fb747ddcf086ce706fbdd23b2926"},
|
||||
{file = "aiohttp-3.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:e78da6b55275987cbc89141a1d8e75f5070e577c482dd48bd9123a76a96f0bbb"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c111b3c69060d2bafc446917534150fd049e7aedd6cbf21ba526a5a97b4402a5"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:efbdd51872cf170093998c87ccdf3cb5993add3559341a8e5708bcb311934c94"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7bfdb41dc6e85d8535b00d73947548a748e9534e8e4fddd2638109ff3fb081df"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bd9d334412961125e9f68d5b73c1d0ab9ea3f74a58a475e6b119f5293eee7ba"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35d78076736f4a668d57ade00c65d30a8ce28719d8a42471b2a06ccd1a2e3063"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:824dff4f9f4d0f59d0fa3577932ee9a20e09edec8a2f813e1d6b9f89ced8293f"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52b8b4e06fc15519019e128abedaeb56412b106ab88b3c452188ca47a25c4093"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eae569fb1e7559d4f3919965617bb39f9e753967fae55ce13454bec2d1c54f09"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:69b97aa5792428f321f72aeb2f118e56893371f27e0b7d05750bcad06fc42ca1"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4d79aad0ad4b980663316f26d9a492e8fab2af77c69c0f33780a56843ad2f89e"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:d6577140cd7db19e430661e4b2653680194ea8c22c994bc65b7a19d8ec834403"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:9860d455847cd98eb67897f5957b7cd69fbcb436dd3f06099230f16a66e66f79"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:69ff36d3f8f5652994e08bd22f093e11cfd0444cea310f92e01b45a4e46b624e"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-win32.whl", hash = "sha256:e27d3b5ed2c2013bce66ad67ee57cbf614288bda8cdf426c8d8fe548316f1b5f"},
|
||||
{file = "aiohttp-3.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d6a67e26daa686a6fbdb600a9af8619c80a332556245fa8e86c747d226ab1a1e"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c5ff8ff44825736a4065d8544b43b43ee4c6dd1530f3a08e6c0578a813b0aa35"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d12a244627eba4e9dc52cbf924edef905ddd6cafc6513849b4876076a6f38b0e"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dcad56c8d8348e7e468899d2fb3b309b9bc59d94e6db08710555f7436156097f"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f7e69a7fd4b5ce419238388e55abd220336bd32212c673ceabc57ccf3d05b55"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4870cb049f10d7680c239b55428916d84158798eb8f353e74fa2c98980dcc0b"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2feaf1b7031ede1bc0880cec4b0776fd347259a723d625357bb4b82f62687b"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:939393e8c3f0a5bcd33ef7ace67680c318dc2ae406f15e381c0054dd658397de"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d2334e387b2adcc944680bebcf412743f2caf4eeebd550f67249c1c3696be04"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e0198ea897680e480845ec0ffc5a14e8b694e25b3f104f63676d55bf76a82f1a"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e40d2cd22914d67c84824045861a5bb0fb46586b15dfe4f046c7495bf08306b2"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:aba80e77c227f4234aa34a5ff2b6ff30c5d6a827a91d22ff6b999de9175d71bd"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:fb68dc73bc8ac322d2e392a59a9e396c4f35cb6fdbdd749e139d1d6c985f2527"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f3460a92638dce7e47062cf088d6e7663adb135e936cb117be88d5e6c48c9d53"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-win32.whl", hash = "sha256:32dc814ddbb254f6170bca198fe307920f6c1308a5492f049f7f63554b88ef36"},
|
||||
{file = "aiohttp-3.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:63f41a909d182d2b78fe3abef557fcc14da50c7852f70ae3be60e83ff64edba5"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c3770365675f6be220032f6609a8fbad994d6dcf3ef7dbcf295c7ee70884c9af"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:305edae1dea368ce09bcb858cf5a63a064f3bff4767dec6fa60a0cc0e805a1d3"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6f121900131d116e4a93b55ab0d12ad72573f967b100e49086e496a9b24523ea"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b71e614c1ae35c3d62a293b19eface83d5e4d194e3eb2fabb10059d33e6e8cbf"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:419f009fa4cfde4d16a7fc070d64f36d70a8d35a90d71aa27670bba2be4fd039"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b39476ee69cfe64061fd77a73bf692c40021f8547cda617a3466530ef63f947"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b33f34c9c7decdb2ab99c74be6443942b730b56d9c5ee48fb7df2c86492f293c"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c78700130ce2dcebb1a8103202ae795be2fa8c9351d0dd22338fe3dac74847d9"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:268ba22d917655d1259af2d5659072b7dc11b4e1dc2cb9662fdd867d75afc6a4"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:17e7c051f53a0d2ebf33013a9cbf020bb4e098c4bc5bce6f7b0c962108d97eab"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7be99f4abb008cb38e144f85f515598f4c2c8932bf11b65add0ff59c9c876d99"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:d58a54d6ff08d2547656356eea8572b224e6f9bbc0cf55fa9966bcaac4ddfb10"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7673a76772bda15d0d10d1aa881b7911d0580c980dbd16e59d7ba1422b2d83cd"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-win32.whl", hash = "sha256:e4370dda04dc8951012f30e1ce7956a0a226ac0714a7b6c389fb2f43f22a250e"},
|
||||
{file = "aiohttp-3.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:eb30c4510a691bb87081192a394fb661860e75ca3896c01c6d186febe7c88530"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:84e90494db7df3be5e056f91412f9fa9e611fbe8ce4aaef70647297f5943b276"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7d4845f8501ab28ebfdbeab980a50a273b415cf69e96e4e674d43d86a464df9d"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:69046cd9a2a17245c4ce3c1f1a4ff8c70c7701ef222fce3d1d8435f09042bba1"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b73a06bafc8dcc508420db43b4dd5850e41e69de99009d0351c4f3007960019"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:418bb0038dfafeac923823c2e63226179976c76f981a2aaad0ad5d51f2229bca"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:71a8f241456b6c2668374d5d28398f8e8cdae4cce568aaea54e0f39359cd928d"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:935c369bf8acc2dc26f6eeb5222768aa7c62917c3554f7215f2ead7386b33748"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74e4e48c8752d14ecfb36d2ebb3d76d614320570e14de0a3aa7a726ff150a03c"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:916b0417aeddf2c8c61291238ce25286f391a6acb6f28005dd9ce282bd6311b6"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9b6787b6d0b3518b2ee4cbeadd24a507756ee703adbac1ab6dc7c4434b8c572a"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:221204dbda5ef350e8db6287937621cf75e85778b296c9c52260b522231940ed"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:10afd99b8251022ddf81eaed1d90f5a988e349ee7d779eb429fb07b670751e8c"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2506d9f7a9b91033201be9ffe7d89c6a54150b0578803cce5cb84a943d075bc3"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-win32.whl", hash = "sha256:e571fdd9efd65e86c6af2f332e0e95dad259bfe6beb5d15b3c3eca3a6eb5d87b"},
|
||||
{file = "aiohttp-3.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:7d29dd5319d20aa3b7749719ac9685fbd926f71ac8c77b2477272725f882072d"},
|
||||
{file = "aiohttp-3.9.4.tar.gz", hash = "sha256:6ff71ede6d9a5a58cfb7b6fffc83ab5d4a63138276c771ac91ceaaddf5459644"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -177,13 +188,13 @@ tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "p
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2024.2.2"
|
||||
version = "2024.7.4"
|
||||
description = "Python package for providing Mozilla's CA Bundle."
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"},
|
||||
{file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"},
|
||||
{file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"},
|
||||
{file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -374,6 +385,60 @@ files = [
|
||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cryptography"
|
||||
version = "42.0.7"
|
||||
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "cryptography-42.0.7-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:a987f840718078212fdf4504d0fd4c6effe34a7e4740378e59d47696e8dfb477"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bd13b5e9b543532453de08bcdc3cc7cebec6f9883e886fd20a92f26940fd3e7a"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a79165431551042cc9d1d90e6145d5d0d3ab0f2d66326c201d9b0e7f5bf43604"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a47787a5e3649008a1102d3df55424e86606c9bae6fb77ac59afe06d234605f8"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:02c0eee2d7133bdbbc5e24441258d5d2244beb31da5ed19fbb80315f4bbbff55"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:5e44507bf8d14b36b8389b226665d597bc0f18ea035d75b4e53c7b1ea84583cc"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7f8b25fa616d8b846aef64b15c606bb0828dbc35faf90566eb139aa9cff67af2"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:93a3209f6bb2b33e725ed08ee0991b92976dfdcf4e8b38646540674fc7508e13"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e6b8f1881dac458c34778d0a424ae5769de30544fc678eac51c1c8bb2183e9da"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3de9a45d3b2b7d8088c3fbf1ed4395dfeff79d07842217b38df14ef09ce1d8d7"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-win32.whl", hash = "sha256:789caea816c6704f63f6241a519bfa347f72fbd67ba28d04636b7c6b7da94b0b"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:8cb8ce7c3347fcf9446f201dc30e2d5a3c898d009126010cbd1f443f28b52678"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:a3a5ac8b56fe37f3125e5b72b61dcde43283e5370827f5233893d461b7360cd4"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:779245e13b9a6638df14641d029add5dc17edbef6ec915688f3acb9e720a5858"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d563795db98b4cd57742a78a288cdbdc9daedac29f2239793071fe114f13785"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:31adb7d06fe4383226c3e963471f6837742889b3c4caa55aac20ad951bc8ffda"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:efd0bf5205240182e0f13bcaea41be4fdf5c22c5129fc7ced4a0282ac86998c9"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a9bc127cdc4ecf87a5ea22a2556cab6c7eda2923f84e4f3cc588e8470ce4e42e"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3577d029bc3f4827dd5bf8bf7710cac13527b470bbf1820a3f394adb38ed7d5f"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2e47577f9b18723fa294b0ea9a17d5e53a227867a0a4904a1a076d1646d45ca1"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1a58839984d9cb34c855197043eaae2c187d930ca6d644612843b4fe8513c886"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-win32.whl", hash = "sha256:e6b79d0adb01aae87e8a44c2b64bc3f3fe59515280e00fb6d57a7267a2583cda"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-win_amd64.whl", hash = "sha256:16268d46086bb8ad5bf0a2b5544d8a9ed87a0e33f5e77dd3c3301e63d941a83b"},
|
||||
{file = "cryptography-42.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2954fccea107026512b15afb4aa664a5640cd0af630e2ee3962f2602693f0c82"},
|
||||
{file = "cryptography-42.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:362e7197754c231797ec45ee081f3088a27a47c6c01eff2ac83f60f85a50fe60"},
|
||||
{file = "cryptography-42.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f698edacf9c9e0371112792558d2f705b5645076cc0aaae02f816a0171770fd"},
|
||||
{file = "cryptography-42.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5482e789294854c28237bba77c4c83be698be740e31a3ae5e879ee5444166582"},
|
||||
{file = "cryptography-42.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e9b2a6309f14c0497f348d08a065d52f3020656f675819fc405fb63bbcd26562"},
|
||||
{file = "cryptography-42.0.7-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d8e3098721b84392ee45af2dd554c947c32cc52f862b6a3ae982dbb90f577f14"},
|
||||
{file = "cryptography-42.0.7-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c65f96dad14f8528a447414125e1fc8feb2ad5a272b8f68477abbcc1ea7d94b9"},
|
||||
{file = "cryptography-42.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36017400817987670037fbb0324d71489b6ead6231c9604f8fc1f7d008087c68"},
|
||||
{file = "cryptography-42.0.7.tar.gz", hash = "sha256:ecbfbc00bf55888edda9868a4cf927205de8499e7fabe6c050322298382953f2"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""}
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"]
|
||||
docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"]
|
||||
nox = ["nox"]
|
||||
pep8test = ["check-sdist", "click", "mypy", "ruff"]
|
||||
sdist = ["build"]
|
||||
ssh = ["bcrypt (>=3.1.5)"]
|
||||
test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
|
||||
test-randomorder = ["pytest-randomly"]
|
||||
|
||||
[[package]]
|
||||
name = "dataclasses-json"
|
||||
version = "0.5.9"
|
||||
@ -393,6 +458,55 @@ typing-inspect = ">=0.4.0"
|
||||
[package.extras]
|
||||
dev = ["flake8", "hypothesis", "ipython", "mypy (>=0.710)", "portray", "pytest (>=7.2.0)", "setuptools", "simplejson", "twine", "types-dataclasses", "wheel"]
|
||||
|
||||
[[package]]
|
||||
name = "debugpy"
|
||||
version = "1.8.5"
|
||||
description = "An implementation of the Debug Adapter Protocol for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "debugpy-1.8.5-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:7e4d594367d6407a120b76bdaa03886e9eb652c05ba7f87e37418426ad2079f7"},
|
||||
{file = "debugpy-1.8.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4413b7a3ede757dc33a273a17d685ea2b0c09dbd312cc03f5534a0fd4d40750a"},
|
||||
{file = "debugpy-1.8.5-cp310-cp310-win32.whl", hash = "sha256:dd3811bd63632bb25eda6bd73bea8e0521794cda02be41fa3160eb26fc29e7ed"},
|
||||
{file = "debugpy-1.8.5-cp310-cp310-win_amd64.whl", hash = "sha256:b78c1250441ce893cb5035dd6f5fc12db968cc07f91cc06996b2087f7cefdd8e"},
|
||||
{file = "debugpy-1.8.5-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:606bccba19f7188b6ea9579c8a4f5a5364ecd0bf5a0659c8a5d0e10dcee3032a"},
|
||||
{file = "debugpy-1.8.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db9fb642938a7a609a6c865c32ecd0d795d56c1aaa7a7a5722d77855d5e77f2b"},
|
||||
{file = "debugpy-1.8.5-cp311-cp311-win32.whl", hash = "sha256:4fbb3b39ae1aa3e5ad578f37a48a7a303dad9a3d018d369bc9ec629c1cfa7408"},
|
||||
{file = "debugpy-1.8.5-cp311-cp311-win_amd64.whl", hash = "sha256:345d6a0206e81eb68b1493ce2fbffd57c3088e2ce4b46592077a943d2b968ca3"},
|
||||
{file = "debugpy-1.8.5-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:5b5c770977c8ec6c40c60d6f58cacc7f7fe5a45960363d6974ddb9b62dbee156"},
|
||||
{file = "debugpy-1.8.5-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0a65b00b7cdd2ee0c2cf4c7335fef31e15f1b7056c7fdbce9e90193e1a8c8cb"},
|
||||
{file = "debugpy-1.8.5-cp312-cp312-win32.whl", hash = "sha256:c9f7c15ea1da18d2fcc2709e9f3d6de98b69a5b0fff1807fb80bc55f906691f7"},
|
||||
{file = "debugpy-1.8.5-cp312-cp312-win_amd64.whl", hash = "sha256:28ced650c974aaf179231668a293ecd5c63c0a671ae6d56b8795ecc5d2f48d3c"},
|
||||
{file = "debugpy-1.8.5-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:3df6692351172a42af7558daa5019651f898fc67450bf091335aa8a18fbf6f3a"},
|
||||
{file = "debugpy-1.8.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cd04a73eb2769eb0bfe43f5bfde1215c5923d6924b9b90f94d15f207a402226"},
|
||||
{file = "debugpy-1.8.5-cp38-cp38-win32.whl", hash = "sha256:8f913ee8e9fcf9d38a751f56e6de12a297ae7832749d35de26d960f14280750a"},
|
||||
{file = "debugpy-1.8.5-cp38-cp38-win_amd64.whl", hash = "sha256:a697beca97dad3780b89a7fb525d5e79f33821a8bc0c06faf1f1289e549743cf"},
|
||||
{file = "debugpy-1.8.5-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:0a1029a2869d01cb777216af8c53cda0476875ef02a2b6ff8b2f2c9a4b04176c"},
|
||||
{file = "debugpy-1.8.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84c276489e141ed0b93b0af648eef891546143d6a48f610945416453a8ad406"},
|
||||
{file = "debugpy-1.8.5-cp39-cp39-win32.whl", hash = "sha256:ad84b7cde7fd96cf6eea34ff6c4a1b7887e0fe2ea46e099e53234856f9d99a34"},
|
||||
{file = "debugpy-1.8.5-cp39-cp39-win_amd64.whl", hash = "sha256:7b0fe36ed9d26cb6836b0a51453653f8f2e347ba7348f2bbfe76bfeb670bfb1c"},
|
||||
{file = "debugpy-1.8.5-py2.py3-none-any.whl", hash = "sha256:55919dce65b471eff25901acf82d328bbd5b833526b6c1364bd5133754777a44"},
|
||||
{file = "debugpy-1.8.5.zip", hash = "sha256:b2112cfeb34b4507399d298fe7023a16656fc553ed5246536060ca7bd0e668d0"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ecdsa"
|
||||
version = "0.19.0"
|
||||
description = "ECDSA cryptographic signature library (pure python)"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.6"
|
||||
files = [
|
||||
{file = "ecdsa-0.19.0-py2.py3-none-any.whl", hash = "sha256:2cea9b88407fdac7bbeca0833b189e4c9c53f2ef1e1eaa29f6224dbc809b707a"},
|
||||
{file = "ecdsa-0.19.0.tar.gz", hash = "sha256:60eaad1199659900dd0af521ed462b793bbdf867432b3948e87416ae4caf6bf8"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
six = ">=1.9.0"
|
||||
|
||||
[package.extras]
|
||||
gmpy = ["gmpy"]
|
||||
gmpy2 = ["gmpy2"]
|
||||
|
||||
[[package]]
|
||||
name = "exceptiongroup"
|
||||
version = "1.2.0"
|
||||
@ -793,13 +907,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "huggingface-hub"
|
||||
version = "0.20.3"
|
||||
version = "0.24.5"
|
||||
description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub"
|
||||
optional = false
|
||||
python-versions = ">=3.8.0"
|
||||
files = [
|
||||
{file = "huggingface_hub-0.20.3-py3-none-any.whl", hash = "sha256:d988ae4f00d3e307b0c80c6a05ca6dbb7edba8bba3079f74cda7d9c2e562a7b6"},
|
||||
{file = "huggingface_hub-0.20.3.tar.gz", hash = "sha256:94e7f8e074475fbc67d6a71957b678e1b4a74ff1b64a644fd6cbb83da962d05d"},
|
||||
{file = "huggingface_hub-0.24.5-py3-none-any.whl", hash = "sha256:d93fb63b1f1a919a22ce91a14518974e81fc4610bf344dfe7572343ce8d3aced"},
|
||||
{file = "huggingface_hub-0.24.5.tar.gz", hash = "sha256:7b45d6744dd53ce9cbf9880957de00e9d10a9ae837f1c9b7255fc8fa4e8264f3"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -812,43 +926,46 @@ tqdm = ">=4.42.1"
|
||||
typing-extensions = ">=3.7.4.3"
|
||||
|
||||
[package.extras]
|
||||
all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "mypy (==1.5.1)", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.1.3)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
|
||||
all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.5.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
|
||||
cli = ["InquirerPy (==0.3.4)"]
|
||||
dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "mypy (==1.5.1)", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.1.3)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
|
||||
dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.5.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
|
||||
fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"]
|
||||
inference = ["aiohttp", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)"]
|
||||
quality = ["mypy (==1.5.1)", "ruff (>=0.1.3)"]
|
||||
hf-transfer = ["hf-transfer (>=0.1.4)"]
|
||||
inference = ["aiohttp", "minijinja (>=1.0)"]
|
||||
quality = ["mypy (==1.5.1)", "ruff (>=0.5.0)"]
|
||||
tensorflow = ["graphviz", "pydot", "tensorflow"]
|
||||
testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"]
|
||||
torch = ["torch"]
|
||||
tensorflow-testing = ["keras (<3.0)", "tensorflow"]
|
||||
testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"]
|
||||
torch = ["safetensors[torch]", "torch"]
|
||||
typing = ["types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "hypercorn"
|
||||
version = "0.16.0"
|
||||
version = "0.17.3"
|
||||
description = "A ASGI Server based on Hyper libraries and inspired by Gunicorn"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "hypercorn-0.16.0-py3-none-any.whl", hash = "sha256:929e45c4acde3fbf7c58edf55336d30a009d2b4cb1f1eb96e6a515d61b663f58"},
|
||||
{file = "hypercorn-0.16.0.tar.gz", hash = "sha256:3b17d1dcf4992c1f262d9f9dd799c374125d0b9a8e40e1e2d11e2938b0adfe03"},
|
||||
{file = "hypercorn-0.17.3-py3-none-any.whl", hash = "sha256:059215dec34537f9d40a69258d323f56344805efb462959e727152b0aa504547"},
|
||||
{file = "hypercorn-0.17.3.tar.gz", hash = "sha256:1b37802ee3ac52d2d85270700d565787ab16cf19e1462ccfa9f089ca17574165"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
exceptiongroup = {version = ">=1.1.0", optional = true, markers = "extra == \"trio\""}
|
||||
exceptiongroup = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||
h11 = "*"
|
||||
h2 = ">=3.1.0"
|
||||
priority = "*"
|
||||
taskgroup = {version = "*", markers = "python_version < \"3.11\""}
|
||||
tomli = {version = "*", markers = "python_version < \"3.11\""}
|
||||
trio = {version = ">=0.22.0", optional = true, markers = "extra == \"trio\""}
|
||||
typing_extensions = {version = "*", markers = "python_version < \"3.11\""}
|
||||
wsproto = ">=0.14.0"
|
||||
|
||||
[package.extras]
|
||||
docs = ["pydata_sphinx_theme", "sphinxcontrib_mermaid"]
|
||||
h3 = ["aioquic (>=0.9.0,<1.0)"]
|
||||
trio = ["exceptiongroup (>=1.1.0)", "trio (>=0.22.0)"]
|
||||
uvloop = ["uvloop"]
|
||||
trio = ["trio (>=0.22.0)"]
|
||||
uvloop = ["uvloop (>=0.18)"]
|
||||
|
||||
[[package]]
|
||||
name = "hyperframe"
|
||||
@ -863,13 +980,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.6"
|
||||
version = "3.7"
|
||||
description = "Internationalized Domain Names in Applications (IDNA)"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"},
|
||||
{file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"},
|
||||
{file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"},
|
||||
{file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1181,24 +1298,24 @@ attrs = ">=19.2.0"
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "23.2"
|
||||
version = "24.1"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
|
||||
{file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
|
||||
{file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
|
||||
{file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.3.0"
|
||||
version = "1.5.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"},
|
||||
{file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"},
|
||||
{file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
|
||||
{file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@ -1216,6 +1333,17 @@ files = [
|
||||
{file = "priority-2.0.0.tar.gz", hash = "sha256:c965d54f1b8d0d0b19479db3924c7c36cf672dbf2aec92d43fbdaf4492ba18c0"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyasn1"
|
||||
version = "0.6.0"
|
||||
description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pyasn1-0.6.0-py2.py3-none-any.whl", hash = "sha256:cca4bb0f2df5504f02f6f8a775b6e416ff9b0b3b16f7ee80b5a3153d9b804473"},
|
||||
{file = "pyasn1-0.6.0.tar.gz", hash = "sha256:3a35ab2c4b5ef98e17dfdec8ab074046fbda76e281c5a706ccd82328cfc8f64c"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pycparser"
|
||||
version = "2.21"
|
||||
@ -1229,47 +1357,54 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "1.10.14"
|
||||
version = "1.10.17"
|
||||
description = "Data validation and settings management using python type hints"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pydantic-1.10.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f4fcec873f90537c382840f330b90f4715eebc2bc9925f04cb92de593eae054"},
|
||||
{file = "pydantic-1.10.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e3a76f571970fcd3c43ad982daf936ae39b3e90b8a2e96c04113a369869dc87"},
|
||||
{file = "pydantic-1.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d886bd3c3fbeaa963692ef6b643159ccb4b4cefaf7ff1617720cbead04fd1d"},
|
||||
{file = "pydantic-1.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:798a3d05ee3b71967844a1164fd5bdb8c22c6d674f26274e78b9f29d81770c4e"},
|
||||
{file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:23d47a4b57a38e8652bcab15a658fdb13c785b9ce217cc3a729504ab4e1d6bc9"},
|
||||
{file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9f674b5c3bebc2eba401de64f29948ae1e646ba2735f884d1594c5f675d6f2a"},
|
||||
{file = "pydantic-1.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:24a7679fab2e0eeedb5a8924fc4a694b3bcaac7d305aeeac72dd7d4e05ecbebf"},
|
||||
{file = "pydantic-1.10.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d578ac4bf7fdf10ce14caba6f734c178379bd35c486c6deb6f49006e1ba78a7"},
|
||||
{file = "pydantic-1.10.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa7790e94c60f809c95602a26d906eba01a0abee9cc24150e4ce2189352deb1b"},
|
||||
{file = "pydantic-1.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad4e10efa5474ed1a611b6d7f0d130f4aafadceb73c11d9e72823e8f508e663"},
|
||||
{file = "pydantic-1.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1245f4f61f467cb3dfeced2b119afef3db386aec3d24a22a1de08c65038b255f"},
|
||||
{file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:21efacc678a11114c765eb52ec0db62edffa89e9a562a94cbf8fa10b5db5c046"},
|
||||
{file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:412ab4a3f6dbd2bf18aefa9f79c7cca23744846b31f1d6555c2ee2b05a2e14ca"},
|
||||
{file = "pydantic-1.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:e897c9f35281f7889873a3e6d6b69aa1447ceb024e8495a5f0d02ecd17742a7f"},
|
||||
{file = "pydantic-1.10.14-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d604be0f0b44d473e54fdcb12302495fe0467c56509a2f80483476f3ba92b33c"},
|
||||
{file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42c7d17706911199798d4c464b352e640cab4351efe69c2267823d619a937e5"},
|
||||
{file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:596f12a1085e38dbda5cbb874d0973303e34227b400b6414782bf205cc14940c"},
|
||||
{file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bfb113860e9288d0886e3b9e49d9cf4a9d48b441f52ded7d96db7819028514cc"},
|
||||
{file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bc3ed06ab13660b565eed80887fcfbc0070f0aa0691fbb351657041d3e874efe"},
|
||||
{file = "pydantic-1.10.14-cp37-cp37m-win_amd64.whl", hash = "sha256:ad8c2bc677ae5f6dbd3cf92f2c7dc613507eafe8f71719727cbc0a7dec9a8c01"},
|
||||
{file = "pydantic-1.10.14-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c37c28449752bb1f47975d22ef2882d70513c546f8f37201e0fec3a97b816eee"},
|
||||
{file = "pydantic-1.10.14-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49a46a0994dd551ec051986806122767cf144b9702e31d47f6d493c336462597"},
|
||||
{file = "pydantic-1.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53e3819bd20a42470d6dd0fe7fc1c121c92247bca104ce608e609b59bc7a77ee"},
|
||||
{file = "pydantic-1.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbb503bbbbab0c588ed3cd21975a1d0d4163b87e360fec17a792f7d8c4ff29f"},
|
||||
{file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:336709883c15c050b9c55a63d6c7ff09be883dbc17805d2b063395dd9d9d0022"},
|
||||
{file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4ae57b4d8e3312d486e2498d42aed3ece7b51848336964e43abbf9671584e67f"},
|
||||
{file = "pydantic-1.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:dba49d52500c35cfec0b28aa8b3ea5c37c9df183ffc7210b10ff2a415c125c4a"},
|
||||
{file = "pydantic-1.10.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c66609e138c31cba607d8e2a7b6a5dc38979a06c900815495b2d90ce6ded35b4"},
|
||||
{file = "pydantic-1.10.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d986e115e0b39604b9eee3507987368ff8148222da213cd38c359f6f57b3b347"},
|
||||
{file = "pydantic-1.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:646b2b12df4295b4c3148850c85bff29ef6d0d9621a8d091e98094871a62e5c7"},
|
||||
{file = "pydantic-1.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282613a5969c47c83a8710cc8bfd1e70c9223feb76566f74683af889faadc0ea"},
|
||||
{file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:466669501d08ad8eb3c4fecd991c5e793c4e0bbd62299d05111d4f827cded64f"},
|
||||
{file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:13e86a19dca96373dcf3190fcb8797d40a6f12f154a244a8d1e8e03b8f280593"},
|
||||
{file = "pydantic-1.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:08b6ec0917c30861e3fe71a93be1648a2aa4f62f866142ba21670b24444d7fd8"},
|
||||
{file = "pydantic-1.10.14-py3-none-any.whl", hash = "sha256:8ee853cd12ac2ddbf0ecbac1c289f95882b2d4482258048079d13be700aa114c"},
|
||||
{file = "pydantic-1.10.14.tar.gz", hash = "sha256:46f17b832fe27de7850896f3afee50ea682220dd218f7e9c88d436788419dca6"},
|
||||
{file = "pydantic-1.10.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fa51175313cc30097660b10eec8ca55ed08bfa07acbfe02f7a42f6c242e9a4b"},
|
||||
{file = "pydantic-1.10.17-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7e8988bb16988890c985bd2093df9dd731bfb9d5e0860db054c23034fab8f7a"},
|
||||
{file = "pydantic-1.10.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:371dcf1831f87c9e217e2b6a0c66842879a14873114ebb9d0861ab22e3b5bb1e"},
|
||||
{file = "pydantic-1.10.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4866a1579c0c3ca2c40575398a24d805d4db6cb353ee74df75ddeee3c657f9a7"},
|
||||
{file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:543da3c6914795b37785703ffc74ba4d660418620cc273490d42c53949eeeca6"},
|
||||
{file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7623b59876f49e61c2e283551cc3647616d2fbdc0b4d36d3d638aae8547ea681"},
|
||||
{file = "pydantic-1.10.17-cp310-cp310-win_amd64.whl", hash = "sha256:409b2b36d7d7d19cd8310b97a4ce6b1755ef8bd45b9a2ec5ec2b124db0a0d8f3"},
|
||||
{file = "pydantic-1.10.17-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fa43f362b46741df8f201bf3e7dff3569fa92069bcc7b4a740dea3602e27ab7a"},
|
||||
{file = "pydantic-1.10.17-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2a72d2a5ff86a3075ed81ca031eac86923d44bc5d42e719d585a8eb547bf0c9b"},
|
||||
{file = "pydantic-1.10.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4ad32aed3bf5eea5ca5decc3d1bbc3d0ec5d4fbcd72a03cdad849458decbc63"},
|
||||
{file = "pydantic-1.10.17-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb4e741782e236ee7dc1fb11ad94dc56aabaf02d21df0e79e0c21fe07c95741"},
|
||||
{file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d2f89a719411cb234105735a520b7c077158a81e0fe1cb05a79c01fc5eb59d3c"},
|
||||
{file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db3b48d9283d80a314f7a682f7acae8422386de659fffaba454b77a083c3937d"},
|
||||
{file = "pydantic-1.10.17-cp311-cp311-win_amd64.whl", hash = "sha256:9c803a5113cfab7bbb912f75faa4fc1e4acff43e452c82560349fff64f852e1b"},
|
||||
{file = "pydantic-1.10.17-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:820ae12a390c9cbb26bb44913c87fa2ff431a029a785642c1ff11fed0a095fcb"},
|
||||
{file = "pydantic-1.10.17-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c1e51d1af306641b7d1574d6d3307eaa10a4991542ca324f0feb134fee259815"},
|
||||
{file = "pydantic-1.10.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e53fb834aae96e7b0dadd6e92c66e7dd9cdf08965340ed04c16813102a47fab"},
|
||||
{file = "pydantic-1.10.17-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2495309b1266e81d259a570dd199916ff34f7f51f1b549a0d37a6d9b17b4dc"},
|
||||
{file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:098ad8de840c92ea586bf8efd9e2e90c6339d33ab5c1cfbb85be66e4ecf8213f"},
|
||||
{file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:525bbef620dac93c430d5d6bdbc91bdb5521698d434adf4434a7ef6ffd5c4b7f"},
|
||||
{file = "pydantic-1.10.17-cp312-cp312-win_amd64.whl", hash = "sha256:6654028d1144df451e1da69a670083c27117d493f16cf83da81e1e50edce72ad"},
|
||||
{file = "pydantic-1.10.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c87cedb4680d1614f1d59d13fea353faf3afd41ba5c906a266f3f2e8c245d655"},
|
||||
{file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11289fa895bcbc8f18704efa1d8020bb9a86314da435348f59745473eb042e6b"},
|
||||
{file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94833612d6fd18b57c359a127cbfd932d9150c1b72fea7c86ab58c2a77edd7c7"},
|
||||
{file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d4ecb515fa7cb0e46e163ecd9d52f9147ba57bc3633dca0e586cdb7a232db9e3"},
|
||||
{file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7017971ffa7fd7808146880aa41b266e06c1e6e12261768a28b8b41ba55c8076"},
|
||||
{file = "pydantic-1.10.17-cp37-cp37m-win_amd64.whl", hash = "sha256:e840e6b2026920fc3f250ea8ebfdedf6ea7a25b77bf04c6576178e681942ae0f"},
|
||||
{file = "pydantic-1.10.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bfbb18b616abc4df70591b8c1ff1b3eabd234ddcddb86b7cac82657ab9017e33"},
|
||||
{file = "pydantic-1.10.17-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb249096d873593e014535ab07145498957091aa6ae92759a32d40cb9998e2e"},
|
||||
{file = "pydantic-1.10.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c209af63ccd7b22fba94b9024e8b7fd07feffee0001efae50dd99316b27768"},
|
||||
{file = "pydantic-1.10.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b40c9e13a0b61583e5599e7950490c700297b4a375b55b2b592774332798b7"},
|
||||
{file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c31d281c7485223caf6474fc2b7cf21456289dbaa31401844069b77160cab9c7"},
|
||||
{file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae5184e99a060a5c80010a2d53c99aee76a3b0ad683d493e5f0620b5d86eeb75"},
|
||||
{file = "pydantic-1.10.17-cp38-cp38-win_amd64.whl", hash = "sha256:ad1e33dc6b9787a6f0f3fd132859aa75626528b49cc1f9e429cdacb2608ad5f0"},
|
||||
{file = "pydantic-1.10.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e17c0ee7192e54a10943f245dc79e36d9fe282418ea05b886e1c666063a7b54"},
|
||||
{file = "pydantic-1.10.17-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cafb9c938f61d1b182dfc7d44a7021326547b7b9cf695db5b68ec7b590214773"},
|
||||
{file = "pydantic-1.10.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95ef534e3c22e5abbdbdd6f66b6ea9dac3ca3e34c5c632894f8625d13d084cbe"},
|
||||
{file = "pydantic-1.10.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d96b8799ae3d782df7ec9615cb59fc32c32e1ed6afa1b231b0595f6516e8ab"},
|
||||
{file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ab2f976336808fd5d539fdc26eb51f9aafc1f4b638e212ef6b6f05e753c8011d"},
|
||||
{file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8ad363330557beac73159acfbeed220d5f1bfcd6b930302a987a375e02f74fd"},
|
||||
{file = "pydantic-1.10.17-cp39-cp39-win_amd64.whl", hash = "sha256:48db882e48575ce4b39659558b2f9f37c25b8d348e37a2b4e32971dd5a7d6227"},
|
||||
{file = "pydantic-1.10.17-py3-none-any.whl", hash = "sha256:e41b5b973e5c64f674b3b4720286ded184dcc26a691dd55f34391c62c6934688"},
|
||||
{file = "pydantic-1.10.17.tar.gz", hash = "sha256:f434160fb14b353caf634149baaf847206406471ba70e64657c1e8330277a991"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -1279,15 +1414,32 @@ typing-extensions = ">=4.2.0"
|
||||
dotenv = ["python-dotenv (>=0.10.4)"]
|
||||
email = ["email-validator (>=1.0.3)"]
|
||||
|
||||
[[package]]
|
||||
name = "pyjwt"
|
||||
version = "2.9.0"
|
||||
description = "JSON Web Token implementation in Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"},
|
||||
{file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
crypto = ["cryptography (>=3.4.0)"]
|
||||
dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"]
|
||||
docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"]
|
||||
tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "8.0.1"
|
||||
version = "8.3.2"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pytest-8.0.1-py3-none-any.whl", hash = "sha256:3e4f16fe1c0a9dc9d9389161c127c3edc5d810c38d6793042fb81d9f48a59fca"},
|
||||
{file = "pytest-8.0.1.tar.gz", hash = "sha256:267f6563751877d772019b13aacbe4e860d73fe8f651f28112e9ac37de7513ae"},
|
||||
{file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"},
|
||||
{file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -1295,11 +1447,47 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
|
||||
iniconfig = "*"
|
||||
packaging = "*"
|
||||
pluggy = ">=1.3.0,<2.0"
|
||||
tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
|
||||
pluggy = ">=1.5,<2"
|
||||
tomli = {version = ">=1", markers = "python_version < \"3.11\""}
|
||||
|
||||
[package.extras]
|
||||
testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
||||
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
||||
|
||||
[[package]]
|
||||
name = "python-jose"
|
||||
version = "3.3.0"
|
||||
description = "JOSE implementation in Python"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "python-jose-3.3.0.tar.gz", hash = "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a"},
|
||||
{file = "python_jose-3.3.0-py2.py3-none-any.whl", hash = "sha256:9b1376b023f8b298536eedd47ae1089bcdb848f1535ab30555cd92002d78923a"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
cryptography = {version = ">=3.4.0", optional = true, markers = "extra == \"cryptography\""}
|
||||
ecdsa = "!=0.15"
|
||||
pyasn1 = "*"
|
||||
rsa = "*"
|
||||
|
||||
[package.extras]
|
||||
cryptography = ["cryptography (>=3.4.0)"]
|
||||
pycrypto = ["pyasn1", "pycrypto (>=2.6.0,<2.7.0)"]
|
||||
pycryptodome = ["pyasn1", "pycryptodome (>=3.3.1,<4.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "python-multipart"
|
||||
version = "0.0.9"
|
||||
description = "A streaming multipart parser for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "python_multipart-0.0.9-py3-none-any.whl", hash = "sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215"},
|
||||
{file = "python_multipart-0.0.9.tar.gz", hash = "sha256:03f54688c663f1b7977105f021043b0793151e4cb1c1a9d4a11fc13d622c4026"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["atomicwrites (==1.4.1)", "attrs (==23.2.0)", "coverage (==7.4.1)", "hatch", "invoke (==2.2.0)", "more-itertools (==10.2.0)", "pbr (==6.0.0)", "pluggy (==1.4.0)", "py (==1.11.0)", "pytest (==8.0.0)", "pytest-cov (==4.1.0)", "pytest-timeout (==2.2.0)", "pyyaml (==6.0.1)", "ruff (==0.2.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
@ -1363,32 +1551,32 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "redis"
|
||||
version = "5.0.1"
|
||||
version = "5.0.8"
|
||||
description = "Python client for Redis database and key-value store"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "redis-5.0.1-py3-none-any.whl", hash = "sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f"},
|
||||
{file = "redis-5.0.1.tar.gz", hash = "sha256:0dab495cd5753069d3bc650a0dde8a8f9edde16fc5691b689a566eda58100d0f"},
|
||||
{file = "redis-5.0.8-py3-none-any.whl", hash = "sha256:56134ee08ea909106090934adc36f65c9bcbbaecea5b21ba704ba6fb561f8eb4"},
|
||||
{file = "redis-5.0.8.tar.gz", hash = "sha256:0c5b10d387568dfe0698c6fad6615750c24170e548ca2deac10c649d463e9870"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2\""}
|
||||
hiredis = {version = ">=1.0.0", optional = true, markers = "extra == \"hiredis\""}
|
||||
async-timeout = {version = ">=4.0.3", markers = "python_full_version < \"3.11.3\""}
|
||||
hiredis = {version = ">1.0.0", optional = true, markers = "extra == \"hiredis\""}
|
||||
|
||||
[package.extras]
|
||||
hiredis = ["hiredis (>=1.0.0)"]
|
||||
hiredis = ["hiredis (>1.0.0)"]
|
||||
ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.31.0"
|
||||
version = "2.32.3"
|
||||
description = "Python HTTP for Humans."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
|
||||
{file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
|
||||
{file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
|
||||
{file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -1401,6 +1589,31 @@ urllib3 = ">=1.21.1,<3"
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
|
||||
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
||||
|
||||
[[package]]
|
||||
name = "rsa"
|
||||
version = "4.9"
|
||||
description = "Pure-Python RSA implementation"
|
||||
optional = false
|
||||
python-versions = ">=3.6,<4"
|
||||
files = [
|
||||
{file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"},
|
||||
{file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pyasn1 = ">=0.1.3"
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
files = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sniffio"
|
||||
version = "1.3.0"
|
||||
@ -1425,64 +1638,64 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlalchemy"
|
||||
version = "2.0.25"
|
||||
version = "2.0.32"
|
||||
description = "Database Abstraction Library"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4344d059265cc8b1b1be351bfb88749294b87a8b2bbe21dfbe066c4199541ebd"},
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6f9e2e59cbcc6ba1488404aad43de005d05ca56e069477b33ff74e91b6319735"},
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84daa0a2055df9ca0f148a64fdde12ac635e30edbca80e87df9b3aaf419e144a"},
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc8b7dabe8e67c4832891a5d322cec6d44ef02f432b4588390017f5cec186a84"},
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f5693145220517b5f42393e07a6898acdfe820e136c98663b971906120549da5"},
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db854730a25db7c956423bb9fb4bdd1216c839a689bf9cc15fada0a7fb2f4570"},
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-win32.whl", hash = "sha256:14a6f68e8fc96e5e8f5647ef6cda6250c780612a573d99e4d881581432ef1669"},
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-win_amd64.whl", hash = "sha256:87f6e732bccd7dcf1741c00f1ecf33797383128bd1c90144ac8adc02cbb98643"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:342d365988ba88ada8af320d43df4e0b13a694dbd75951f537b2d5e4cb5cd002"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f37c0caf14b9e9b9e8f6dbc81bc56db06acb4363eba5a633167781a48ef036ed"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa9373708763ef46782d10e950b49d0235bfe58facebd76917d3f5cbf5971aed"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d24f571990c05f6b36a396218f251f3e0dda916e0c687ef6fdca5072743208f5"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75432b5b14dc2fff43c50435e248b45c7cdadef73388e5610852b95280ffd0e9"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:884272dcd3ad97f47702965a0e902b540541890f468d24bd1d98bcfe41c3f018"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-win32.whl", hash = "sha256:e607cdd99cbf9bb80391f54446b86e16eea6ad309361942bf88318bcd452363c"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d505815ac340568fd03f719446a589162d55c52f08abd77ba8964fbb7eb5b5f"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0dacf67aee53b16f365c589ce72e766efaabd2b145f9de7c917777b575e3659d"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b801154027107461ee992ff4b5c09aa7cc6ec91ddfe50d02bca344918c3265c6"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59a21853f5daeb50412d459cfb13cb82c089ad4c04ec208cd14dddd99fc23b39"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29049e2c299b5ace92cbed0c1610a7a236f3baf4c6b66eb9547c01179f638ec5"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b64b183d610b424a160b0d4d880995e935208fc043d0302dd29fee32d1ee3f95"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4f7a7d7fcc675d3d85fbf3b3828ecd5990b8d61bd6de3f1b260080b3beccf215"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-win32.whl", hash = "sha256:cf18ff7fc9941b8fc23437cc3e68ed4ebeff3599eec6ef5eebf305f3d2e9a7c2"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-win_amd64.whl", hash = "sha256:91f7d9d1c4dd1f4f6e092874c128c11165eafcf7c963128f79e28f8445de82d5"},
|
||||
{file = "SQLAlchemy-2.0.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bb209a73b8307f8fe4fe46f6ad5979649be01607f11af1eb94aa9e8a3aaf77f0"},
|
||||
{file = "SQLAlchemy-2.0.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:798f717ae7c806d67145f6ae94dc7c342d3222d3b9a311a784f371a4333212c7"},
|
||||
{file = "SQLAlchemy-2.0.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fdd402169aa00df3142149940b3bf9ce7dde075928c1886d9a1df63d4b8de62"},
|
||||
{file = "SQLAlchemy-2.0.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0d3cab3076af2e4aa5693f89622bef7fa770c6fec967143e4da7508b3dceb9b9"},
|
||||
{file = "SQLAlchemy-2.0.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:74b080c897563f81062b74e44f5a72fa44c2b373741a9ade701d5f789a10ba23"},
|
||||
{file = "SQLAlchemy-2.0.25-cp37-cp37m-win32.whl", hash = "sha256:87d91043ea0dc65ee583026cb18e1b458d8ec5fc0a93637126b5fc0bc3ea68c4"},
|
||||
{file = "SQLAlchemy-2.0.25-cp37-cp37m-win_amd64.whl", hash = "sha256:75f99202324383d613ddd1f7455ac908dca9c2dd729ec8584c9541dd41822a2c"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:420362338681eec03f53467804541a854617faed7272fe71a1bfdb07336a381e"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c88f0c7dcc5f99bdb34b4fd9b69b93c89f893f454f40219fe923a3a2fd11625"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3be4987e3ee9d9a380b66393b77a4cd6d742480c951a1c56a23c335caca4ce3"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a159111a0f58fb034c93eeba211b4141137ec4b0a6e75789ab7a3ef3c7e7e3"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8b8cb63d3ea63b29074dcd29da4dc6a97ad1349151f2d2949495418fd6e48db9"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:736ea78cd06de6c21ecba7416499e7236a22374561493b456a1f7ffbe3f6cdb4"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-win32.whl", hash = "sha256:10331f129982a19df4284ceac6fe87353ca3ca6b4ca77ff7d697209ae0a5915e"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-win_amd64.whl", hash = "sha256:c55731c116806836a5d678a70c84cb13f2cedba920212ba7dcad53260997666d"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:605b6b059f4b57b277f75ace81cc5bc6335efcbcc4ccb9066695e515dbdb3900"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:665f0a3954635b5b777a55111ababf44b4fc12b1f3ba0a435b602b6387ffd7cf"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecf6d4cda1f9f6cb0b45803a01ea7f034e2f1aed9475e883410812d9f9e3cfcf"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c51db269513917394faec5e5c00d6f83829742ba62e2ac4fa5c98d58be91662f"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:790f533fa5c8901a62b6fef5811d48980adeb2f51f1290ade8b5e7ba990ba3de"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1b1180cda6df7af84fe72e4530f192231b1f29a7496951db4ff38dac1687202d"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-win32.whl", hash = "sha256:555651adbb503ac7f4cb35834c5e4ae0819aab2cd24857a123370764dc7d7e24"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-win_amd64.whl", hash = "sha256:dc55990143cbd853a5d038c05e79284baedf3e299661389654551bd02a6a68d7"},
|
||||
{file = "SQLAlchemy-2.0.25-py3-none-any.whl", hash = "sha256:a86b4240e67d4753dc3092d9511886795b3c2852abe599cffe108952f7af7ac3"},
|
||||
{file = "SQLAlchemy-2.0.25.tar.gz", hash = "sha256:a2c69a7664fb2d54b8682dd774c3b54f67f84fa123cf84dda2a5f40dcaa04e08"},
|
||||
{file = "SQLAlchemy-2.0.32-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0c9045ecc2e4db59bfc97b20516dfdf8e41d910ac6fb667ebd3a79ea54084619"},
|
||||
{file = "SQLAlchemy-2.0.32-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1467940318e4a860afd546ef61fefb98a14d935cd6817ed07a228c7f7c62f389"},
|
||||
{file = "SQLAlchemy-2.0.32-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5954463675cb15db8d4b521f3566a017c8789222b8316b1e6934c811018ee08b"},
|
||||
{file = "SQLAlchemy-2.0.32-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:167e7497035c303ae50651b351c28dc22a40bb98fbdb8468cdc971821b1ae533"},
|
||||
{file = "SQLAlchemy-2.0.32-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b27dfb676ac02529fb6e343b3a482303f16e6bc3a4d868b73935b8792edb52d0"},
|
||||
{file = "SQLAlchemy-2.0.32-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bf2360a5e0f7bd75fa80431bf8ebcfb920c9f885e7956c7efde89031695cafb8"},
|
||||
{file = "SQLAlchemy-2.0.32-cp310-cp310-win32.whl", hash = "sha256:306fe44e754a91cd9d600a6b070c1f2fadbb4a1a257b8781ccf33c7067fd3e4d"},
|
||||
{file = "SQLAlchemy-2.0.32-cp310-cp310-win_amd64.whl", hash = "sha256:99db65e6f3ab42e06c318f15c98f59a436f1c78179e6a6f40f529c8cc7100b22"},
|
||||
{file = "SQLAlchemy-2.0.32-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:21b053be28a8a414f2ddd401f1be8361e41032d2ef5884b2f31d31cb723e559f"},
|
||||
{file = "SQLAlchemy-2.0.32-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b178e875a7a25b5938b53b006598ee7645172fccafe1c291a706e93f48499ff5"},
|
||||
{file = "SQLAlchemy-2.0.32-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723a40ee2cc7ea653645bd4cf024326dea2076673fc9d3d33f20f6c81db83e1d"},
|
||||
{file = "SQLAlchemy-2.0.32-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:295ff8689544f7ee7e819529633d058bd458c1fd7f7e3eebd0f9268ebc56c2a0"},
|
||||
{file = "SQLAlchemy-2.0.32-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:49496b68cd190a147118af585173ee624114dfb2e0297558c460ad7495f9dfe2"},
|
||||
{file = "SQLAlchemy-2.0.32-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:acd9b73c5c15f0ec5ce18128b1fe9157ddd0044abc373e6ecd5ba376a7e5d961"},
|
||||
{file = "SQLAlchemy-2.0.32-cp311-cp311-win32.whl", hash = "sha256:9365a3da32dabd3e69e06b972b1ffb0c89668994c7e8e75ce21d3e5e69ddef28"},
|
||||
{file = "SQLAlchemy-2.0.32-cp311-cp311-win_amd64.whl", hash = "sha256:8bd63d051f4f313b102a2af1cbc8b80f061bf78f3d5bd0843ff70b5859e27924"},
|
||||
{file = "SQLAlchemy-2.0.32-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6bab3db192a0c35e3c9d1560eb8332463e29e5507dbd822e29a0a3c48c0a8d92"},
|
||||
{file = "SQLAlchemy-2.0.32-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:19d98f4f58b13900d8dec4ed09dd09ef292208ee44cc9c2fe01c1f0a2fe440e9"},
|
||||
{file = "SQLAlchemy-2.0.32-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd33c61513cb1b7371fd40cf221256456d26a56284e7d19d1f0b9f1eb7dd7e8"},
|
||||
{file = "SQLAlchemy-2.0.32-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6ba0497c1d066dd004e0f02a92426ca2df20fac08728d03f67f6960271feec"},
|
||||
{file = "SQLAlchemy-2.0.32-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2b6be53e4fde0065524f1a0a7929b10e9280987b320716c1509478b712a7688c"},
|
||||
{file = "SQLAlchemy-2.0.32-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:916a798f62f410c0b80b63683c8061f5ebe237b0f4ad778739304253353bc1cb"},
|
||||
{file = "SQLAlchemy-2.0.32-cp312-cp312-win32.whl", hash = "sha256:31983018b74908ebc6c996a16ad3690301a23befb643093fcfe85efd292e384d"},
|
||||
{file = "SQLAlchemy-2.0.32-cp312-cp312-win_amd64.whl", hash = "sha256:4363ed245a6231f2e2957cccdda3c776265a75851f4753c60f3004b90e69bfeb"},
|
||||
{file = "SQLAlchemy-2.0.32-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b8afd5b26570bf41c35c0121801479958b4446751a3971fb9a480c1afd85558e"},
|
||||
{file = "SQLAlchemy-2.0.32-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c750987fc876813f27b60d619b987b057eb4896b81117f73bb8d9918c14f1cad"},
|
||||
{file = "SQLAlchemy-2.0.32-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ada0102afff4890f651ed91120c1120065663506b760da4e7823913ebd3258be"},
|
||||
{file = "SQLAlchemy-2.0.32-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:78c03d0f8a5ab4f3034c0e8482cfcc415a3ec6193491cfa1c643ed707d476f16"},
|
||||
{file = "SQLAlchemy-2.0.32-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:3bd1cae7519283ff525e64645ebd7a3e0283f3c038f461ecc1c7b040a0c932a1"},
|
||||
{file = "SQLAlchemy-2.0.32-cp37-cp37m-win32.whl", hash = "sha256:01438ebcdc566d58c93af0171c74ec28efe6a29184b773e378a385e6215389da"},
|
||||
{file = "SQLAlchemy-2.0.32-cp37-cp37m-win_amd64.whl", hash = "sha256:4979dc80fbbc9d2ef569e71e0896990bc94df2b9fdbd878290bd129b65ab579c"},
|
||||
{file = "SQLAlchemy-2.0.32-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c742be912f57586ac43af38b3848f7688863a403dfb220193a882ea60e1ec3a"},
|
||||
{file = "SQLAlchemy-2.0.32-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:62e23d0ac103bcf1c5555b6c88c114089587bc64d048fef5bbdb58dfd26f96da"},
|
||||
{file = "SQLAlchemy-2.0.32-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:251f0d1108aab8ea7b9aadbd07fb47fb8e3a5838dde34aa95a3349876b5a1f1d"},
|
||||
{file = "SQLAlchemy-2.0.32-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ef18a84e5116340e38eca3e7f9eeaaef62738891422e7c2a0b80feab165905f"},
|
||||
{file = "SQLAlchemy-2.0.32-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:3eb6a97a1d39976f360b10ff208c73afb6a4de86dd2a6212ddf65c4a6a2347d5"},
|
||||
{file = "SQLAlchemy-2.0.32-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0c1c9b673d21477cec17ab10bc4decb1322843ba35b481585facd88203754fc5"},
|
||||
{file = "SQLAlchemy-2.0.32-cp38-cp38-win32.whl", hash = "sha256:c41a2b9ca80ee555decc605bd3c4520cc6fef9abde8fd66b1cf65126a6922d65"},
|
||||
{file = "SQLAlchemy-2.0.32-cp38-cp38-win_amd64.whl", hash = "sha256:8a37e4d265033c897892279e8adf505c8b6b4075f2b40d77afb31f7185cd6ecd"},
|
||||
{file = "SQLAlchemy-2.0.32-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:52fec964fba2ef46476312a03ec8c425956b05c20220a1a03703537824b5e8e1"},
|
||||
{file = "SQLAlchemy-2.0.32-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:328429aecaba2aee3d71e11f2477c14eec5990fb6d0e884107935f7fb6001632"},
|
||||
{file = "SQLAlchemy-2.0.32-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85a01b5599e790e76ac3fe3aa2f26e1feba56270023d6afd5550ed63c68552b3"},
|
||||
{file = "SQLAlchemy-2.0.32-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaf04784797dcdf4c0aa952c8d234fa01974c4729db55c45732520ce12dd95b4"},
|
||||
{file = "SQLAlchemy-2.0.32-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4488120becf9b71b3ac718f4138269a6be99a42fe023ec457896ba4f80749525"},
|
||||
{file = "SQLAlchemy-2.0.32-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:14e09e083a5796d513918a66f3d6aedbc131e39e80875afe81d98a03312889e6"},
|
||||
{file = "SQLAlchemy-2.0.32-cp39-cp39-win32.whl", hash = "sha256:0d322cc9c9b2154ba7e82f7bf25ecc7c36fbe2d82e2933b3642fc095a52cfc78"},
|
||||
{file = "SQLAlchemy-2.0.32-cp39-cp39-win_amd64.whl", hash = "sha256:7dd8583df2f98dea28b5cd53a1beac963f4f9d087888d75f22fcc93a07cf8d84"},
|
||||
{file = "SQLAlchemy-2.0.32-py3-none-any.whl", hash = "sha256:e567a8793a692451f706b363ccf3c45e056b67d90ead58c3bc9471af5d212202"},
|
||||
{file = "SQLAlchemy-2.0.32.tar.gz", hash = "sha256:c1b88cc8b02b6a5f0efb0345a03672d4c897dc7d92585176f88c67346f565ea8"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""}
|
||||
greenlet = {version = "!=0.4.17", markers = "python_version < \"3.13\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"}
|
||||
typing-extensions = ">=4.6.0"
|
||||
|
||||
[package.extras]
|
||||
@ -1585,13 +1798,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "tqdm"
|
||||
version = "4.66.2"
|
||||
version = "4.66.4"
|
||||
description = "Fast, Extensible Progress Meter"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "tqdm-4.66.2-py3-none-any.whl", hash = "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9"},
|
||||
{file = "tqdm-4.66.2.tar.gz", hash = "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531"},
|
||||
{file = "tqdm-4.66.4-py3-none-any.whl", hash = "sha256:b75ca56b413b030bc3f00af51fd2c1a1a5eac6a0c1cca83cbb37a5c52abce644"},
|
||||
{file = "tqdm-4.66.4.tar.gz", hash = "sha256:e4d936c9de8727928f3be6079590e97d9abfe8d39a590be678eb5919ffc186bb"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -1625,13 +1838,13 @@ sortedcontainers = "*"
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.9.0"
|
||||
version = "4.12.2"
|
||||
description = "Backported and Experimental Type Hints for Python 3.8+"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"},
|
||||
{file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
|
||||
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
|
||||
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1651,13 +1864,13 @@ typing-extensions = ">=3.7.4"
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.2.1"
|
||||
version = "2.2.2"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"},
|
||||
{file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"},
|
||||
{file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"},
|
||||
{file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@ -1819,4 +2032,4 @@ multidict = ">=4.0"
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.10,<4.0"
|
||||
content-hash = "c085bc80e7b0d147608ea5176a48d6a657f3f2e4719777540c6eb645a1100acf"
|
||||
content-hash = "613f4b72cb2c76dde4e3319cc6434026566e862fc8d515932d99a774bcc2d90f"
|
||||
|
||||
@ -23,21 +23,27 @@ build-backend = "poetry.core.masonry.api"
|
||||
[tool.poetry.dependencies]
|
||||
python=">=3.10,<4.0"
|
||||
asyncio = "^3.4.3"
|
||||
packaging = "^23.2"
|
||||
pydantic = "^1.10.14"
|
||||
packaging = "^24.1"
|
||||
pydantic = "^1.10.17"
|
||||
sse-starlette = "^1.8.2"
|
||||
starlette = "^0.26.1"
|
||||
typing-extensions = "^4.9.0"
|
||||
urllib3 = "^2.2.1"
|
||||
typing-extensions = "^4.12.2"
|
||||
urllib3 = "^2.2.2"
|
||||
fastapi = "^0.95.1"
|
||||
huggingface-hub = "^0.20.3"
|
||||
requests = "^2.31.0"
|
||||
huggingface-hub = "^0.24.5"
|
||||
requests = "^2.32.3"
|
||||
langchain = "^0.0.180"
|
||||
loguru = "^0.7.2"
|
||||
redis = {extras = ["hiredis"], version = "^5.0.1"}
|
||||
pytest = "^8.0.1"
|
||||
hypercorn = {extras = ["trio"], version = "^0.16.0"}
|
||||
redis = {extras = ["hiredis"], version = "^5.0.8"}
|
||||
pytest = "^8.3.2"
|
||||
hypercorn = {extras = ["trio"], version = "^0.17.3"}
|
||||
|
||||
pyjwt = "^2.9.0"
|
||||
python-jose = {extras = ["cryptography"], version = "^3.3.0"}
|
||||
aiofiles = "^24.1.0"
|
||||
python-multipart = "^0.0.9"
|
||||
debugpy = "^1.8.5"
|
||||
sqlalchemy = "^2.0.32"
|
||||
[tool.ruff]
|
||||
# Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default.
|
||||
select = ["E", "F"]
|
||||
|
||||
110
api/src/serge/crud.py
Normal file
110
api/src/serge/crud.py
Normal file
@ -0,0 +1,110 @@
|
||||
import logging
|
||||
import uuid
|
||||
from typing import List, Optional
|
||||
|
||||
from serge.schema import user as user_schema
|
||||
from serge.utils.security import get_password_hash
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from serge.models import user as user_model
|
||||
|
||||
|
||||
def get_user(db: Session, username: str) -> Optional[user_schema.User]:
|
||||
return Mappers.user_db_to_view(
|
||||
db.query(user_model.User).filter(user_model.User.username == username).first(),
|
||||
include_auth=True,
|
||||
)
|
||||
|
||||
|
||||
def get_user_by_email(db: Session, email: str) -> Optional[user_schema.User]:
|
||||
return Mappers.user_db_to_view(db.query(user_model.User).filter(user_model.User.email == email).first())
|
||||
|
||||
|
||||
def get_users(db: Session, skip: int = 0, limit: int = 100) -> List[user_schema.User]:
|
||||
return [Mappers.user_db_to_view(u) for u in db.query(user_model.User).offset(skip).limit(limit).all()]
|
||||
|
||||
|
||||
def create_user(db: Session, ua: user_schema.UserAuth) -> Optional[user_schema.User]:
|
||||
# Check already exists
|
||||
if get_user(db, ua.username):
|
||||
logging.error(f"Tried to create new user, but already exists: {ua.username}")
|
||||
return None
|
||||
|
||||
match ua.auth_type:
|
||||
case 1:
|
||||
ua.secret = get_password_hash(ua.secret)
|
||||
case _: # Todo: More auth types
|
||||
return None
|
||||
|
||||
db_user, db_user_auth = Mappers.user_view_to_db(None, ua)
|
||||
db.add(db_user_auth)
|
||||
db.add(db_user)
|
||||
db.commit()
|
||||
return Mappers.user_db_to_view(db_user)
|
||||
|
||||
|
||||
def update_user(db: Session, u: user_schema.User) -> Optional[user_schema.User]:
|
||||
user = db.query(user_model.User).filter(user_model.User.username == u.username).first()
|
||||
if not user:
|
||||
return None
|
||||
for k, v in u.dict().items():
|
||||
if k in ["auth", "chats"]:
|
||||
continue
|
||||
setattr(user, k, v)
|
||||
db.commit()
|
||||
return user
|
||||
|
||||
|
||||
def create_chat(db: Session, chat: user_schema.Chat):
|
||||
c = user_model.Chat(owner=chat.owner, chat_id=chat.chat_id)
|
||||
db.add(c)
|
||||
db.commit()
|
||||
|
||||
|
||||
def remove_chat(db: Session, chat: user_schema.Chat):
|
||||
c = db.query(user_model.Chat).filter(user_model.Chat.chat_id == chat.chat_id).one()
|
||||
db.delete(c)
|
||||
db.commit()
|
||||
|
||||
|
||||
class Mappers:
|
||||
@staticmethod
|
||||
def user_db_to_view(u: user_model.User, include_auth=False) -> user_schema.User:
|
||||
if not u:
|
||||
return None
|
||||
auths = chats = []
|
||||
if include_auth:
|
||||
auths = u.auth
|
||||
# u.auth = []
|
||||
chats = u.chats
|
||||
# u.chats = []
|
||||
app_user = user_schema.User(**{k: v for k, v in u.__dict__.items() if not k.startswith("_") and k not in ["chats", "auth"]})
|
||||
|
||||
app_user.auth = [user_schema.UserAuth(username=u.username, secret=x.secret, auth_type=x.auth_type) for x in auths]
|
||||
|
||||
app_user.chats = [user_schema.Chat(chat_id=x.chat_id, owner=x.owner) for x in chats]
|
||||
|
||||
return app_user
|
||||
|
||||
@staticmethod
|
||||
def user_view_to_db(
|
||||
u: Optional[user_schema.User] = None, ua: Optional[user_schema.UserAuth] = None
|
||||
) -> (user_model.User, Optional[user_model.UserAuth]):
|
||||
assert u or ua, "One of User or UserAuth must be passed"
|
||||
if not u: # Creating a new user
|
||||
u = user_schema.User(id=uuid.uuid4(), username=ua.username)
|
||||
auth = []
|
||||
if ua:
|
||||
auth = Mappers.user_auth_view_to_db(ua, u.id)
|
||||
user = user_model.User(**u.dict())
|
||||
if auth:
|
||||
user.auth.append(auth)
|
||||
for chat in u.chats:
|
||||
user.chats.append(user_model.Chat(chat_id=chat.chat_id))
|
||||
return (user, auth)
|
||||
|
||||
@staticmethod
|
||||
def user_auth_view_to_db(ua: user_schema.UserAuth, user_id: uuid.UUID) -> user_model.UserAuth:
|
||||
if not ua:
|
||||
return None
|
||||
return user_model.UserAuth(secret=ua.secret, auth_type=ua.auth_type, user_id=user_id)
|
||||
@ -161,7 +161,23 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "Codesstral",
|
||||
"models": [
|
||||
{
|
||||
"name": "Codestral-22B-v0.1",
|
||||
"repo": "bartowski/Codestral-22B-v0.1-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "Codestral-22B-v0.1-Q4_K_M.gguf",
|
||||
"disk_space": 15722553696.0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Falcon",
|
||||
"models": [
|
||||
@ -226,13 +242,13 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Gemma-2B-Instruct",
|
||||
"repo": "brittlewis12/gemma-2b-it-GGUF",
|
||||
"name": "Gemma-1_1-2B-Instruct",
|
||||
"repo": "brittlewis12/gemma-1.1-2b-it-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "gemma-2b-it.Q4_K_M.gguf",
|
||||
"disk_space": 1630263008.0
|
||||
"filename": "gemma-1.1-2b-it.Q4_K_M.gguf",
|
||||
"disk_space": 1630263200.0
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -248,18 +264,67 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Gemma-7B-Instruct",
|
||||
"repo": "brittlewis12/gemma-7b-it-GGUF",
|
||||
"name": "Gemma-1_1-7B-Instruct",
|
||||
"repo": "brittlewis12/gemma-1.1-7b-it-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "gemma-7b-it.Q4_K_M.gguf",
|
||||
"filename": "gemma-1.1-7b-it.Q4_K_M.gguf",
|
||||
"disk_space": 5329759200.0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Gorilla",
|
||||
"models": [
|
||||
{
|
||||
"name": "Gorilla-7B Falcon",
|
||||
"repo": "gorilla-llm/gorilla-falcon-7b-hf-v0-gguf",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "gorilla-falcon-7b-hf-v0-q4_K_M.gguf",
|
||||
"disk_space": 4975125696.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Gorilla-7B",
|
||||
"repo": "gorilla-llm/gorilla-7b-hf-v1-gguf",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "gorilla-7b-hf-v1-q4_K_M.gguf",
|
||||
"disk_space": 4081004288.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Gorilla OpenFunctions V1",
|
||||
"repo": "gorilla-llm/gorilla-openfunctions-v1-gguf",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "gorilla-openfunctions-v1-q4_K_M.gguf",
|
||||
"disk_space": 4081004288.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Gorilla OpenFunctions V2",
|
||||
"repo": "gorilla-llm/gorilla-openfunctions-v2-gguf",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "gorilla-openfunctions-v2-q4_K_M.gguf",
|
||||
"disk_space": 4223770912.0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LLaMA_2",
|
||||
"models": [
|
||||
@ -353,6 +418,44 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LLaMA_3",
|
||||
"models": [
|
||||
{
|
||||
"name": "Llama-3-11B-Instruct-v0.1",
|
||||
"repo": "MaziyarPanahi/Llama-3-11B-Instruct-v0.1-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "Llama-3-11B-Instruct-v0.1.Q4_K_M.gguf",
|
||||
"disk_space": 8200021632.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Llama-3-13B-Instruct-v0.1",
|
||||
"repo": "MaziyarPanahi/Llama-3-13B-Instruct-v0.1-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "Llama-3-13B-Instruct-v0.1.Q4_K_M.gguf",
|
||||
"disk_space": 8061089600.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Llama-3-16B-Instruct-v0.1",
|
||||
"repo": "MaziyarPanahi/Llama-3-16B-Instruct-v0.1-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "Llama-3-16B-Instruct-v0.1.Q4_K_M.gguf",
|
||||
"disk_space": 10154318048.0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LLaMA-Pro",
|
||||
"models": [
|
||||
@ -487,7 +590,56 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "Meta-Llama-3",
|
||||
"models": [
|
||||
{
|
||||
"name": "Meta-Llama-3-8B",
|
||||
"repo": "QuantFactory/Meta-Llama-3-8B-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "Meta-Llama-3-8B.Q4_K_M.gguf",
|
||||
"disk_space": 4921246944.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Meta-Llama-3-8B-Instruct",
|
||||
"repo": "QuantFactory/Meta-Llama-3-8B-Instruct-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "Meta-Llama-3-8B-Instruct.Q4_K_M.gguf",
|
||||
"disk_space": 4921246944.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Meta-Llama-3-70B",
|
||||
"repo": "NousResearch/Meta-Llama-3-70B-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "Meta-Llama-3-70B-Q4_K_M.gguf",
|
||||
"disk_space": 42520906176.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Meta-Llama-3-70B-Instruct",
|
||||
"repo": "QuantFactory/Meta-Llama-3-70B-Instruct-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "Meta-Llama-3-70B-Instruct.Q4_K_M.gguf",
|
||||
"disk_space": 42520906208.0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Mistral",
|
||||
"models": [
|
||||
@ -681,7 +833,67 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "OpenCodeInterpreter",
|
||||
"models": [
|
||||
{
|
||||
"name": "OpenCodeInterpreter-DS-6.7B",
|
||||
"repo": "LoneStriker/OpenCodeInterpreter-DS-6.7B-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "OpenCodeInterpreter-DS-6.7B-Q4_K_M.gguf",
|
||||
"disk_space": 4083016864.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OpenCodeInterpreter-DS-33B",
|
||||
"repo": "LoneStriker/OpenCodeInterpreter-DS-33B-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "OpenCodeInterpreter-DS-33B-Q4_K_M.gguf",
|
||||
"disk_space": 19940659200.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OpenCodeInterpreter-CL-7B",
|
||||
"repo": "LoneStriker/OpenCodeInterpreter-CL-7B-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "OpenCodeInterpreter-CL-7B-Q4_K_M.gguf",
|
||||
"disk_space": 4081095360.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OpenCodeInterpreter-CL-13B",
|
||||
"repo": "LoneStriker/OpenCodeInterpreter-CL-13B-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "OpenCodeInterpreter-CL-13B-Q4_K_M.gguf",
|
||||
"disk_space": 7866070048.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OpenCodeInterpreter-CL-70B",
|
||||
"repo": "LoneStriker/OpenCodeInterpreter-CL-70B-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "OpenCodeInterpreter-CL-70B-Q4_K_M.gguf",
|
||||
"disk_space": 41423092096.0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OpenLLaMA",
|
||||
"models": [
|
||||
@ -760,6 +972,39 @@
|
||||
"disk_space": 1789239136.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Phi-3-mini-4k-instruct-v0_3",
|
||||
"repo": "bartowski/Phi-3-mini-4k-instruct-v0.3-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "Phi-3-mini-4k-instruct-v0.3-Q4_K_M.gguf",
|
||||
"disk_space": 2393231456.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Phi-3-medium-4k-instruct",
|
||||
"repo": "bartowski/Phi-3-medium-4k-instruct-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "Phi-3-medium-4k-instruct-Q4_K_M.gguf",
|
||||
"disk_space": 8566820736.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Phi-3-medium-128k-instruct",
|
||||
"repo": "bartowski/Phi-3-medium-128k-instruct-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "Phi-3-medium-128k-instruct-Q4_K_M.gguf",
|
||||
"disk_space": 8566821408.0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -849,6 +1094,33 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SOLAR",
|
||||
"models": [
|
||||
{
|
||||
"name": "SOLAR-10.7B-V1_0",
|
||||
"repo": "TheBloke/SOLAR-10.7B-v1.0-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "solar-10.7b-v1.0.Q4_K_M.gguf",
|
||||
"disk_space": 6461667488.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SOLAR-10.7B-instruct-V1_0",
|
||||
"repo": "TheBloke/SOLAR-10.7B-Instruct-v1.0-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "solar-10.7b-instruct-v1.0.Q4_K_M.gguf",
|
||||
"disk_space": 6461667936.0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Tinyllama",
|
||||
"models": [
|
||||
@ -918,13 +1190,13 @@
|
||||
"name": "WizardLM",
|
||||
"models": [
|
||||
{
|
||||
"name": "WizardLM-7B-v1_0",
|
||||
"repo": "TheBloke/wizardLM-7B-GGUF",
|
||||
"name": "WizardLM-2-7B",
|
||||
"repo": "MaziyarPanahi/WizardLM-2-7B-GGUF",
|
||||
"files": [
|
||||
{
|
||||
"name": "q4_K_M",
|
||||
"filename": "wizardLM-7B.Q4_K_M.gguf",
|
||||
"disk_space": 4081009920.0
|
||||
"filename": "WizardLM-2-7B.Q4_K_M.gguf",
|
||||
"disk_space": 4368439008.0
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
31
api/src/serge/database.py
Normal file
31
api/src/serge/database.py
Normal file
@ -0,0 +1,31 @@
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
from serge.models.settings import Settings
|
||||
from serge.models.user import User, UserAuth
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import Session, sessionmaker
|
||||
|
||||
settings = Settings()
|
||||
|
||||
engine = create_engine(settings.SERGE_DATABASE_URL, connect_args={"check_same_thread": False})
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
|
||||
|
||||
def seed_db(db: Session):
|
||||
sys_u = db.query(User).filter(User.username == "system").first()
|
||||
if sys_u:
|
||||
return
|
||||
system_user = User(
|
||||
id=uuid.uuid4(),
|
||||
username="system",
|
||||
email="",
|
||||
full_name="Default User",
|
||||
theme_light=False,
|
||||
default_prompt="Below is an instruction that describes a task. Write a response that appropriately completes the request.",
|
||||
is_active=True,
|
||||
auth=[UserAuth(secret="", auth_type=0)],
|
||||
)
|
||||
db.add(system_user)
|
||||
db.commit()
|
||||
logging.info("System user created")
|
||||
@ -5,12 +5,16 @@ from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from loguru import logger
|
||||
from starlette.responses import FileResponse
|
||||
|
||||
from serge.database import SessionLocal, engine, seed_db
|
||||
from serge.models.settings import Settings
|
||||
from serge.routers.auth import auth_router
|
||||
from serge.routers.chat import chat_router
|
||||
from serge.routers.model import model_router
|
||||
from serge.routers.ping import ping_router
|
||||
from serge.routers.user import user_router
|
||||
from starlette.responses import FileResponse
|
||||
|
||||
from serge.models import user as user_models
|
||||
|
||||
# Configure logging settings
|
||||
|
||||
@ -41,12 +45,17 @@ origins = [
|
||||
"http://localhost:9124",
|
||||
]
|
||||
|
||||
# Seed the database
|
||||
user_models.Base.metadata.create_all(bind=engine)
|
||||
|
||||
app = FastAPI(title="Serge", version="0.0.1", description=description, tags_metadata=tags_metadata)
|
||||
|
||||
api_app = FastAPI(title="Serge API")
|
||||
api_app.include_router(chat_router)
|
||||
api_app.include_router(ping_router)
|
||||
api_app.include_router(model_router)
|
||||
api_app.include_router(auth_router)
|
||||
api_app.include_router(user_router)
|
||||
app.mount("/api", api_app)
|
||||
|
||||
# handle serving the frontend as static files in production
|
||||
@ -83,6 +92,9 @@ async def start_database():
|
||||
for file in files:
|
||||
os.remove(WEIGHTS + file)
|
||||
|
||||
db = SessionLocal()
|
||||
seed_db(db)
|
||||
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
|
||||
@ -32,5 +32,5 @@ class ChatParameters(BaseModel):
|
||||
class Chat(BaseModel):
|
||||
id: str = Field(default_factory=lambda: str(uuid4()))
|
||||
created: datetime = Field(default_factory=datetime.now)
|
||||
|
||||
owner: str = Field("system")
|
||||
params: ChatParameters
|
||||
|
||||
@ -1,8 +1,13 @@
|
||||
from os import getenv
|
||||
|
||||
from pydantic import BaseSettings
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
SERGE_DATABASE_URL: str = getenv("SERGE_DATABASE_URL", "sqlite:////data/db/sql_app.db")
|
||||
NODE_ENV: str = "development"
|
||||
SERGE_JWT_SECRET: str = getenv("SERGE_JWT_SECRET", "uF7FGN5uzfGdFiPzR")
|
||||
SERGE_SESSION_EXPIRY: int = getenv("SERGE_SESSION_EXPIRY", 60)
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
40
api/src/serge/models/user.py
Normal file
40
api/src/serge/models/user.py
Normal file
@ -0,0 +1,40 @@
|
||||
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Uuid
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = "users"
|
||||
|
||||
id = Column(Uuid, primary_key=True)
|
||||
username = Column(String, unique=True, index=True)
|
||||
email = Column(String)
|
||||
full_name = Column(String)
|
||||
theme_light = Column(Boolean)
|
||||
default_prompt = Column(String)
|
||||
is_active = Column(Boolean, default=True)
|
||||
|
||||
auth = relationship("UserAuth", back_populates="user", lazy="joined")
|
||||
chats = relationship("Chat", back_populates="user", lazy="joined")
|
||||
|
||||
|
||||
class Chat(Base):
|
||||
__tablename__ = "chats"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
chat_id = Column(String, index=True)
|
||||
owner = Column(String, ForeignKey("users.username"))
|
||||
user = relationship("User", back_populates="chats")
|
||||
|
||||
|
||||
class UserAuth(Base):
|
||||
__tablename__ = "auth"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
secret = Column(String)
|
||||
auth_type = Column(Integer)
|
||||
user_id = Column(Uuid, ForeignKey("users.id"))
|
||||
|
||||
user = relationship("User", back_populates="auth")
|
||||
108
api/src/serge/routers/auth.py
Normal file
108
api/src/serge/routers/auth.py
Normal file
@ -0,0 +1,108 @@
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request, Response, status
|
||||
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||
from jose import JWTError
|
||||
from serge.crud import get_user
|
||||
from serge.database import SessionLocal
|
||||
from serge.schema.user import Token, User
|
||||
from serge.models.settings import Settings
|
||||
from serge.utils.security import create_access_token, decode_access_token, verify_password
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
|
||||
settings = Settings()
|
||||
|
||||
auth_router = APIRouter(
|
||||
prefix="/auth",
|
||||
tags=["auth"],
|
||||
)
|
||||
|
||||
|
||||
def get_db():
|
||||
db = SessionLocal()
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def authenticate_user(username: str, password: str, db: Session) -> Optional[User]:
|
||||
user = get_user(db, username)
|
||||
if not user:
|
||||
return None
|
||||
# Users may have multipe ways to authenticate
|
||||
auths = [a.auth_type for a in user.auth]
|
||||
if 0 in auths: # Default user, passwordless
|
||||
return user
|
||||
if 1 in auths: # Password auth
|
||||
secret = [x for x in user.auth if x.auth_type == 1][0].secret
|
||||
if verify_password(password, secret):
|
||||
return user
|
||||
if 2 in auths: # todo future auths
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
@auth_router.post("/token", response_model=Token)
|
||||
async def login_for_access_token(
|
||||
response: Response,
|
||||
form_data: OAuth2PasswordRequestForm = Depends(),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
user = authenticate_user(form_data.username, form_data.password, db)
|
||||
if not user:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Incorrect username or password",
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
access_token_expires = timedelta(minutes=settings.SERGE_SESSION_EXPIRY)
|
||||
access_token = create_access_token(data={"sub": user.username}, expires_delta=access_token_expires)
|
||||
response.set_cookie(key="token", value=access_token, httponly=True, secure=True, samesite="strict")
|
||||
return {"access_token": access_token, "token_type": "bearer"}
|
||||
|
||||
|
||||
@auth_router.post("/logout")
|
||||
async def logout(response: Response):
|
||||
# Clear the token cookie by setting it to expire immediately
|
||||
response.delete_cookie(key="token")
|
||||
return {"message": "Logged out successfully"}
|
||||
|
||||
|
||||
async def get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)) -> User:
|
||||
credentials_exception = HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Could not validate credentials",
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
try:
|
||||
username = decode_access_token(token)
|
||||
if username is None:
|
||||
raise credentials_exception
|
||||
except JWTError as e:
|
||||
logging.exception(e)
|
||||
raise credentials_exception
|
||||
|
||||
user = get_user(db, username)
|
||||
|
||||
if user is None:
|
||||
raise credentials_exception
|
||||
return user
|
||||
|
||||
|
||||
async def get_current_active_user(request: Request, response: Response, db: Session = Depends(get_db)) -> User:
|
||||
token = request.cookies.get("token")
|
||||
|
||||
if not token:
|
||||
return get_user(db, "system")
|
||||
|
||||
u = None
|
||||
try:
|
||||
u = await get_current_user(token, db)
|
||||
except HTTPException:
|
||||
await logout(response)
|
||||
u = get_user(db, "system")
|
||||
return u
|
||||
@ -1,25 +1,60 @@
|
||||
import os
|
||||
|
||||
from typing import Optional
|
||||
from fastapi import APIRouter, HTTPException
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from langchain.memory import RedisChatMessageHistory
|
||||
from langchain.schema import SystemMessage, messages_to_dict, AIMessage, HumanMessage
|
||||
from langchain.schema import AIMessage, HumanMessage, SystemMessage, messages_to_dict
|
||||
from llama_cpp import Llama
|
||||
from loguru import logger
|
||||
from redis import Redis
|
||||
from sse_starlette.sse import EventSourceResponse
|
||||
|
||||
from serge.crud import create_chat, remove_chat, update_user
|
||||
from serge.database import SessionLocal
|
||||
from serge.models.chat import Chat, ChatParameters
|
||||
from serge.routers.auth import get_current_active_user
|
||||
from serge.schema.user import Chat as UserChat
|
||||
from serge.schema.user import User
|
||||
from serge.utils.stream import get_prompt
|
||||
from sqlalchemy.orm import Session
|
||||
from sse_starlette.sse import EventSourceResponse
|
||||
|
||||
chat_router = APIRouter(
|
||||
prefix="/chat",
|
||||
tags=["chat"],
|
||||
)
|
||||
|
||||
unauth_error = HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Unauthorized",
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
|
||||
|
||||
def get_db():
|
||||
db = SessionLocal()
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def _try_get_chat(client, chat_id):
|
||||
if not client.sismember("chats", chat_id):
|
||||
raise ValueError("Chat does not exist")
|
||||
|
||||
chat_raw = client.get(f"chat:{chat_id}")
|
||||
chat = Chat.parse_raw(chat_raw)
|
||||
|
||||
# backwards compat
|
||||
if not hasattr(chat, "owner"):
|
||||
chat.owner = "system"
|
||||
|
||||
return chat
|
||||
|
||||
|
||||
@chat_router.post("/")
|
||||
async def create_new_chat(
|
||||
u: User = Depends(get_current_active_user),
|
||||
db: Session = Depends(get_db),
|
||||
model: str = "7B",
|
||||
temperature: float = 0.1,
|
||||
top_k: int = 50,
|
||||
@ -51,11 +86,16 @@ async def create_new_chat(
|
||||
init_prompt=init_prompt,
|
||||
)
|
||||
# create the chat
|
||||
chat = Chat(params=params)
|
||||
chat = Chat(owner=u.username, params=params)
|
||||
|
||||
# store the parameters
|
||||
client.set(f"chat:{chat.id}", chat.json())
|
||||
|
||||
uc = UserChat(chat_id=chat.id, owner=u.username)
|
||||
create_chat(db, uc)
|
||||
u.chats.append(uc)
|
||||
update_user(db, u)
|
||||
|
||||
# create the message history
|
||||
history = RedisChatMessageHistory(chat.id)
|
||||
history.append(SystemMessage(content=init_prompt))
|
||||
@ -67,13 +107,11 @@ async def create_new_chat(
|
||||
|
||||
|
||||
@chat_router.get("/")
|
||||
async def get_all_chats():
|
||||
async def get_all_chats(u: User = Depends(get_current_active_user)):
|
||||
res = []
|
||||
client = Redis(host="localhost", port=6379, decode_responses=False)
|
||||
ids = client.smembers("chats")
|
||||
|
||||
chats = sorted(
|
||||
[await get_specific_chat(id.decode()) for id in ids],
|
||||
[await get_specific_chat(x.chat_id, u) for x in u.chats],
|
||||
key=lambda x: x["created"],
|
||||
reverse=True,
|
||||
)
|
||||
@ -96,39 +134,33 @@ async def get_all_chats():
|
||||
|
||||
|
||||
@chat_router.get("/{chat_id}")
|
||||
async def get_specific_chat(chat_id: str):
|
||||
async def get_specific_chat(chat_id: str, u: User = Depends(get_current_active_user)):
|
||||
client = Redis(host="localhost", port=6379, decode_responses=False)
|
||||
|
||||
if not client.sismember("chats", chat_id):
|
||||
raise ValueError("Chat does not exist")
|
||||
if chat_id not in [x.chat_id for x in u.chats]:
|
||||
raise unauth_error
|
||||
|
||||
chat_raw = client.get(f"chat:{chat_id}")
|
||||
chat = Chat.parse_raw(chat_raw)
|
||||
chat = _try_get_chat(client, chat_id)
|
||||
|
||||
history = RedisChatMessageHistory(chat.id)
|
||||
|
||||
chat_dict = chat.dict()
|
||||
chat_dict["history"] = messages_to_dict(history.messages)
|
||||
return chat_dict
|
||||
|
||||
|
||||
@chat_router.get("/{chat_id}/history")
|
||||
async def get_chat_history(chat_id: str):
|
||||
client = Redis(host="localhost", port=6379, decode_responses=False)
|
||||
|
||||
if not client.sismember("chats", chat_id):
|
||||
raise ValueError("Chat does not exist")
|
||||
async def get_chat_history(chat_id: str, u: User = Depends(get_current_active_user)):
|
||||
if chat_id not in [x.chat_id for x in u.chats]:
|
||||
raise unauth_error
|
||||
|
||||
history = RedisChatMessageHistory(chat_id)
|
||||
return messages_to_dict(history.messages)
|
||||
|
||||
|
||||
@chat_router.delete("/{chat_id}/prompt")
|
||||
async def delete_prompt(chat_id: str, idx: int):
|
||||
client = Redis(host="localhost", port=6379, decode_responses=False)
|
||||
|
||||
if not client.sismember("chats", chat_id):
|
||||
raise ValueError("Chat does not exist")
|
||||
async def delete_prompt(chat_id: str, idx: int, u: User = Depends(get_current_active_user)):
|
||||
if chat_id not in [x.chat_id for x in u.chats]:
|
||||
raise unauth_error
|
||||
|
||||
history = RedisChatMessageHistory(chat_id)
|
||||
|
||||
@ -146,12 +178,17 @@ async def delete_prompt(chat_id: str, idx: int):
|
||||
|
||||
|
||||
@chat_router.delete("/{chat_id}")
|
||||
async def delete_chat(chat_id: str):
|
||||
async def delete_chat(chat_id: str, u: User = Depends(get_current_active_user), db: Session = Depends(get_db)):
|
||||
client = Redis(host="localhost", port=6379, decode_responses=False)
|
||||
if chat_id not in [x.chat_id for x in u.chats]:
|
||||
raise unauth_error
|
||||
|
||||
if not client.sismember("chats", chat_id):
|
||||
raise ValueError("Chat does not exist")
|
||||
|
||||
if cid := next((x for x in u.chats if x.chat_id == chat_id), None):
|
||||
remove_chat(db, cid)
|
||||
|
||||
RedisChatMessageHistory(chat_id).clear()
|
||||
|
||||
client.delete(f"chat:{chat_id}")
|
||||
@ -161,23 +198,25 @@ async def delete_chat(chat_id: str):
|
||||
|
||||
|
||||
@chat_router.delete("/delete/all")
|
||||
async def delete_all_chats():
|
||||
client = Redis(host="localhost", port=6379, decode_responses=False)
|
||||
client.flushdb()
|
||||
async def delete_all_chats(u: User = Depends(get_current_active_user), db: Session = Depends(get_db)):
|
||||
[delete_chat(x.chat_id, u, db) for x in u.chats]
|
||||
return True
|
||||
|
||||
|
||||
@chat_router.get("/{chat_id}/question")
|
||||
def stream_ask_a_question(chat_id: str, prompt: str):
|
||||
async def stream_ask_a_question(chat_id: str, prompt: str, u: User = Depends(get_current_active_user)):
|
||||
if chat_id not in [x.chat_id for x in u.chats]:
|
||||
raise unauth_error
|
||||
|
||||
logger.info("Starting redis client")
|
||||
|
||||
client = Redis(host="localhost", port=6379, decode_responses=False)
|
||||
|
||||
if not client.sismember("chats", chat_id):
|
||||
raise ValueError("Chat does not exist")
|
||||
|
||||
logger.debug("creating chat")
|
||||
chat_raw = client.get(f"chat:{chat_id}")
|
||||
chat = Chat.parse_raw(chat_raw)
|
||||
chat = _try_get_chat(client, chat_id)
|
||||
|
||||
logger.debug(chat.params)
|
||||
logger.debug("creating history")
|
||||
@ -223,7 +262,7 @@ def stream_ask_a_question(chat_id: str, prompt: str):
|
||||
yield {"event": "message", "data": txt}
|
||||
|
||||
except Exception as e:
|
||||
if type(e) == UnicodeDecodeError:
|
||||
if type(e) is UnicodeDecodeError:
|
||||
pass
|
||||
else:
|
||||
error = e.__str__()
|
||||
@ -242,15 +281,16 @@ def stream_ask_a_question(chat_id: str, prompt: str):
|
||||
|
||||
|
||||
@chat_router.post("/{chat_id}/question")
|
||||
async def ask_a_question(chat_id: str, prompt: str):
|
||||
async def ask_a_question(chat_id: str, prompt: str, u: User = Depends(get_current_active_user)):
|
||||
if chat_id not in [x.chat_id for x in u.chats]:
|
||||
raise unauth_error
|
||||
|
||||
client = Redis(host="localhost", port=6379, decode_responses=False)
|
||||
|
||||
if not client.sismember("chats", chat_id):
|
||||
raise ValueError("Chat does not exist")
|
||||
|
||||
chat_raw = client.get(f"chat:{chat_id}")
|
||||
chat = Chat.parse_raw(chat_raw)
|
||||
|
||||
chat = _try_get_chat(client, chat_id)
|
||||
history = RedisChatMessageHistory(chat.id)
|
||||
|
||||
if len(prompt) > 0:
|
||||
|
||||
63
api/src/serge/routers/user.py
Normal file
63
api/src/serge/routers/user.py
Normal file
@ -0,0 +1,63 @@
|
||||
import logging
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from serge.crud import create_user, update_user
|
||||
from serge.database import SessionLocal
|
||||
from serge.routers.auth import get_current_active_user
|
||||
from serge.schema import user as user_schema
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
user_router = APIRouter(
|
||||
prefix="/user",
|
||||
tags=["user"],
|
||||
)
|
||||
|
||||
|
||||
def get_db():
|
||||
db = SessionLocal()
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@user_router.get("/", response_model=user_schema.User)
|
||||
async def get_user(u: user_schema.User = Depends(get_current_active_user)):
|
||||
if not u:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Incorrect username or password",
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
return u.to_public_dict()
|
||||
|
||||
|
||||
@user_router.post("/create", response_model=user_schema.User)
|
||||
async def create_user_with_pass(ua: user_schema.UserAuth, db: Session = Depends(get_db)):
|
||||
try:
|
||||
u = create_user(db, ua)
|
||||
except Exception as e:
|
||||
logging.exception(e)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail=f"Failed to create. {e}",
|
||||
)
|
||||
if not u:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_405_METHOD_NOT_ALLOWED,
|
||||
detail="Could not create user",
|
||||
)
|
||||
return u.to_public_dict()
|
||||
|
||||
|
||||
@user_router.put("/", response_model=user_schema.User)
|
||||
async def self_update_user(
|
||||
new_data: user_schema.User,
|
||||
current: user_schema.User = Depends(get_current_active_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
current.email = new_data.email
|
||||
current.full_name = new_data.full_name
|
||||
current.default_prompt = new_data.default_prompt
|
||||
update_user(db, current)
|
||||
return current.to_public_dict()
|
||||
@ -73,16 +73,35 @@
|
||||
"Name": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"fp16",
|
||||
"iq1_M",
|
||||
"iq1_S",
|
||||
"iq2_M",
|
||||
"iq2_S",
|
||||
"iq2_XS",
|
||||
"iq2_XXS",
|
||||
"iq3_M",
|
||||
"iq3_S",
|
||||
"iq3_XS",
|
||||
"iq3_XXS",
|
||||
"iq4_NL",
|
||||
"iq4_XS",
|
||||
"q2_K",
|
||||
"q3_K_L",
|
||||
"q3_K_M",
|
||||
"q3_K_S",
|
||||
"q4_0",
|
||||
"q4_1",
|
||||
"q4_K_M",
|
||||
"q4_K_S",
|
||||
"q5_0",
|
||||
"q5_1",
|
||||
"q5_K_M",
|
||||
"q5_K_S",
|
||||
"q6_K",
|
||||
"q8_0"
|
||||
"q8_0",
|
||||
"q8_1",
|
||||
"q8_K"
|
||||
],
|
||||
"title": "Name"
|
||||
}
|
||||
|
||||
42
api/src/serge/schema/user.py
Normal file
42
api/src/serge/schema/user.py
Normal file
@ -0,0 +1,42 @@
|
||||
import uuid
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class UserBase(BaseModel):
|
||||
username: str
|
||||
|
||||
|
||||
class UserAuth(UserBase):
|
||||
secret: str
|
||||
auth_type: int
|
||||
|
||||
|
||||
class Chat(BaseModel):
|
||||
chat_id: str
|
||||
owner: str
|
||||
|
||||
|
||||
class User(UserBase):
|
||||
id: uuid.UUID
|
||||
is_active: bool = True
|
||||
email: str = ""
|
||||
full_name: str = ""
|
||||
theme_light: bool = False
|
||||
default_prompt: str = "Below is an instruction that describes a task. Write a response that appropriately completes the request."
|
||||
auth: list[UserAuth] = []
|
||||
chats: list[Chat] = []
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
def to_public_dict(self):
|
||||
user_dict = self.dict()
|
||||
for auth in user_dict["auth"]:
|
||||
auth["secret"] = "********"
|
||||
return user_dict
|
||||
|
||||
|
||||
class Token(BaseModel):
|
||||
access_token: str
|
||||
token_type: str
|
||||
56
api/src/serge/utils/security.py
Normal file
56
api/src/serge/utils/security.py
Normal file
@ -0,0 +1,56 @@
|
||||
import base64
|
||||
import hashlib
|
||||
import os
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import HTTPException, status
|
||||
from jose import JWTError, jwt
|
||||
from serge.models.settings import Settings
|
||||
|
||||
ALGORITHM = "HS256"
|
||||
settings = Settings()
|
||||
|
||||
credentials_exception = HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Could not validate credentials",
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
|
||||
|
||||
def verify_password(plain_password: str, hashed_password: str) -> bool:
|
||||
salt_and_hash = base64.b64decode(hashed_password.encode("utf-8"))
|
||||
salt = salt_and_hash[:16]
|
||||
stored_password = salt_and_hash[16:]
|
||||
new_hashed_password = hashlib.scrypt(plain_password.encode("utf-8"), salt=salt, n=8192, r=8, p=1, dklen=64)
|
||||
return new_hashed_password == stored_password
|
||||
|
||||
|
||||
def get_password_hash(password: str) -> str:
|
||||
salt = os.urandom(16)
|
||||
hashed_password = hashlib.scrypt(password.encode("utf-8"), salt=salt, n=8192, r=8, p=1, dklen=64)
|
||||
salt_and_hash = salt + hashed_password
|
||||
return base64.b64encode(salt_and_hash).decode("utf-8")
|
||||
|
||||
|
||||
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
|
||||
to_encode = data.copy()
|
||||
if expires_delta:
|
||||
expire = datetime.utcnow() + expires_delta
|
||||
else:
|
||||
expire = datetime.utcnow() + timedelta(minutes=settings.SERGE_SESSION_EXPIRY)
|
||||
to_encode.update({"exp": expire})
|
||||
encoded_jwt = jwt.encode(to_encode, settings.SERGE_JWT_SECRET, algorithm=ALGORITHM)
|
||||
return encoded_jwt
|
||||
|
||||
|
||||
def decode_access_token(token: str):
|
||||
try:
|
||||
payload = jwt.decode(token, settings.SERGE_JWT_SECRET, algorithms=[ALGORITHM])
|
||||
username: str = payload.get("sub")
|
||||
if username is None:
|
||||
raise credentials_exception
|
||||
return username
|
||||
except JWTError:
|
||||
raise credentials_exception
|
||||
@ -8,8 +8,6 @@ image:
|
||||
repository: ghcr.io/serge-chat/serge
|
||||
image:
|
||||
pullPolicy: IfNotPresent
|
||||
# Model file extensions to be recognized by the application.
|
||||
modelFileExtensions: ['.bin', '.gguf']
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
tag: "main"
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
services:
|
||||
serge:
|
||||
restart: on-failure
|
||||
build:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.dev
|
||||
volumes:
|
||||
@ -11,9 +11,9 @@ services:
|
||||
- weights:/usr/src/app/weights/
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- "8008:8008"
|
||||
- "9124:9124"
|
||||
|
||||
- 8008:8008
|
||||
- 9124:9124
|
||||
- 5678:5678
|
||||
volumes:
|
||||
datadb:
|
||||
weights:
|
||||
|
||||
@ -12,5 +12,3 @@ services:
|
||||
volumes:
|
||||
weights:
|
||||
datadb:
|
||||
# Ensure volume mappings include directories for .gguf model files.
|
||||
volumes:
|
||||
|
||||
@ -21,12 +21,13 @@ detect_cpu_features() {
|
||||
}
|
||||
|
||||
# Check if the CPU architecture is aarch64/arm64
|
||||
if [ "$cpu_arch" = "aarch64" ]; then
|
||||
pip_command="python -m pip install -v llama-cpp-python==$LLAMA_PYTHON_VERSION --only-binary=:all: --extra-index-url=https://gaby.github.io/arm64-wheels/"
|
||||
if [ "$cpu_arch" = "aarch64" ] || [ "$cpu_arch" = "arm64" ]; then
|
||||
pip_command="python -m pip install -v llama-cpp-python==$LLAMA_PYTHON_VERSION --only-binary=:all: --extra-index-url=https://abetlen.github.io/llama-cpp-python/whl/cpu/"
|
||||
else
|
||||
# Use @smartappli provided wheels
|
||||
cpu_feature=$(detect_cpu_features)
|
||||
pip_command="python -m pip install -v llama-cpp-python==$LLAMA_PYTHON_VERSION --only-binary=:all: --extra-index-url=https://smartappli.github.io/serge-wheels/$cpu_feature/cpu"
|
||||
#cpu_feature=$(detect_cpu_features)
|
||||
#pip_command="python -m pip install -v llama-cpp-python==$LLAMA_PYTHON_VERSION --only-binary=:all: --extra-index-url=https://abetlen.github.io/llama-cpp-python/whl/cpu-$cpu_feature/"
|
||||
pip_command="python -m pip install -v llama-cpp-python==$LLAMA_PYTHON_VERSION --only-binary=:all: --extra-index-url=https://abetlen.github.io/llama-cpp-python/whl/cpu/"
|
||||
fi
|
||||
|
||||
echo "Recommended install command for llama-cpp-python: $pip_command"
|
||||
|
||||
@ -21,12 +21,13 @@ detect_cpu_features() {
|
||||
}
|
||||
|
||||
# Check if the CPU architecture is aarch64/arm64
|
||||
if [ "$cpu_arch" = "aarch64" ]; then
|
||||
pip_command="python -m pip install -v llama-cpp-python==$LLAMA_PYTHON_VERSION --only-binary=:all: --extra-index-url=https://gaby.github.io/arm64-wheels/"
|
||||
if [ "$cpu_arch" = "aarch64" ] || [ "$cpu_arch" = "arm64" ]; then
|
||||
pip_command="python -m pip install -v llama-cpp-python==$LLAMA_PYTHON_VERSION --only-binary=:all: --extra-index-url=https://abetlen.github.io/llama-cpp-python/whl/cpu/"
|
||||
else
|
||||
# Use @smartappli provided wheels
|
||||
cpu_feature=$(detect_cpu_features)
|
||||
pip_command="python -m pip install -v llama-cpp-python==$LLAMA_PYTHON_VERSION --only-binary=:all: --extra-index-url=https://smartappli.github.io/serge-wheels/$cpu_feature/cpu"
|
||||
#cpu_feature=$(detect_cpu_features)
|
||||
#pip_command="python -m pip install -v llama-cpp-python==$LLAMA_PYTHON_VERSION --only-binary=:all: --extra-index-url=https://abetlen.github.io/llama-cpp-python/whl/cpu-$cpu_feature/"
|
||||
pip_command="python -m pip install -v llama-cpp-python==$LLAMA_PYTHON_VERSION --only-binary=:all: --extra-index-url=https://abetlen.github.io/llama-cpp-python/whl/cpu/"
|
||||
fi
|
||||
|
||||
echo "Recommended install command for llama-cpp-python: $pip_command"
|
||||
@ -56,13 +57,15 @@ redis-server /etc/redis/redis.conf &
|
||||
cd /usr/src/app/web || exit 1
|
||||
npm run dev -- --host 0.0.0.0 --port 8008 &
|
||||
|
||||
python -m pip install debugpy -t /tmp
|
||||
|
||||
# Start the API
|
||||
cd /usr/src/app/api || exit 1
|
||||
hypercorn_cmd="hypercorn src.serge.main:api_app --bind 0.0.0.0:9124"
|
||||
hypercorn_cmd="python /tmp/debugpy --listen 0.0.0.0:5678 -m hypercorn src.serge.main:api_app --reload --bind 0.0.0.0:9124"
|
||||
if [ "$SERGE_ENABLE_IPV6" = true ] && [ "$SERGE_ENABLE_IPV4" != true ]; then
|
||||
hypercorn_cmd="hypercorn src.serge.main:api_app --bind [::]:9124"
|
||||
hypercorn_cmd="python /tmp/debugpy --listen 0.0.0.0:5678 -m hypercorn src.serge.main:api_app --reload --bind [::]:9124"
|
||||
elif [ "$SERGE_ENABLE_IPV4" = true ] && [ "$SERGE_ENABLE_IPV6" = true ]; then
|
||||
hypercorn_cmd="hypercorn src.serge.main:api_app --bind 0.0.0.0:9124 --bind [::]:9124"
|
||||
hypercorn_cmd="python /tmp/debugpy --listen 0.0.0.0:5678 -m hypercorn src.serge.main:api_app --reload --bind 0.0.0.0:9124 --bind [::]:9124"
|
||||
fi
|
||||
|
||||
$hypercorn_cmd || {
|
||||
|
||||
@ -1,74 +0,0 @@
|
||||
import configparser
|
||||
import os
|
||||
from typing import List
|
||||
|
||||
|
||||
class ModelLoader:
|
||||
def __init__(self):
|
||||
self.model_extensions = self._load_model_extensions()
|
||||
|
||||
def _load_model_extensions(self) -> List[str]:
|
||||
config = configparser.ConfigParser()
|
||||
config.read('config.ini')
|
||||
extensions = config.get('ModelConfig', 'modelFileExtensions').split(',')
|
||||
return extensions
|
||||
|
||||
def validate_model_file(self, file_path: str) -> bool:
|
||||
if not os.path.exists(file_path):
|
||||
return False
|
||||
if not os.path.isfile(file_path):
|
||||
return False
|
||||
_, ext = os.path.splitext(file_path)
|
||||
if ext not in self.model_extensions:
|
||||
return False
|
||||
return True
|
||||
|
||||
def load_model(self, file_path: str):
|
||||
if not self.validate_model_file(file_path):
|
||||
raise ValueError(f"Model file {file_path} is not valid or supported.")
|
||||
# Assuming the application uses a generic load function for models
|
||||
# This part would be replaced with the actual model loading logic
|
||||
print(f"Loading model from {file_path}")
|
||||
# Load the model here
|
||||
|
||||
# Unit tests covering all edge cases
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
|
||||
class TestModelLoader(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.loader = ModelLoader()
|
||||
|
||||
@patch('os.path.exists', return_value=True)
|
||||
@patch('os.path.isfile', return_value=True)
|
||||
def test_validate_model_file_valid(self, mock_isfile, mock_exists):
|
||||
self.assertTrue(self.loader.validate_model_file("model.bin"))
|
||||
|
||||
@patch('os.path.exists', return_value=False)
|
||||
def test_validate_model_file_nonexistent(self, mock_exists):
|
||||
self.assertFalse(self.loader.validate_model_file("nonexistent.bin"))
|
||||
|
||||
@patch('os.path.exists', return_value=True)
|
||||
@patch('os.path.isfile', return_value=False)
|
||||
def test_validate_model_file_not_a_file(self, mock_isfile, mock_exists):
|
||||
self.assertFalse(self.loader.validate_model_file("directory"))
|
||||
|
||||
@patch('os.path.exists', return_value=True)
|
||||
@patch('os.path.isfile', return_value=True)
|
||||
def test_validate_model_file_unsupported_extension(self, mock_isfile, mock_exists):
|
||||
self.assertFalse(self.loader.validate_model_file("unsupported.txt"))
|
||||
|
||||
@patch.object(ModelLoader, 'validate_model_file', return_value=True)
|
||||
def test_load_model_valid(self, mock_validate):
|
||||
with patch('builtins.print') as mock_print:
|
||||
self.loader.load_model("model.bin")
|
||||
mock_print.assert_called_with("Loading model from model.bin")
|
||||
|
||||
@patch.object(ModelLoader, 'validate_model_file', return_value=False)
|
||||
def test_load_model_invalid(self, mock_validate):
|
||||
with self.assertRaises(ValueError):
|
||||
self.loader.load_model("invalid.txt")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@ -1,3 +1,3 @@
|
||||
LLAMA_PYTHON_VERSION=0.2.50
|
||||
LLAMA_PYTHON_VERSION=0.2.87
|
||||
SERGE_ENABLE_IPV4=true
|
||||
SERGE_ENABLE_IPV6=false
|
||||
|
||||
27
sweep.yaml
27
sweep.yaml
@ -1,27 +0,0 @@
|
||||
# Sweep AI turns bugs & feature requests into code changes (https://sweep.dev)
|
||||
# For details on our config file, check out our docs at https://docs.sweep.dev/usage/config
|
||||
|
||||
# This setting contains a list of rules that Sweep will check for. If any of these rules are broken in a new commit, Sweep will create an pull request to fix the broken rule.
|
||||
rules:
|
||||
- "All new business logic should have corresponding unit tests."
|
||||
- "Refactor large functions to be more modular."
|
||||
- "Add docstrings to all functions and file headers."
|
||||
|
||||
# This is the branch that Sweep will develop from and make pull requests to. Most people use 'main' or 'master' but some users also use 'dev' or 'staging'.
|
||||
branch: 'main'
|
||||
|
||||
# By default Sweep will read the logs and outputs from your existing Github Actions. To disable this, set this to false.
|
||||
gha_enabled: True
|
||||
|
||||
# This is the description of your project. It will be used by sweep when creating PRs. You can tell Sweep what's unique about your project, what frameworks you use, or anything else you want.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# description: sweepai/sweep is a python project. The main api endpoints are in sweepai/api.py. Write code that adheres to PEP8.
|
||||
description: ''
|
||||
|
||||
# This sets whether to create pull requests as drafts. If this is set to True, then all pull requests will be created as drafts and GitHub Actions will not be triggered.
|
||||
draft: False
|
||||
|
||||
# This is a list of directories that Sweep will not be able to edit.
|
||||
blocked_dirs: []
|
||||
6
vendor/requirements.txt
vendored
6
vendor/requirements.txt
vendored
@ -1,3 +1,3 @@
|
||||
typing-extensions>=4.5.0
|
||||
numpy>=1.20.0
|
||||
diskcache>=5.6.1
|
||||
typing-extensions>=4.12.2
|
||||
numpy>=1.26.0,<2.0.0
|
||||
diskcache>=5.6.3
|
||||
|
||||
2063
web/package-lock.json
generated
2063
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -12,40 +12,41 @@
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^3.1.1",
|
||||
"@sveltejs/adapter-node": "^4.0.1",
|
||||
"@sveltejs/adapter-static": "^3.0.1",
|
||||
"@sveltejs/kit": "^2.5.1",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.2",
|
||||
"@types/markdown-it": "^13.0.7",
|
||||
"@typescript-eslint/eslint-plugin": "^7.0.2",
|
||||
"@typescript-eslint/parser": "^7.0.2",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"eslint": "^8.56.0",
|
||||
"@sveltejs/adapter-auto": "^3.2.2",
|
||||
"@sveltejs/adapter-node": "^5.2.0",
|
||||
"@sveltejs/adapter-static": "^3.0.2",
|
||||
"@sveltejs/kit": "^2.5.20",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.1.1",
|
||||
"@types/markdown-it": "^14.1.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.17.0",
|
||||
"@typescript-eslint/parser": "^7.18.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-svelte": "^2.35.1",
|
||||
"eslint-plugin-vue": "^9.22.0",
|
||||
"postcss": "^8.4.35",
|
||||
"prettier": "3.2.5",
|
||||
"prettier-plugin-svelte": "^3.2.1",
|
||||
"svelte": "^4.2.12",
|
||||
"svelte-check": "^3.6.4",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"tslib": "^2.6.2",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.1.4"
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint-plugin-svelte": "^2.43.0",
|
||||
"eslint-plugin-vue": "^9.27.0",
|
||||
"postcss": "^8.4.40",
|
||||
"prettier": "3.3.3",
|
||||
"prettier-plugin-svelte": "^3.2.6",
|
||||
"svelte": "^4.2.18",
|
||||
"svelte-check": "^3.8.5",
|
||||
"tailwindcss": "^3.4.7",
|
||||
"tslib": "^2.6.3",
|
||||
"typescript": "^5.5.4",
|
||||
"vite": "^5.4.1"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@iconify/svelte": "^3.1.6",
|
||||
"@iconify/svelte": "^4.0.2",
|
||||
"@sveltestack/svelte-query": "^1.6.0",
|
||||
"clipboard": "^2.0.11",
|
||||
"daisyui": "^4.7.2",
|
||||
"highlight.js": "^11.9.0",
|
||||
"markdown-it": "^14.0.0",
|
||||
"markdown-it-highlightjs": "^4.0.1",
|
||||
"prettier-plugin-tailwindcss": "^0.5.11"
|
||||
"daisyui": "^4.12.10",
|
||||
"highlight.js": "^11.10.0",
|
||||
"ioredis": "^5.4.1",
|
||||
"markdown-it": "^14.1.0",
|
||||
"markdown-it-highlightjs": "^4.1.0",
|
||||
"prettier-plugin-tailwindcss": "^0.6.5"
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
width: auto;
|
||||
}
|
||||
|
||||
markdown. .hljs {
|
||||
markdown .hljs {
|
||||
background: hsl(var(--b3)) !important;
|
||||
}
|
||||
|
||||
@ -145,3 +145,33 @@ markdown. .hljs {
|
||||
padding-right: 40px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
main {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
div {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
@ -200,7 +200,7 @@
|
||||
<ul
|
||||
class="my-1 w-full flex-grow overflow-y-auto no-scrollbar firefox-no-scrollbar ie-edge-no-scrollbar"
|
||||
>
|
||||
{#if data && data.chats}
|
||||
{#if data && Symbol.iterator in Object(data.chats)}
|
||||
{#each data.chats as chat (chat.id)}
|
||||
<li in:fly={{ x: -100, duration: 900 }}>
|
||||
<a
|
||||
@ -208,83 +208,88 @@
|
||||
class="group hover:from-base-100 hover:text-base-content flex items-center rounded-lg py-2 pl-2 text-base font-normal hover:bg-gradient-to-r hover:to-transparent"
|
||||
class:bg-base-300={id === chat.id}
|
||||
>
|
||||
<div class="flex w-full flex-col">
|
||||
<div class="flex w-full flex-col items-start justify-start">
|
||||
<div
|
||||
class="flex w-full flex-col space-y-2 p-2 border-b border-gray-200 relative"
|
||||
>
|
||||
<div
|
||||
class="flex w-full flex-col items-start justify-start space-y-1"
|
||||
>
|
||||
<div
|
||||
class="relative flex w-full flex-row items-center justify-between"
|
||||
class="flex w-full flex-row items-center justify-between"
|
||||
>
|
||||
<div class="flex flex-col">
|
||||
<p class="text-sm font-light">
|
||||
{truncate(chat.subtitle, 42)}
|
||||
<div class="flex flex-col space-y-1.5">
|
||||
<p class="text-sm font-light max-w-[25ch] break-words">
|
||||
{truncate(chat.subtitle, 100)}
|
||||
</p>
|
||||
<span class="text-xs font-semibold">{chat.model}</span>
|
||||
<span
|
||||
class="text-xs font-semibold max-w-[25ch] break-words"
|
||||
>{chat.model}</span
|
||||
>
|
||||
<span class="text-xs"
|
||||
>{timeSince(chat.created) + " ago"}</span
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="absolute right-0 opacity-0 group-hover:opacity-100 transition"
|
||||
>
|
||||
<!-- {#if $page.params.id === chat.id} -->
|
||||
{#if deleteConfirm}
|
||||
<div class="flex flex-row items-center">
|
||||
<button
|
||||
name="confirm-delete"
|
||||
class="btn-ghost btn-sm btn"
|
||||
on:click|preventDefault={() => deleteChat(chat.id)}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
<path
|
||||
class="fill-base-content"
|
||||
d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm1.5 0a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm10.28-1.72-4.5 4.5a.75.75 0 0 1-1.06 0l-2-2a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018l1.47 1.47 3.97-3.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
name="cancel-delete"
|
||||
class="btn-ghost btn-sm btn"
|
||||
on:click|preventDefault={toggleDeleteConfirm}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
<path
|
||||
class="fill-base-content"
|
||||
d="M2.344 2.343h-.001a8 8 0 0 1 11.314 11.314A8.002 8.002 0 0 1 .234 10.089a8 8 0 0 1 2.11-7.746Zm1.06 10.253a6.5 6.5 0 1 0 9.108-9.275 6.5 6.5 0 0 0-9.108 9.275ZM6.03 4.97 8 6.94l1.97-1.97a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l1.97 1.97a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-1.97 1.97a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L6.94 8 4.97 6.03a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{:else}
|
||||
<button
|
||||
class="btn-ghost btn-sm btn"
|
||||
on:click|preventDefault={toggleDeleteConfirm}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
<path
|
||||
class="fill-base-content"
|
||||
d="M11 1.75V3h2.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75ZM4.496 6.675l.66 6.6a.25.25 0 0 0 .249.225h5.19a.25.25 0 0 0 .249-.225l.66-6.6a.75.75 0 0 1 1.492.149l-.66 6.6A1.748 1.748 0 0 1 10.595 15h-5.19a1.75 1.75 0 0 1-1.741-1.575l-.66-6.6a.75.75 0 1 1 1.492-.15ZM6.5 1.75V3h3V1.75a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
{/if}
|
||||
<!-- {/if} -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="absolute bottom-1.5 right-2 opacity-0 group-hover:opacity-100 transition-opacity duration-300"
|
||||
>
|
||||
{#if deleteConfirm}
|
||||
<div class="flex flex-row items-center space-x-2">
|
||||
<button
|
||||
name="confirm-delete"
|
||||
class="btn btn-sm btn"
|
||||
on:click|preventDefault={() => deleteChat(chat.id)}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
<path
|
||||
class="fill-base-content"
|
||||
d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm1.5 0a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm10.28-1.72-4.5 4.5a.75.75 0 0 1-1.06 0l-2-2a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018l1.47 1.47 3.97-3.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
name="cancel-delete"
|
||||
class="btn btn-sm btn"
|
||||
on:click|preventDefault={toggleDeleteConfirm}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
<path
|
||||
class="fill-base-content"
|
||||
d="M2.344 2.343h-.001a8 8 0 0 1 11.314 11.314A8.002 8.002 0 0 1 .234 10.089a8 8 0 0 1 2.11-7.746Zm1.06 10.253a6.5 6.5 0 1 0 9.108-9.275 6.5 6.5 0 0 0-9.108 9.275ZM6.03 4.97 8 6.94l1.97-1.97a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l1.97 1.97a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-1.97 1.97a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L6.94 8 4.97 6.03a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{:else}
|
||||
<button
|
||||
class="btn btn-sm btn"
|
||||
on:click|preventDefault={toggleDeleteConfirm}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
<path
|
||||
class="fill-base-content"
|
||||
d="M11 1.75V3h2.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75ZM4.496 6.675l.66 6.6a.25.25 0 0 0 .249.225h5.19a.25.25 0 0 0 .249-.225l.66-6.6a.75.75 0 0 1 1.492.149l-.66 6.6A1.748 1.748 0 0 1 10.595 15h-5.19a1.75 1.75 0 0 1-1.741-1.575l-.66-6.6a.75.75 0 1 1 1.492-.15ZM6.5 1.75V3h3V1.75a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
@ -292,11 +297,158 @@
|
||||
{/if}
|
||||
</ul>
|
||||
<div class="w-full border-t border-base-content/[.2] pt-1">
|
||||
{#if deleteAllConfirm}
|
||||
{#if data.userData?.username === "system"}
|
||||
<button
|
||||
class="btn btn-ghost w-full flex flex-row justify-between items-center p-2.5 text-left text-sm capitalize"
|
||||
name="login-btn"
|
||||
class="btn btn-ghost w-full flex justify-start items-center p-2.5 text-left text-sm capitalize"
|
||||
on:click={() => goto("/login")}
|
||||
>
|
||||
<div class="h-6 flex flex-row items-center">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="currentColor"
|
||||
class="mr-3"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
<path
|
||||
d="M12.5 16a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7m1.679-4.493-1.335 2.226a.75.75 0 0 1-1.174.144l-.774-.773a.5.5 0 0 1 .708-.708l.547.548 1.17-1.951a.5.5 0 1 1 .858.514M11 5a3 3 0 1 1-6 0 3 3 0 0 1 6 0M8 7a2 2 0 1 0 0-4 2 2 0 0 0 0 4"
|
||||
/>
|
||||
<path
|
||||
d="M8.256 14a4.5 4.5 0 0 1-.229-1.004H3c.001-.246.154-.986.832-1.664C4.484 10.68 5.711 10 8 10q.39 0 .74.025c.226-.341.496-.65.804-.918Q8.844 9.002 8 9c-5 0-6 3-6 4s1 1 1 1z"
|
||||
/>
|
||||
</svg>
|
||||
<span>Login</span>
|
||||
</button>
|
||||
<button
|
||||
name="create-btn"
|
||||
class="btn btn-ghost w-full flex justify-start items-center p-2.5 text-left text-sm capitalize"
|
||||
on:click={() => goto("/signup")}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="currentColor"
|
||||
class="mr-3"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
<path
|
||||
d="M12.5 16a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7m.5-5v1h1a.5.5 0 0 1 0 1h-1v1a.5.5 0 0 1-1 0v-1h-1a.5.5 0 0 1 0-1h1v-1a.5.5 0 0 1 1 0m-2-6a3 3 0 1 1-6 0 3 3 0 0 1 6 0M8 7a2 2 0 1 0 0-4 2 2 0 0 0 0 4"
|
||||
/>
|
||||
<path
|
||||
d="M8.256 14a4.5 4.5 0 0 1-.229-1.004H3c.001-.246.154-.986.832-1.664C4.484 10.68 5.711 10 8 10q.39 0 .74.025c.226-.341.496-.65.804-.918Q8.844 9.002 8 9c-5 0-6 3-6 4s1 1 1 1z"
|
||||
/>
|
||||
</svg>
|
||||
<span>Create Account</span>
|
||||
</button>
|
||||
{:else}
|
||||
<button
|
||||
name="logout-btn"
|
||||
class="btn btn-ghost w-full flex justify-start items-center p-2.5 text-left text-sm capitalize"
|
||||
on:click={async () => {
|
||||
const response = await fetch("/api/auth/logout", {
|
||||
method: "POST",
|
||||
});
|
||||
data.userData = null;
|
||||
window.location.href = "/";
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="currentColor"
|
||||
class="mr-3"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
<path
|
||||
d="M11 5a3 3 0 1 1-6 0 3 3 0 0 1 6 0M8 7a2 2 0 1 0 0-4 2 2 0 0 0 0 4m0 5.996V14H3s-1 0-1-1 1-4 6-4q.845.002 1.544.107a4.5 4.5 0 0 0-.803.918A11 11 0 0 0 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664zM9 13a1 1 0 0 1 1-1v-1a2 2 0 1 1 4 0v1a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1zm3-3a1 1 0 0 0-1 1v1h2v-1a1 1 0 0 0-1-1"
|
||||
/>
|
||||
</svg>
|
||||
<span>Log Out</span>
|
||||
</button>
|
||||
<a
|
||||
href="/account"
|
||||
class="btn btn-ghost w-full flex justify-start items-center p-2.5 text-left text-sm capitalize"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="currentColor"
|
||||
class="mr-3"
|
||||
>
|
||||
<path
|
||||
d="M8 0a8.2 8.2 0 0 1 .701.031C9.444.095 9.99.645 10.16 1.29l.288 1.107c.018.066.079.158.212.224.231.114.454.243.668.386.123.082.233.09.299.071l1.103-.303c.644-.176 1.392.021 1.82.63.27.385.506.792.704 1.218.315.675.111 1.422-.364 1.891l-.814.806c-.049.048-.098.147-.088.294.016.257.016.515 0 .772-.01.147.038.246.088.294l.814.806c.475.469.679 1.216.364 1.891a7.977 7.977 0 0 1-.704 1.217c-.428.61-1.176.807-1.82.63l-1.102-.302c-.067-.019-.177-.011-.3.071a5.909 5.909 0 0 1-.668.386c-.133.066-.194.158-.211.224l-.29 1.106c-.168.646-.715 1.196-1.458 1.26a8.006 8.006 0 0 1-1.402 0c-.743-.064-1.289-.614-1.458-1.26l-.289-1.106c-.018-.066-.079-.158-.212-.224a5.738 5.738 0 0 1-.668-.386c-.123-.082-.233-.09-.299-.071l-1.103.303c-.644.176-1.392-.021-1.82-.63a8.12 8.12 0 0 1-.704-1.218c-.315-.675-.111-1.422.363-1.891l.815-.806c.05-.048.098-.147.088-.294a6.214 6.214 0 0 1 0-.772c.01-.147-.038-.246-.088-.294l-.815-.806C.635 6.045.431 5.298.746 4.623a7.92 7.92 0 0 1 .704-1.217c.428-.61 1.176-.807 1.82-.63l1.102.302c.067.019.177.011.3-.071.214-.143.437-.272.668-.386.133-.066.194-.158.211-.224l.29-1.106C6.009.645 6.556.095 7.299.03 7.53.01 7.764 0 8 0Zm-.571 1.525c-.036.003-.108.036-.137.146l-.289 1.105c-.147.561-.549.967-.998 1.189-.173.086-.34.183-.5.29-.417.278-.97.423-1.529.27l-1.103-.303c-.109-.03-.175.016-.195.045-.22.312-.412.644-.573.99-.014.031-.021.11.059.19l.815.806c.411.406.562.957.53 1.456a4.709 4.709 0 0 0 0 .582c.032.499-.119 1.05-.53 1.456l-.815.806c-.081.08-.073.159-.059.19.162.346.353.677.573.989.02.03.085.076.195.046l1.102-.303c.56-.153 1.113-.008 1.53.27.161.107.328.204.501.29.447.222.85.629.997 1.189l.289 1.105c.029.109.101.143.137.146a6.6 6.6 0 0 0 1.142 0c.036-.003.108-.036.137-.146l.289-1.105c.147-.561.549-.967.998-1.189.173-.086.34-.183.5-.29.417-.278.97-.423 1.529-.27l1.103.303c.109.029.175-.016.195-.045.22-.313.411-.644.573-.99.014-.031.021-.11-.059-.19l-.815-.806c-.411-.406-.562-.957-.53-1.456a4.709 4.709 0 0 0 0-.582c-.032-.499.119-1.05.53-1.456l.815-.806c.081-.08.073-.159.059-.19a6.464 6.464 0 0 0-.573-.989c-.02-.03-.085-.076-.195-.046l-1.102.303c-.56.153-1.113.008-1.53-.27a4.44 4.44 0 0 0-.501-.29c-.447-.222-.85-.629-.997-1.189l-.289-1.105c-.029-.11-.101-.143-.137-.146a6.6 6.6 0 0 0-1.142 0ZM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0ZM9.5 8a1.5 1.5 0 1 0-3.001.001A1.5 1.5 0 0 0 9.5 8Z"
|
||||
>
|
||||
</path>
|
||||
</svg>
|
||||
<span>Settings</span>
|
||||
</a>
|
||||
{#if deleteAllConfirm}
|
||||
<button
|
||||
class="btn btn-ghost w-full flex flex-row justify-between items-center p-2.5 text-left text-sm capitalize"
|
||||
>
|
||||
<div class="h-6 flex flex-row items-center">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="currentColor"
|
||||
class="mr-3"
|
||||
>
|
||||
<path
|
||||
d="M11 1.75V3h2.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75ZM4.496 6.675l.66 6.6a.25.25 0 0 0 .249.225h5.19a.25.25 0 0 0 .249-.225l.66-6.6a.75.75 0 0 1 1.492.149l-.66 6.6A1.748 1.748 0 0 1 10.595 15h-5.19a1.75 1.75 0 0 1-1.741-1.575l-.66-6.6a.75.75 0 1 1 1.492-.15ZM6.5 1.75V3h3V1.75a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25Z"
|
||||
>
|
||||
</path>
|
||||
</svg>
|
||||
<span>Clear Chats</span>
|
||||
</div>
|
||||
<div class="h-6 flex flex-row items-center">
|
||||
<button
|
||||
name="confirm-delete"
|
||||
class="btn-ghost btn-sm btn"
|
||||
on:click|preventDefault={() => deleteAllChat()}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
<path
|
||||
class="fill-base-content"
|
||||
d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm1.5 0a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm10.28-1.72-4.5 4.5a.75.75 0 0 1-1.06 0l-2-2a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018l1.47 1.47 3.97-3.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
name="cancel-delete"
|
||||
class="btn-ghost btn-sm btn"
|
||||
on:click|preventDefault={toggleDeleteAllConfirm}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
<path
|
||||
class="fill-base-content"
|
||||
d="M2.344 2.343h-.001a8 8 0 0 1 11.314 11.314A8.002 8.002 0 0 1 .234 10.089a8 8 0 0 1 2.11-7.746Zm1.06 10.253a6.5 6.5 0 1 0 9.108-9.275 6.5 6.5 0 0 0-9.108 9.275ZM6.03 4.97 8 6.94l1.97-1.97a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l1.97 1.97a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-1.97 1.97a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L6.94 8 4.97 6.03a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</button>
|
||||
{:else}
|
||||
<button
|
||||
on:click|preventDefault={toggleDeleteAllConfirm}
|
||||
class="btn btn-ghost w-full flex justify-start items-center p-2.5 text-left text-sm capitalize"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
@ -311,64 +463,8 @@
|
||||
</path>
|
||||
</svg>
|
||||
<span>Clear Chats</span>
|
||||
</div>
|
||||
<div class="h-6 flex flex-row items-center">
|
||||
<button
|
||||
name="confirm-delete"
|
||||
class="btn-ghost btn-sm btn"
|
||||
on:click|preventDefault={() => deleteAllChat()}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
<path
|
||||
class="fill-base-content"
|
||||
d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm1.5 0a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm10.28-1.72-4.5 4.5a.75.75 0 0 1-1.06 0l-2-2a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018l1.47 1.47 3.97-3.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
name="cancel-delete"
|
||||
class="btn-ghost btn-sm btn"
|
||||
on:click|preventDefault={toggleDeleteAllConfirm}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
<path
|
||||
class="fill-base-content"
|
||||
d="M2.344 2.343h-.001a8 8 0 0 1 11.314 11.314A8.002 8.002 0 0 1 .234 10.089a8 8 0 0 1 2.11-7.746Zm1.06 10.253a6.5 6.5 0 1 0 9.108-9.275 6.5 6.5 0 0 0-9.108 9.275ZM6.03 4.97 8 6.94l1.97-1.97a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l1.97 1.97a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-1.97 1.97a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L6.94 8 4.97 6.03a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</button>
|
||||
{:else}
|
||||
<button
|
||||
on:click|preventDefault={toggleDeleteAllConfirm}
|
||||
class="btn btn-ghost w-full flex justify-start items-center p-2.5 text-left text-sm capitalize"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="currentColor"
|
||||
class="mr-3"
|
||||
>
|
||||
<path
|
||||
d="M11 1.75V3h2.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75ZM4.496 6.675l.66 6.6a.25.25 0 0 0 .249.225h5.19a.25.25 0 0 0 .249-.225l.66-6.6a.75.75 0 0 1 1.492.149l-.66 6.6A1.748 1.748 0 0 1 10.595 15h-5.19a1.75 1.75 0 0 1-1.741-1.575l-.66-6.6a.75.75 0 1 1 1.492-.15ZM6.5 1.75V3h3V1.75a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25Z"
|
||||
>
|
||||
</path>
|
||||
</svg>
|
||||
<span>Clear Chats</span>
|
||||
</button>
|
||||
</button>
|
||||
{/if}
|
||||
{/if}
|
||||
<button
|
||||
on:click={toggleTheme}
|
||||
@ -404,29 +500,12 @@
|
||||
</label>
|
||||
<span>{theme == "dark" ? "Light" : "Dark"} theme</span>
|
||||
</button>
|
||||
<a
|
||||
href="/"
|
||||
class="btn btn-ghost w-full flex justify-start items-center p-2.5 text-left text-sm capitalize"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="currentColor"
|
||||
class="mr-3"
|
||||
>
|
||||
<path
|
||||
d="M8 0a8.2 8.2 0 0 1 .701.031C9.444.095 9.99.645 10.16 1.29l.288 1.107c.018.066.079.158.212.224.231.114.454.243.668.386.123.082.233.09.299.071l1.103-.303c.644-.176 1.392.021 1.82.63.27.385.506.792.704 1.218.315.675.111 1.422-.364 1.891l-.814.806c-.049.048-.098.147-.088.294.016.257.016.515 0 .772-.01.147.038.246.088.294l.814.806c.475.469.679 1.216.364 1.891a7.977 7.977 0 0 1-.704 1.217c-.428.61-1.176.807-1.82.63l-1.102-.302c-.067-.019-.177-.011-.3.071a5.909 5.909 0 0 1-.668.386c-.133.066-.194.158-.211.224l-.29 1.106c-.168.646-.715 1.196-1.458 1.26a8.006 8.006 0 0 1-1.402 0c-.743-.064-1.289-.614-1.458-1.26l-.289-1.106c-.018-.066-.079-.158-.212-.224a5.738 5.738 0 0 1-.668-.386c-.123-.082-.233-.09-.299-.071l-1.103.303c-.644.176-1.392-.021-1.82-.63a8.12 8.12 0 0 1-.704-1.218c-.315-.675-.111-1.422.363-1.891l.815-.806c.05-.048.098-.147.088-.294a6.214 6.214 0 0 1 0-.772c.01-.147-.038-.246-.088-.294l-.815-.806C.635 6.045.431 5.298.746 4.623a7.92 7.92 0 0 1 .704-1.217c.428-.61 1.176-.807 1.82-.63l1.102.302c.067.019.177.011.3-.071.214-.143.437-.272.668-.386.133-.066.194-.158.211-.224l.29-1.106C6.009.645 6.556.095 7.299.03 7.53.01 7.764 0 8 0Zm-.571 1.525c-.036.003-.108.036-.137.146l-.289 1.105c-.147.561-.549.967-.998 1.189-.173.086-.34.183-.5.29-.417.278-.97.423-1.529.27l-1.103-.303c-.109-.03-.175.016-.195.045-.22.312-.412.644-.573.99-.014.031-.021.11.059.19l.815.806c.411.406.562.957.53 1.456a4.709 4.709 0 0 0 0 .582c.032.499-.119 1.05-.53 1.456l-.815.806c-.081.08-.073.159-.059.19.162.346.353.677.573.989.02.03.085.076.195.046l1.102-.303c.56-.153 1.113-.008 1.53.27.161.107.328.204.501.29.447.222.85.629.997 1.189l.289 1.105c.029.109.101.143.137.146a6.6 6.6 0 0 0 1.142 0c.036-.003.108-.036.137-.146l.289-1.105c.147-.561.549-.967.998-1.189.173-.086.34-.183.5-.29.417-.278.97-.423 1.529-.27l1.103.303c.109.029.175-.016.195-.045.22-.313.411-.644.573-.99.014-.031.021-.11-.059-.19l-.815-.806c-.411-.406-.562-.957-.53-1.456a4.709 4.709 0 0 0 0-.582c-.032-.499.119-1.05.53-1.456l.815-.806c.081-.08.073-.159.059-.19a6.464 6.464 0 0 0-.573-.989c-.02-.03-.085-.076-.195-.046l-1.102.303c-.56.153-1.113.008-1.53-.27a4.44 4.44 0 0 0-.501-.29c-.447-.222-.85-.629-.997-1.189l-.289-1.105c-.029-.11-.101-.143-.137-.146a6.6 6.6 0 0 0-1.142 0ZM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0ZM9.5 8a1.5 1.5 0 1 0-3.001.001A1.5 1.5 0 0 0 9.5 8Z"
|
||||
>
|
||||
</path>
|
||||
</svg>
|
||||
<span>Settings</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<button class="h-full w-full" on:click={hideSidebar} type="button">
|
||||
<button on:click={hideSidebar} type="button"></button>
|
||||
|
||||
<div id="main_content" class="h-full w-full">
|
||||
<slot />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -7,6 +7,8 @@ interface ChatMetadata {
|
||||
subtitle: string;
|
||||
}
|
||||
|
||||
export const ssr = false; // off for now because ssr with auth is broken
|
||||
|
||||
export interface ModelStatus {
|
||||
name: string;
|
||||
size: number;
|
||||
@ -14,14 +16,32 @@ export interface ModelStatus {
|
||||
progress?: number;
|
||||
}
|
||||
|
||||
export interface User {
|
||||
id: string;
|
||||
username: string;
|
||||
email: string;
|
||||
pref_theme: "light" | "dark";
|
||||
full_name: string;
|
||||
default_prompt: string;
|
||||
}
|
||||
|
||||
export const load: LayoutLoad = async ({ fetch }) => {
|
||||
let userData: User | null = null;
|
||||
|
||||
const api_chat = await fetch("/api/chat/");
|
||||
const chats = (await api_chat.json()) as ChatMetadata[];
|
||||
|
||||
const model_api = await fetch("/api/model/all");
|
||||
const models = (await model_api.json()) as ModelStatus[];
|
||||
|
||||
const userData_api = await fetch("/api/user/");
|
||||
if (userData_api.ok) {
|
||||
userData = (await userData_api.json()) as User;
|
||||
}
|
||||
|
||||
return {
|
||||
chats,
|
||||
models,
|
||||
userData,
|
||||
};
|
||||
};
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
let repeat_penalty = 1.3;
|
||||
|
||||
let init_prompt =
|
||||
data.userData?.default_prompt ??
|
||||
"Below is an instruction that describes a task. Write a response that appropriately completes the request.";
|
||||
|
||||
let n_threads = 4;
|
||||
|
||||
106
web/src/routes/account/+page.svelte
Normal file
106
web/src/routes/account/+page.svelte
Normal file
@ -0,0 +1,106 @@
|
||||
<script context="module" lang="ts">
|
||||
export { load } from "./+page";
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { writable } from "svelte/store";
|
||||
import { goto } from "$app/navigation";
|
||||
export let data: {
|
||||
user: {
|
||||
id: string;
|
||||
username: string;
|
||||
email: string;
|
||||
full_name: string;
|
||||
pref_theme: "light" | "dark";
|
||||
default_prompt: string;
|
||||
} | null;
|
||||
};
|
||||
let user = data.user;
|
||||
let id: string = user?.id ?? "";
|
||||
let username: string = user?.username ?? "";
|
||||
let email: string = user?.email ?? "";
|
||||
let full_name: string = user?.full_name ?? "";
|
||||
let pref_theme: "light" | "dark" = user?.pref_theme ?? "light";
|
||||
let default_prompt: string = user?.default_prompt ?? "";
|
||||
let status = writable<string | null>(null);
|
||||
|
||||
async function handleSubmit(event: Event) {
|
||||
event.preventDefault();
|
||||
// Implement the update logic here, e.g., sending a PUT request to update user preferences
|
||||
try {
|
||||
await fetch("/api/user/", {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id,
|
||||
username,
|
||||
email,
|
||||
full_name,
|
||||
pref_theme,
|
||||
default_prompt,
|
||||
}),
|
||||
});
|
||||
|
||||
status.set("Preferences updated successfully");
|
||||
goto("/", { invalidateAll: true });
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
status.set(error.message);
|
||||
} else {
|
||||
status.set("Failed to update preferences");
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<div class="card-group">
|
||||
<div class="card">
|
||||
<div class="card-title p-3 text-3xl justify-center font-bold">
|
||||
User Preferences
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{#if user}
|
||||
<form on:submit={handleSubmit}>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Username</span>
|
||||
</div>
|
||||
<input type="text" bind:value={username} disabled />
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Full Name</span>
|
||||
</div>
|
||||
<input id="full_name" type="text" bind:value={full_name} />
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Email</span>
|
||||
</div>
|
||||
<input id="email" type="email" bind:value={email} />
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Default Prompt</span>
|
||||
</div>
|
||||
<textarea
|
||||
id="default_prompt"
|
||||
bind:value={default_prompt}
|
||||
style="resize:both; width:100%;"
|
||||
/>
|
||||
</div>
|
||||
{#if $status}
|
||||
<p>{$status}</p>
|
||||
{/if}
|
||||
<button class="btn" type="submit">Save Preferences</button>
|
||||
</form>
|
||||
{:else}
|
||||
<p>Loading...</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
27
web/src/routes/account/+page.ts
Normal file
27
web/src/routes/account/+page.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import type { Load } from "@sveltejs/kit";
|
||||
|
||||
interface User {
|
||||
id: string;
|
||||
username: string;
|
||||
email: string;
|
||||
pref_theme: "light" | "dark";
|
||||
full_name: string;
|
||||
default_prompt: string;
|
||||
}
|
||||
|
||||
export const load: Load = async () => {
|
||||
const user = await fetch("/api/user/", {
|
||||
method: "GET",
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.status == 401) {
|
||||
window.location.href = "/";
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
window.location.href = "/";
|
||||
});
|
||||
return { user };
|
||||
};
|
||||
@ -127,7 +127,19 @@
|
||||
accept: "application/json",
|
||||
},
|
||||
},
|
||||
).then((response) => response.json());
|
||||
)
|
||||
.then((response) => {
|
||||
if (response.status == 401) {
|
||||
console.log("Not authorized");
|
||||
window.location.href = "/";
|
||||
} else {
|
||||
return response.json();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
window.location.href = "/";
|
||||
});
|
||||
await invalidate("/api/chat/");
|
||||
await goto("/chat/" + newData);
|
||||
}
|
||||
@ -142,6 +154,8 @@
|
||||
await invalidate("/api/chat/" + $page.params.id);
|
||||
} else if (response.status === 202) {
|
||||
showToast("Chat in progress!");
|
||||
} else if (response.status === 401) {
|
||||
window.location.href = "/";
|
||||
} else {
|
||||
showToast("An error occurred: " + response.statusText);
|
||||
}
|
||||
|
||||
@ -28,12 +28,22 @@ interface Response {
|
||||
id: string;
|
||||
created: string;
|
||||
params: Params;
|
||||
owner: string;
|
||||
history: Message[];
|
||||
}
|
||||
|
||||
export const load: PageLoad = async ({ fetch, params }) => {
|
||||
const r = await fetch("/api/chat/" + params.id);
|
||||
const data = (await r.json()) as Response;
|
||||
const data = await fetch("/api/chat/" + params.id)
|
||||
.then((response) => {
|
||||
if (response.status == 401) {
|
||||
window.location.href = "/";
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
window.location.href = "/";
|
||||
});
|
||||
|
||||
return {
|
||||
chat: data,
|
||||
|
||||
69
web/src/routes/login/+page.svelte
Normal file
69
web/src/routes/login/+page.svelte
Normal file
@ -0,0 +1,69 @@
|
||||
<script lang="ts">
|
||||
import { goto } from "$app/navigation";
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
let username = "";
|
||||
let password = "";
|
||||
let error = writable<string | null>(null);
|
||||
|
||||
async function handleSubmit(event: Event) {
|
||||
event.preventDefault();
|
||||
try {
|
||||
const response = await fetch("/api/auth/token", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
username,
|
||||
password,
|
||||
}),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
localStorage.setItem("token", data.access_token);
|
||||
goto("/", { invalidateAll: true });
|
||||
} else {
|
||||
const errorData = await response.json();
|
||||
error.set(errorData.detail || "Login failed");
|
||||
}
|
||||
} catch (err) {
|
||||
error.set("An error occurred");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<div class="card-group">
|
||||
<div class="card">
|
||||
<div class="card-title p-3 text-3xl justify-center font-bold">
|
||||
Sign In
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form on:submit={handleSubmit}>
|
||||
<div class="form-control">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
bind:value={username}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
bind:value={password}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
{#if $error}
|
||||
<p style="color: red;">{$error}</p>
|
||||
{/if}
|
||||
<button class="btn" type="submit">Authenticate</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
165
web/src/routes/signup/+page.svelte
Normal file
165
web/src/routes/signup/+page.svelte
Normal file
@ -0,0 +1,165 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { goto } from "$app/navigation";
|
||||
let username = "";
|
||||
let secret = "";
|
||||
let full_name = "";
|
||||
let email = "";
|
||||
let auth_type = 1;
|
||||
let error = "";
|
||||
let success = "";
|
||||
|
||||
async function handleSubmit(event: Event) {
|
||||
event.preventDefault();
|
||||
error = "";
|
||||
success = "";
|
||||
const response = await fetch("/api/user/create", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
username,
|
||||
secret,
|
||||
full_name,
|
||||
email,
|
||||
auth_type,
|
||||
}),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
success = "User created successfully!";
|
||||
await authAfterCreate(event);
|
||||
goto("/account");
|
||||
} else {
|
||||
const data = await response.json();
|
||||
error = data.detail || "An error occurred";
|
||||
}
|
||||
}
|
||||
|
||||
async function authAfterCreate(event: Event) {
|
||||
event.preventDefault();
|
||||
try {
|
||||
const response = await fetch("/api/auth/token", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
username: username,
|
||||
password: secret,
|
||||
}),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
goto("/", { invalidateAll: true });
|
||||
} else {
|
||||
const errorData = await response.json();
|
||||
error = errorData.detail || "Login failed";
|
||||
}
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : "An unknown error occurred";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<div class="card-group">
|
||||
<div class="card">
|
||||
<div class="card-title p-3 text-3xl justify-center font-bold">
|
||||
Register a new user
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form on:submit={handleSubmit}>
|
||||
<div class="form-control">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
bind:value={username}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
bind:value={secret}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if error}
|
||||
<p class="error-message">{error}</p>
|
||||
{/if}
|
||||
{#if success}
|
||||
<p class="success-message">{success}</p>
|
||||
{/if}
|
||||
<button class="btn" type="submit">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-title p-3 text-3xl justify-center font-bold">
|
||||
Or link an account (comming soon)
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<button name="google-btn" class="btn" disabled={true}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
<path
|
||||
d="M15.545 6.558a9.4 9.4 0 0 1 .139 1.626c0 2.434-.87 4.492-2.384 5.885h.002C11.978 15.292 10.158 16 8 16A8 8 0 1 1 8 0a7.7 7.7 0 0 1 5.352 2.082l-2.284 2.284A4.35 4.35 0 0 0 8 3.166c-2.087 0-3.86 1.408-4.492 3.304a4.8 4.8 0 0 0 0 3.063h.003c.635 1.893 2.405 3.301 4.492 3.301 1.078 0 2.004-.276 2.722-.764h-.003a3.7 3.7 0 0 0 1.599-2.431H8v-3.08z"
|
||||
/>
|
||||
</svg>
|
||||
<span>Link Google Account</span>
|
||||
</button>
|
||||
<button name="reddit-btn" class="btn" disabled={true}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
<path
|
||||
d="M6.167 8a.83.83 0 0 0-.83.83c0 .459.372.84.83.831a.831.831 0 0 0 0-1.661m1.843 3.647c.315 0 1.403-.038 1.976-.611a.23.23 0 0 0 0-.306.213.213 0 0 0-.306 0c-.353.363-1.126.487-1.67.487-.545 0-1.308-.124-1.671-.487a.213.213 0 0 0-.306 0 .213.213 0 0 0 0 .306c.564.563 1.652.61 1.977.61zm.992-2.807c0 .458.373.83.831.83s.83-.381.83-.83a.831.831 0 0 0-1.66 0z"
|
||||
/>
|
||||
<path
|
||||
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-3.828-1.165c-.315 0-.602.124-.812.325-.801-.573-1.9-.945-3.121-.993l.534-2.501 1.738.372a.83.83 0 1 0 .83-.869.83.83 0 0 0-.744.468l-1.938-.41a.2.2 0 0 0-.153.028.2.2 0 0 0-.086.134l-.592 2.788c-1.24.038-2.358.41-3.17.992-.21-.2-.496-.324-.81-.324a1.163 1.163 0 0 0-.478 2.224q-.03.17-.029.353c0 1.795 2.091 3.256 4.669 3.256s4.668-1.451 4.668-3.256c0-.114-.01-.238-.029-.353.401-.181.688-.592.688-1.069 0-.65-.525-1.165-1.165-1.165"
|
||||
/>
|
||||
</svg>
|
||||
<span>Link Reddit Account</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-title pt-3 text-3xl justify-center font-bold">
|
||||
Already have an account?
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<button name="login-btn" class="btn" on:click={() => goto("/login")}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="currentColor"
|
||||
class="mr-3"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
<path
|
||||
d="M12.5 16a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7m1.679-4.493-1.335 2.226a.75.75 0 0 1-1.174.144l-.774-.773a.5.5 0 0 1 .708-.708l.547.548 1.17-1.951a.5.5 0 1 1 .858.514M11 5a3 3 0 1 1-6 0 3 3 0 0 1 6 0M8 7a2 2 0 1 0 0-4 2 2 0 0 0 0 4"
|
||||
/>
|
||||
<path
|
||||
d="M8.256 14a4.5 4.5 0 0 1-.229-1.004H3c.001-.246.154-.986.832-1.664C4.484 10.68 5.711 10 8 10q.39 0 .74.025c.226-.341.496-.65.804-.918Q8.844 9.002 8 9c-5 0-6 3-6 4s1 1 1 1z"
|
||||
/>
|
||||
</svg>
|
||||
<span>Login Instead</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
Loading…
x
Reference in New Issue
Block a user