mirror of
https://github.com/Eugeny/tabby-web.git
synced 2025-06-25 22:00:11 +00:00
wip
This commit is contained in:
parent
151a2fab60
commit
cbd8a93909
@ -1,15 +1,16 @@
|
|||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
FROM python:3.7-alpine AS build
|
FROM python:3.7-alpine AS build
|
||||||
|
ARG EXTRA_DEPS
|
||||||
RUN apk add build-base musl-dev libffi-dev openssl-dev mariadb-dev
|
RUN apk add build-base musl-dev libffi-dev openssl-dev mariadb-dev
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN pip install -U setuptools 'cryptography>=3.0,<3.1' poetry==1.1.7
|
RUN pip install -U setuptools 'cryptography>=3.0,<3.1' poetry==1.1.7 ${EXTRA_DEPS}
|
||||||
COPY pyproject.toml poetry.lock ./
|
COPY pyproject.toml poetry.lock ./
|
||||||
RUN poetry config virtualenvs.create false
|
RUN poetry config virtualenvs.create false
|
||||||
RUN poetry install --no-dev --no-ansi --no-interaction
|
RUN poetry install --no-dev --no-ansi --no-interaction
|
||||||
|
|
||||||
FROM node:12-alpine AS package
|
FROM node:12-alpine AS package
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=0 /usr /usr
|
COPY --from=0 /usr/local /usr/local
|
||||||
COPY start.sh manage.py gunicorn.conf.py ./
|
COPY start.sh manage.py gunicorn.conf.py ./
|
||||||
COPY tabby tabby
|
COPY tabby tabby
|
||||||
ENTRYPOINT ./start.sh
|
ENTRYPOINT ./start.sh
|
||||||
|
@ -7,6 +7,8 @@ steps:
|
|||||||
- '${_DOCKER_TAG}'
|
- '${_DOCKER_TAG}'
|
||||||
- '--cache-from'
|
- '--cache-from'
|
||||||
- '${_DOCKER_TAG}'
|
- '${_DOCKER_TAG}'
|
||||||
|
- '--build-arg'
|
||||||
|
- 'EXTRA_DEPS=${_EXTRA_DEPS}'
|
||||||
- '.'
|
- '.'
|
||||||
|
|
||||||
images: ['${_DOCKER_TAG}']
|
images: ['${_DOCKER_TAG}']
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
wsgi_app = "tabby.asgi:application"
|
wsgi_app = "tabby.wsgi:application"
|
||||||
workers = 4
|
workers = 4
|
||||||
worker_class = 'uvicorn.workers.UvicornWorker'
|
|
||||||
preload_app = True
|
preload_app = True
|
||||||
sendfile = True
|
sendfile = True
|
||||||
|
|
||||||
|
279
backend/poetry.lock
generated
279
backend/poetry.lock
generated
@ -26,31 +26,6 @@ docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
|
|||||||
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"]
|
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"]
|
||||||
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"]
|
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autobahn"
|
|
||||||
version = "21.2.1"
|
|
||||||
description = "WebSocket client & server library, WAMP real-time framework"
|
|
||||||
category = "main"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.6"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
cryptography = ">=2.9.2"
|
|
||||||
hyperlink = ">=20.0.1"
|
|
||||||
txaio = ">=20.4.1"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
accelerate = ["wsaccel (>=0.6.2)"]
|
|
||||||
all = ["zope.interface (>=3.6.0)", "twisted (>=20.3.0)", "attrs (>=19.2.0)", "wsaccel (>=0.6.2)", "python-snappy (>=0.5)", "msgpack (>=0.6.1)", "ujson (>=1.35)", "cbor2 (>=5.0.1)", "cbor (>=1.0.0)", "py-ubjson (>=0.8.4)", "flatbuffers (>=1.10)", "pyopenssl (>=16.2.0)", "service-identity (>=18.1.0)", "pynacl (>=1.0.1)", "pytrie (>=0.2)", "pyqrcode (>=1.1)", "cffi (>=1.11.5)", "argon2-cffi (>=18.1.0)", "passlib (>=1.7.1)", "xbr (>=20.1.1)", "cbor2 (>=5.1.0)", "zlmdb (>=20.4.1)", "web3 (>=4.8.1)", "jinja2 (>=2.11.2)", "rlp (>=2.0.1)", "py-eth-sig-utils (>=0.4.0)", "py-ecc (>=1.7.1)", "eth-abi (>=1.3.0)", "mnemonic (>=0.13)", "base58 (>=1.0.2,<2.0)", "ecdsa (>=0.13)", "py-multihash (>=0.2.3)"]
|
|
||||||
compress = ["python-snappy (>=0.5)"]
|
|
||||||
dev = ["pep8-naming (>=0.3.3)", "flake8 (>=2.5.1)", "pyflakes (>=1.0.0)", "pytest (>=2.8.6,<3.3.0)", "twine (>=1.6.5)", "sphinx (>=1.2.3)", "sphinxcontrib-images (>=0.9.2)", "pyenchant (>=1.6.6)", "sphinxcontrib-spelling (>=2.1.2)", "sphinx-rtd-theme (>=0.1.9)", "awscli", "qualname", "passlib", "wheel", "pytest-asyncio (<0.6)", "pytest-aiohttp"]
|
|
||||||
encryption = ["pyopenssl (>=16.2.0)", "service-identity (>=18.1.0)", "pynacl (>=1.0.1)", "pytrie (>=0.2)", "pyqrcode (>=1.1)"]
|
|
||||||
nvx = ["cffi (>=1.11.5)"]
|
|
||||||
scram = ["cffi (>=1.11.5)", "argon2-cffi (>=18.1.0)", "passlib (>=1.7.1)"]
|
|
||||||
serialization = ["msgpack (>=0.6.1)", "ujson (>=1.35)", "cbor2 (>=5.0.1)", "cbor (>=1.0.0)", "py-ubjson (>=0.8.4)", "flatbuffers (>=1.10)"]
|
|
||||||
twisted = ["zope.interface (>=3.6.0)", "twisted (>=20.3.0)", "attrs (>=19.2.0)"]
|
|
||||||
xbr = ["xbr (>=20.1.1)", "cbor2 (>=5.1.0)", "zlmdb (>=20.4.1)", "twisted (>=20.3.0)", "web3 (>=4.8.1)", "jinja2 (>=2.11.2)", "rlp (>=2.0.1)", "py-eth-sig-utils (>=0.4.0)", "py-ecc (>=1.7.1)", "eth-abi (>=1.3.0)", "mnemonic (>=0.13)", "base58 (>=1.0.2,<2.0)", "ecdsa (>=0.13)", "py-multihash (>=0.2.3)"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "automat"
|
name = "automat"
|
||||||
version = "20.2.0"
|
version = "20.2.0"
|
||||||
@ -85,22 +60,6 @@ python-versions = "*"
|
|||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pycparser = "*"
|
pycparser = "*"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "channels"
|
|
||||||
version = "3.0.3"
|
|
||||||
description = "Brings async, event-driven capabilities to Django. Django 2.2 and up only."
|
|
||||||
category = "main"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.6"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
asgiref = ">=3.2.10,<4"
|
|
||||||
daphne = ">=3.0,<4"
|
|
||||||
Django = ">=2.2"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
tests = ["pytest", "pytest-django", "pytest-asyncio", "async-generator", "async-timeout", "coverage (>=4.5,<5.0)"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chardet"
|
name = "chardet"
|
||||||
version = "4.0.0"
|
version = "4.0.0"
|
||||||
@ -109,26 +68,6 @@ category = "main"
|
|||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "click"
|
|
||||||
version = "8.0.1"
|
|
||||||
description = "Composable command line interface toolkit"
|
|
||||||
category = "main"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.6"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
|
||||||
importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "colorama"
|
|
||||||
version = "0.4.4"
|
|
||||||
description = "Cross-platform colored terminal text."
|
|
||||||
category = "main"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "constantly"
|
name = "constantly"
|
||||||
version = "15.1.0"
|
version = "15.1.0"
|
||||||
@ -157,22 +96,6 @@ pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"]
|
|||||||
ssh = ["bcrypt (>=3.1.5)"]
|
ssh = ["bcrypt (>=3.1.5)"]
|
||||||
test = ["pytest (>=3.6.0,!=3.9.0,!=3.9.1,!=3.9.2)", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"]
|
test = ["pytest (>=3.6.0,!=3.9.0,!=3.9.1,!=3.9.2)", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "daphne"
|
|
||||||
version = "3.0.2"
|
|
||||||
description = "Django ASGI (HTTP/WebSocket) server"
|
|
||||||
category = "main"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.6"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
asgiref = ">=3.2.10,<4"
|
|
||||||
autobahn = ">=0.18"
|
|
||||||
twisted = {version = ">=18.7", extras = ["tls"]}
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
tests = ["hypothesis (==4.23)", "pytest (>=3.10,<4.0)", "pytest-asyncio (>=0.8,<1.0)"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "defusedxml"
|
name = "defusedxml"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@ -266,6 +189,31 @@ mccabe = ">=0.6.0,<0.7.0"
|
|||||||
pycodestyle = ">=2.7.0,<2.8.0"
|
pycodestyle = ">=2.7.0,<2.8.0"
|
||||||
pyflakes = ">=2.3.0,<2.4.0"
|
pyflakes = ">=2.3.0,<2.4.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fsspec"
|
||||||
|
version = "2021.7.0"
|
||||||
|
description = "File-system specification"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
abfs = ["adlfs"]
|
||||||
|
adl = ["adlfs"]
|
||||||
|
dask = ["dask", "distributed"]
|
||||||
|
dropbox = ["dropboxdrivefs", "requests", "dropbox"]
|
||||||
|
entrypoints = ["importlib-metadata"]
|
||||||
|
gcs = ["gcsfs"]
|
||||||
|
git = ["pygit2"]
|
||||||
|
github = ["requests"]
|
||||||
|
gs = ["gcsfs"]
|
||||||
|
hdfs = ["pyarrow (>=1)"]
|
||||||
|
http = ["requests", "aiohttp"]
|
||||||
|
s3 = ["s3fs"]
|
||||||
|
sftp = ["paramiko"]
|
||||||
|
smb = ["smbprotocol"]
|
||||||
|
ssh = ["paramiko"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gql"
|
name = "gql"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
@ -315,14 +263,6 @@ gevent = ["gevent (>=1.4.0)"]
|
|||||||
setproctitle = ["setproctitle"]
|
setproctitle = ["setproctitle"]
|
||||||
tornado = ["tornado (>=0.2)"]
|
tornado = ["tornado (>=0.2)"]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "h11"
|
|
||||||
version = "0.12.0"
|
|
||||||
description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
|
|
||||||
category = "main"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.6"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyperlink"
|
name = "hyperlink"
|
||||||
version = "21.0.0"
|
version = "21.0.0"
|
||||||
@ -346,7 +286,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|||||||
name = "importlib-metadata"
|
name = "importlib-metadata"
|
||||||
version = "4.4.0"
|
version = "4.4.0"
|
||||||
description = "Read metadata from Python packages"
|
description = "Read metadata from Python packages"
|
||||||
category = "main"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
@ -412,25 +352,6 @@ six = "*"
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
test = ["pytest (>=2.7.3)", "pytest-cov", "coveralls", "futures", "pytest-benchmark", "mock"]
|
test = ["pytest (>=2.7.3)", "pytest-cov", "coveralls", "futures", "pytest-benchmark", "mock"]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pyasn1"
|
|
||||||
version = "0.4.8"
|
|
||||||
description = "ASN.1 types and codecs"
|
|
||||||
category = "main"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pyasn1-modules"
|
|
||||||
version = "0.2.8"
|
|
||||||
description = "A collection of ASN.1-based protocols modules."
|
|
||||||
category = "main"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
pyasn1 = ">=0.4.6,<0.5.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pycodestyle"
|
name = "pycodestyle"
|
||||||
version = "2.7.0"
|
version = "2.7.0"
|
||||||
@ -488,22 +409,6 @@ dev = ["sphinx", "sphinx-rtd-theme", "zope.interface", "cryptography (>=3.3.1,<4
|
|||||||
docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"]
|
docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"]
|
||||||
tests = ["pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)"]
|
tests = ["pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)"]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pyopenssl"
|
|
||||||
version = "19.1.0"
|
|
||||||
description = "Python wrapper module around the OpenSSL library"
|
|
||||||
category = "main"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
cryptography = ">=2.8"
|
|
||||||
six = ">=1.5.2"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
docs = ["sphinx", "sphinx-rtd-theme"]
|
|
||||||
test = ["flaky", "pretend", "pytest (>=3.0.1)"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "python-dotenv"
|
name = "python-dotenv"
|
||||||
version = "0.17.1"
|
version = "0.17.1"
|
||||||
@ -587,27 +492,6 @@ category = "main"
|
|||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "service-identity"
|
|
||||||
version = "21.1.0"
|
|
||||||
description = "Service identity verification for pyOpenSSL & cryptography."
|
|
||||||
category = "main"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
attrs = ">=19.1.0"
|
|
||||||
cryptography = "*"
|
|
||||||
pyasn1 = "*"
|
|
||||||
pyasn1-modules = "*"
|
|
||||||
six = "*"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
dev = ["coverage[toml] (>=5.0.2)", "pytest", "sphinx", "furo", "idna", "pyopenssl"]
|
|
||||||
docs = ["sphinx", "furo"]
|
|
||||||
idna = ["idna"]
|
|
||||||
tests = ["coverage[toml] (>=5.0.2)", "pytest"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "six"
|
name = "six"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
@ -673,11 +557,8 @@ attrs = ">=19.2.0"
|
|||||||
Automat = ">=0.3.0"
|
Automat = ">=0.3.0"
|
||||||
constantly = ">=15.1"
|
constantly = ">=15.1"
|
||||||
hyperlink = ">=17.1.1"
|
hyperlink = ">=17.1.1"
|
||||||
idna = {version = ">=0.6,<2.3 || >2.3", optional = true, markers = "extra == \"tls\""}
|
|
||||||
incremental = ">=16.10.1"
|
incremental = ">=16.10.1"
|
||||||
PyHamcrest = ">=1.9.0,<1.10.0 || >1.10.0"
|
PyHamcrest = ">=1.9.0,<1.10.0 || >1.10.0"
|
||||||
pyopenssl = {version = ">=16.0.0", optional = true, markers = "extra == \"tls\""}
|
|
||||||
service_identity = {version = ">=18.1.0", optional = true, markers = "extra == \"tls\""}
|
|
||||||
"zope.interface" = ">=4.4.2"
|
"zope.interface" = ">=4.4.2"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
@ -692,19 +573,6 @@ soap = ["soappy"]
|
|||||||
tls = ["pyopenssl (>=16.0.0)", "service_identity (>=18.1.0)", "idna (>=0.6,!=2.3)"]
|
tls = ["pyopenssl (>=16.0.0)", "service_identity (>=18.1.0)", "idna (>=0.6,!=2.3)"]
|
||||||
windows_platform = ["pywin32 (!=226)", "pyopenssl (>=16.0.0)", "service_identity (>=18.1.0)", "idna (>=0.6,!=2.3)", "pyasn1", "cryptography (>=2.5)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "soappy", "pyserial (>=3.0)", "h2 (>=3.0,<4.0)", "priority (>=1.1.0,<2.0)", "pywin32 (!=226)"]
|
windows_platform = ["pywin32 (!=226)", "pyopenssl (>=16.0.0)", "service_identity (>=18.1.0)", "idna (>=0.6,!=2.3)", "pyasn1", "cryptography (>=2.5)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "soappy", "pyserial (>=3.0)", "h2 (>=3.0,<4.0)", "priority (>=1.1.0,<2.0)", "pywin32 (!=226)"]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "txaio"
|
|
||||||
version = "21.2.1"
|
|
||||||
description = "Compatibility API between asyncio/Twisted/Trollius"
|
|
||||||
category = "main"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.6"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
all = ["zope.interface (>=5.2.0)", "twisted (>=20.3.0)"]
|
|
||||||
dev = ["wheel", "pytest (>=2.6.4)", "pytest-cov (>=1.8.1)", "pep8 (>=1.6.2)", "sphinx (>=1.2.3)", "pyenchant (>=1.6.6)", "sphinxcontrib-spelling (>=2.1.2)", "sphinx-rtd-theme (>=0.1.9)", "tox (>=2.1.1)", "mock (==1.3.0)", "twine (>=1.6.5)", "tox-gh-actions (>=2.2.0)"]
|
|
||||||
twisted = ["zope.interface (>=5.2.0)", "twisted (>=20.3.0)"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typing-extensions"
|
name = "typing-extensions"
|
||||||
version = "3.10.0.0"
|
version = "3.10.0.0"
|
||||||
@ -726,23 +594,6 @@ brotli = ["brotlipy (>=0.6.0)"]
|
|||||||
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
|
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
|
||||||
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "uvicorn"
|
|
||||||
version = "0.14.0"
|
|
||||||
description = "The lightning-fast ASGI server."
|
|
||||||
category = "main"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
asgiref = ">=3.3.4"
|
|
||||||
click = ">=7"
|
|
||||||
h11 = ">=0.8"
|
|
||||||
typing-extensions = {version = "*", markers = "python_version < \"3.8\""}
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
standard = ["websockets (>=9.1)", "httptools (>=0.2.0,<0.3.0)", "watchgod (>=0.6)", "python-dotenv (>=0.13)", "PyYAML (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "colorama (>=0.4)"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "websockets"
|
name = "websockets"
|
||||||
version = "9.1"
|
version = "9.1"
|
||||||
@ -755,7 +606,7 @@ python-versions = ">=3.6.1"
|
|||||||
name = "zipp"
|
name = "zipp"
|
||||||
version = "3.4.1"
|
version = "3.4.1"
|
||||||
description = "Backport of pathlib-compatible object wrapper for zip files"
|
description = "Backport of pathlib-compatible object wrapper for zip files"
|
||||||
category = "main"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
@ -779,7 +630,7 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.7"
|
python-versions = "^3.7"
|
||||||
content-hash = "84c68730a52d039da15d782202c5490079398992ede936c33a696cb97c1bfa5d"
|
content-hash = "a855859b9c8eb70c722c6e1ce320e3b4a8b554b8eeb12e42cfaea4dce857855d"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
asgiref = [
|
asgiref = [
|
||||||
@ -790,10 +641,6 @@ attrs = [
|
|||||||
{file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"},
|
{file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"},
|
||||||
{file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"},
|
{file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"},
|
||||||
]
|
]
|
||||||
autobahn = [
|
|
||||||
{file = "autobahn-21.2.1-py2.py3-none-any.whl", hash = "sha256:41a3a3f89cde48643baf4e105d9491c566295f9abee951379e59121784044b8b"},
|
|
||||||
{file = "autobahn-21.2.1.tar.gz", hash = "sha256:7e6b1bf95196b733978bab2d54a7ab8899c16ce11be369dc58422c07b7eea726"},
|
|
||||||
]
|
|
||||||
automat = [
|
automat = [
|
||||||
{file = "Automat-20.2.0-py2.py3-none-any.whl", hash = "sha256:b6feb6455337df834f6c9962d6ccf771515b7d939bca142b29c20c2376bc6111"},
|
{file = "Automat-20.2.0-py2.py3-none-any.whl", hash = "sha256:b6feb6455337df834f6c9962d6ccf771515b7d939bca142b29c20c2376bc6111"},
|
||||||
{file = "Automat-20.2.0.tar.gz", hash = "sha256:7979803c74610e11ef0c0d68a2942b152df52da55336e0c9d58daf1831cbdf33"},
|
{file = "Automat-20.2.0.tar.gz", hash = "sha256:7979803c74610e11ef0c0d68a2942b152df52da55336e0c9d58daf1831cbdf33"},
|
||||||
@ -853,22 +700,10 @@ cffi = [
|
|||||||
{file = "cffi-1.14.5-cp39-cp39-win_amd64.whl", hash = "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d"},
|
{file = "cffi-1.14.5-cp39-cp39-win_amd64.whl", hash = "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d"},
|
||||||
{file = "cffi-1.14.5.tar.gz", hash = "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"},
|
{file = "cffi-1.14.5.tar.gz", hash = "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"},
|
||||||
]
|
]
|
||||||
channels = [
|
|
||||||
{file = "channels-3.0.3-py3-none-any.whl", hash = "sha256:3f15bdd2138bb4796e76ea588a0a344b12a7964ea9b2e456f992fddb988a4317"},
|
|
||||||
{file = "channels-3.0.3.tar.gz", hash = "sha256:056b72e51080a517a0f33a0a30003e03833b551d75394d6636c885d4edb8188f"},
|
|
||||||
]
|
|
||||||
chardet = [
|
chardet = [
|
||||||
{file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"},
|
{file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"},
|
||||||
{file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"},
|
{file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"},
|
||||||
]
|
]
|
||||||
click = [
|
|
||||||
{file = "click-8.0.1-py3-none-any.whl", hash = "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"},
|
|
||||||
{file = "click-8.0.1.tar.gz", hash = "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a"},
|
|
||||||
]
|
|
||||||
colorama = [
|
|
||||||
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
|
|
||||||
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
|
|
||||||
]
|
|
||||||
constantly = [
|
constantly = [
|
||||||
{file = "constantly-15.1.0-py2.py3-none-any.whl", hash = "sha256:dd2fa9d6b1a51a83f0d7dd76293d734046aa176e384bf6e33b7e44880eb37c5d"},
|
{file = "constantly-15.1.0-py2.py3-none-any.whl", hash = "sha256:dd2fa9d6b1a51a83f0d7dd76293d734046aa176e384bf6e33b7e44880eb37c5d"},
|
||||||
{file = "constantly-15.1.0.tar.gz", hash = "sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"},
|
{file = "constantly-15.1.0.tar.gz", hash = "sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"},
|
||||||
@ -894,10 +729,6 @@ cryptography = [
|
|||||||
{file = "cryptography-3.0-cp38-cp38-win_amd64.whl", hash = "sha256:bea0b0468f89cdea625bb3f692cd7a4222d80a6bdafd6fb923963f2b9da0e15f"},
|
{file = "cryptography-3.0-cp38-cp38-win_amd64.whl", hash = "sha256:bea0b0468f89cdea625bb3f692cd7a4222d80a6bdafd6fb923963f2b9da0e15f"},
|
||||||
{file = "cryptography-3.0.tar.gz", hash = "sha256:8e924dbc025206e97756e8903039662aa58aa9ba357d8e1d8fc29e3092322053"},
|
{file = "cryptography-3.0.tar.gz", hash = "sha256:8e924dbc025206e97756e8903039662aa58aa9ba357d8e1d8fc29e3092322053"},
|
||||||
]
|
]
|
||||||
daphne = [
|
|
||||||
{file = "daphne-3.0.2-py3-none-any.whl", hash = "sha256:a9af943c79717bc52fe64a3c236ae5d3adccc8b5be19c881b442d2c3db233393"},
|
|
||||||
{file = "daphne-3.0.2.tar.gz", hash = "sha256:76ffae916ba3aa66b46996c14fa713e46004788167a4873d647544e750e0e99f"},
|
|
||||||
]
|
|
||||||
defusedxml = [
|
defusedxml = [
|
||||||
{file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
|
{file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
|
||||||
{file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
|
{file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
|
||||||
@ -929,6 +760,10 @@ flake8 = [
|
|||||||
{file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"},
|
{file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"},
|
||||||
{file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"},
|
{file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"},
|
||||||
]
|
]
|
||||||
|
fsspec = [
|
||||||
|
{file = "fsspec-2021.7.0-py3-none-any.whl", hash = "sha256:86822ccf367da99957f49db64f7d5fd3d8d21444fac4dfdc8ebc38ee93d478c6"},
|
||||||
|
{file = "fsspec-2021.7.0.tar.gz", hash = "sha256:792ebd3b54de0b30f1ce73f0ba0a8bcc864724f2d9f248cb8d0ece47db0cbde8"},
|
||||||
|
]
|
||||||
gql = [
|
gql = [
|
||||||
{file = "gql-2.0.0-py2.py3-none-any.whl", hash = "sha256:35032ddd4bfe6b8f3169f806b022168932385d751eacc5c5f7122e0b3f4d6b88"},
|
{file = "gql-2.0.0-py2.py3-none-any.whl", hash = "sha256:35032ddd4bfe6b8f3169f806b022168932385d751eacc5c5f7122e0b3f4d6b88"},
|
||||||
{file = "gql-2.0.0.tar.gz", hash = "sha256:fe8d3a08047f77362ddfcfddba7cae377da2dd66f5e61c59820419c9283d4fb5"},
|
{file = "gql-2.0.0.tar.gz", hash = "sha256:fe8d3a08047f77362ddfcfddba7cae377da2dd66f5e61c59820419c9283d4fb5"},
|
||||||
@ -941,10 +776,6 @@ gunicorn = [
|
|||||||
{file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"},
|
{file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"},
|
||||||
{file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"},
|
{file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"},
|
||||||
]
|
]
|
||||||
h11 = [
|
|
||||||
{file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"},
|
|
||||||
{file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"},
|
|
||||||
]
|
|
||||||
hyperlink = [
|
hyperlink = [
|
||||||
{file = "hyperlink-21.0.0-py2.py3-none-any.whl", hash = "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4"},
|
{file = "hyperlink-21.0.0-py2.py3-none-any.whl", hash = "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4"},
|
||||||
{file = "hyperlink-21.0.0.tar.gz", hash = "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b"},
|
{file = "hyperlink-21.0.0.tar.gz", hash = "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b"},
|
||||||
@ -979,36 +810,6 @@ oauthlib = [
|
|||||||
promise = [
|
promise = [
|
||||||
{file = "promise-2.3.tar.gz", hash = "sha256:dfd18337c523ba4b6a58801c164c1904a9d4d1b1747c7d5dbf45b693a49d93d0"},
|
{file = "promise-2.3.tar.gz", hash = "sha256:dfd18337c523ba4b6a58801c164c1904a9d4d1b1747c7d5dbf45b693a49d93d0"},
|
||||||
]
|
]
|
||||||
pyasn1 = [
|
|
||||||
{file = "pyasn1-0.4.8-py2.4.egg", hash = "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"},
|
|
||||||
{file = "pyasn1-0.4.8-py2.5.egg", hash = "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf"},
|
|
||||||
{file = "pyasn1-0.4.8-py2.6.egg", hash = "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"},
|
|
||||||
{file = "pyasn1-0.4.8-py2.7.egg", hash = "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8"},
|
|
||||||
{file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"},
|
|
||||||
{file = "pyasn1-0.4.8-py3.1.egg", hash = "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86"},
|
|
||||||
{file = "pyasn1-0.4.8-py3.2.egg", hash = "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"},
|
|
||||||
{file = "pyasn1-0.4.8-py3.3.egg", hash = "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576"},
|
|
||||||
{file = "pyasn1-0.4.8-py3.4.egg", hash = "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"},
|
|
||||||
{file = "pyasn1-0.4.8-py3.5.egg", hash = "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"},
|
|
||||||
{file = "pyasn1-0.4.8-py3.6.egg", hash = "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359"},
|
|
||||||
{file = "pyasn1-0.4.8-py3.7.egg", hash = "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776"},
|
|
||||||
{file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"},
|
|
||||||
]
|
|
||||||
pyasn1-modules = [
|
|
||||||
{file = "pyasn1-modules-0.2.8.tar.gz", hash = "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e"},
|
|
||||||
{file = "pyasn1_modules-0.2.8-py2.4.egg", hash = "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199"},
|
|
||||||
{file = "pyasn1_modules-0.2.8-py2.5.egg", hash = "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405"},
|
|
||||||
{file = "pyasn1_modules-0.2.8-py2.6.egg", hash = "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb"},
|
|
||||||
{file = "pyasn1_modules-0.2.8-py2.7.egg", hash = "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8"},
|
|
||||||
{file = "pyasn1_modules-0.2.8-py2.py3-none-any.whl", hash = "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"},
|
|
||||||
{file = "pyasn1_modules-0.2.8-py3.1.egg", hash = "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d"},
|
|
||||||
{file = "pyasn1_modules-0.2.8-py3.2.egg", hash = "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45"},
|
|
||||||
{file = "pyasn1_modules-0.2.8-py3.3.egg", hash = "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4"},
|
|
||||||
{file = "pyasn1_modules-0.2.8-py3.4.egg", hash = "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811"},
|
|
||||||
{file = "pyasn1_modules-0.2.8-py3.5.egg", hash = "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed"},
|
|
||||||
{file = "pyasn1_modules-0.2.8-py3.6.egg", hash = "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0"},
|
|
||||||
{file = "pyasn1_modules-0.2.8-py3.7.egg", hash = "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd"},
|
|
||||||
]
|
|
||||||
pycodestyle = [
|
pycodestyle = [
|
||||||
{file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"},
|
{file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"},
|
||||||
{file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"},
|
{file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"},
|
||||||
@ -1033,10 +834,6 @@ pyjwt = [
|
|||||||
{file = "PyJWT-2.1.0-py3-none-any.whl", hash = "sha256:934d73fbba91b0483d3857d1aff50e96b2a892384ee2c17417ed3203f173fca1"},
|
{file = "PyJWT-2.1.0-py3-none-any.whl", hash = "sha256:934d73fbba91b0483d3857d1aff50e96b2a892384ee2c17417ed3203f173fca1"},
|
||||||
{file = "PyJWT-2.1.0.tar.gz", hash = "sha256:fba44e7898bbca160a2b2b501f492824fc8382485d3a6f11ba5d0c1937ce6130"},
|
{file = "PyJWT-2.1.0.tar.gz", hash = "sha256:fba44e7898bbca160a2b2b501f492824fc8382485d3a6f11ba5d0c1937ce6130"},
|
||||||
]
|
]
|
||||||
pyopenssl = [
|
|
||||||
{file = "pyOpenSSL-19.1.0-py2.py3-none-any.whl", hash = "sha256:621880965a720b8ece2f1b2f54ea2071966ab00e2970ad2ce11d596102063504"},
|
|
||||||
{file = "pyOpenSSL-19.1.0.tar.gz", hash = "sha256:9a24494b2602aaf402be5c9e30a0b82d4a5c67528fe8fb475e3f3bc00dd69507"},
|
|
||||||
]
|
|
||||||
python-dotenv = [
|
python-dotenv = [
|
||||||
{file = "python-dotenv-0.17.1.tar.gz", hash = "sha256:b1ae5e9643d5ed987fc57cc2583021e38db531946518130777734f9589b3141f"},
|
{file = "python-dotenv-0.17.1.tar.gz", hash = "sha256:b1ae5e9643d5ed987fc57cc2583021e38db531946518130777734f9589b3141f"},
|
||||||
{file = "python_dotenv-0.17.1-py2.py3-none-any.whl", hash = "sha256:00aa34e92d992e9f8383730816359647f358f4a3be1ba45e5a5cefd27ee91544"},
|
{file = "python_dotenv-0.17.1-py2.py3-none-any.whl", hash = "sha256:00aa34e92d992e9f8383730816359647f358f4a3be1ba45e5a5cefd27ee91544"},
|
||||||
@ -1066,10 +863,6 @@ semver = [
|
|||||||
{file = "semver-2.13.0-py2.py3-none-any.whl", hash = "sha256:ced8b23dceb22134307c1b8abfa523da14198793d9787ac838e70e29e77458d4"},
|
{file = "semver-2.13.0-py2.py3-none-any.whl", hash = "sha256:ced8b23dceb22134307c1b8abfa523da14198793d9787ac838e70e29e77458d4"},
|
||||||
{file = "semver-2.13.0.tar.gz", hash = "sha256:fa0fe2722ee1c3f57eac478820c3a5ae2f624af8264cbdf9000c980ff7f75e3f"},
|
{file = "semver-2.13.0.tar.gz", hash = "sha256:fa0fe2722ee1c3f57eac478820c3a5ae2f624af8264cbdf9000c980ff7f75e3f"},
|
||||||
]
|
]
|
||||||
service-identity = [
|
|
||||||
{file = "service-identity-21.1.0.tar.gz", hash = "sha256:6e6c6086ca271dc11b033d17c3a8bea9f24ebff920c587da090afc9519419d34"},
|
|
||||||
{file = "service_identity-21.1.0-py2.py3-none-any.whl", hash = "sha256:f0b0caac3d40627c3c04d7a51b6e06721857a0e10a8775f2d1d7e72901b3a7db"},
|
|
||||||
]
|
|
||||||
six = [
|
six = [
|
||||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||||
@ -1112,10 +905,6 @@ twisted = [
|
|||||||
{file = "Twisted-20.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d95803193561a243cb0401b0567c6b7987d3f2a67046770e1dccd1c9e49a9780"},
|
{file = "Twisted-20.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d95803193561a243cb0401b0567c6b7987d3f2a67046770e1dccd1c9e49a9780"},
|
||||||
{file = "Twisted-20.3.0.tar.bz2", hash = "sha256:d72c55b5d56e176563b91d11952d13b01af8725c623e498db5507b6614fc1e10"},
|
{file = "Twisted-20.3.0.tar.bz2", hash = "sha256:d72c55b5d56e176563b91d11952d13b01af8725c623e498db5507b6614fc1e10"},
|
||||||
]
|
]
|
||||||
txaio = [
|
|
||||||
{file = "txaio-21.2.1-py2.py3-none-any.whl", hash = "sha256:c16b55f9a67b2419cfdf8846576e2ec9ba94fe6978a83080c352a80db31c93fb"},
|
|
||||||
{file = "txaio-21.2.1.tar.gz", hash = "sha256:7d6f89745680233f1c4db9ddb748df5e88d2a7a37962be174c0fd04c8dba1dc8"},
|
|
||||||
]
|
|
||||||
typing-extensions = [
|
typing-extensions = [
|
||||||
{file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"},
|
{file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"},
|
||||||
{file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"},
|
{file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"},
|
||||||
@ -1125,10 +914,6 @@ urllib3 = [
|
|||||||
{file = "urllib3-1.26.6-py2.py3-none-any.whl", hash = "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4"},
|
{file = "urllib3-1.26.6-py2.py3-none-any.whl", hash = "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4"},
|
||||||
{file = "urllib3-1.26.6.tar.gz", hash = "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"},
|
{file = "urllib3-1.26.6.tar.gz", hash = "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"},
|
||||||
]
|
]
|
||||||
uvicorn = [
|
|
||||||
{file = "uvicorn-0.14.0-py3-none-any.whl", hash = "sha256:2a76bb359171a504b3d1c853409af3adbfa5cef374a4a59e5881945a97a93eae"},
|
|
||||||
{file = "uvicorn-0.14.0.tar.gz", hash = "sha256:45ad7dfaaa7d55cab4cd1e85e03f27e9d60bc067ddc59db52a2b0aeca8870292"},
|
|
||||||
]
|
|
||||||
websockets = [
|
websockets = [
|
||||||
{file = "websockets-9.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d144b350045c53c8ff09aa1cfa955012dd32f00c7e0862c199edcabb1a8b32da"},
|
{file = "websockets-9.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d144b350045c53c8ff09aa1cfa955012dd32f00c7e0862c199edcabb1a8b32da"},
|
||||||
{file = "websockets-9.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:b4ad84b156cf50529b8ac5cc1638c2cf8680490e3fccb6121316c8c02620a2e4"},
|
{file = "websockets-9.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:b4ad84b156cf50529b8ac5cc1638c2cf8680490e3fccb6121316c8c02620a2e4"},
|
||||||
|
@ -8,7 +8,6 @@ authors = ["Your Name <you@example.com>"]
|
|||||||
python = "^3.7"
|
python = "^3.7"
|
||||||
Django = "^3.2.3"
|
Django = "^3.2.3"
|
||||||
django-rest-framework = "^0.1.0"
|
django-rest-framework = "^0.1.0"
|
||||||
channels = "^3.0.3"
|
|
||||||
djangorestframework-dataclasses = "^0.9"
|
djangorestframework-dataclasses = "^0.9"
|
||||||
social-auth-app-django = "^4.0.0"
|
social-auth-app-django = "^4.0.0"
|
||||||
python-dotenv = "^0.17.1"
|
python-dotenv = "^0.17.1"
|
||||||
@ -23,7 +22,7 @@ requests = "^2.25.1"
|
|||||||
pyga = "^2.6.2"
|
pyga = "^2.6.2"
|
||||||
django-cors-headers = "^3.7.0"
|
django-cors-headers = "^3.7.0"
|
||||||
cryptography = "3.0"
|
cryptography = "3.0"
|
||||||
uvicorn = "^0.14.0"
|
fsspec = "^2021.7.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
flake8 = "^3.9.2"
|
flake8 = "^3.9.2"
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import fsspec
|
||||||
|
import os
|
||||||
import asyncio
|
import asyncio
|
||||||
import random
|
import random
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -15,8 +17,9 @@ from rest_framework.serializers import ModelSerializer, Serializer
|
|||||||
from rest_framework_dataclasses.serializers import DataclassSerializer
|
from rest_framework_dataclasses.serializers import DataclassSerializer
|
||||||
from social_django.models import UserSocialAuth
|
from social_django.models import UserSocialAuth
|
||||||
from typing import List
|
from typing import List
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
from .consumers import GatewayAdminConnection
|
from .gateway import GatewayAdminConnection
|
||||||
from .sponsors import check_is_sponsor, check_is_sponsor_cached
|
from .sponsors import check_is_sponsor, check_is_sponsor_cached
|
||||||
from .models import Config, Gateway, User
|
from .models import Config, Gateway, User
|
||||||
|
|
||||||
@ -74,19 +77,26 @@ class AppVersionViewSet(ListModelMixin, GenericViewSet):
|
|||||||
queryset = ''
|
queryset = ''
|
||||||
|
|
||||||
def _get_versions(self):
|
def _get_versions(self):
|
||||||
return [self._get_version(x) for x in settings.APP_DIST_PATH.iterdir()]
|
fs = fsspec.filesystem(urlparse(settings.APP_DIST_STORAGE).scheme)
|
||||||
|
return [
|
||||||
|
self._get_version(x['name'])
|
||||||
|
for x in fs.listdir(settings.APP_DIST_STORAGE)
|
||||||
|
]
|
||||||
|
|
||||||
def _get_version(self, dir: Path):
|
def _get_version(self, dir):
|
||||||
|
fs = fsspec.filesystem(urlparse(settings.APP_DIST_STORAGE).scheme)
|
||||||
plugins = [
|
plugins = [
|
||||||
x.name for x in dir.iterdir()
|
os.path.basename(x['name'])
|
||||||
if x.is_dir() and x.name not in [
|
for x in fs.listdir(dir)
|
||||||
|
if x['type'] == 'directory' and os.path.basename(x['name'])
|
||||||
|
not in [
|
||||||
'tabby-web-container',
|
'tabby-web-container',
|
||||||
'tabby-web-demo',
|
'tabby-web-demo',
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
return AppVersion(
|
return AppVersion(
|
||||||
version=dir.name,
|
version=os.path.basename(dir),
|
||||||
plugins=plugins,
|
plugins=plugins,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -166,7 +176,7 @@ class InstanceInfoViewSet(RetrieveModelMixin, GenericViewSet):
|
|||||||
|
|
||||||
class NoGatewaysError(APIException):
|
class NoGatewaysError(APIException):
|
||||||
status_code = status.HTTP_503_SERVICE_UNAVAILABLE
|
status_code = status.HTTP_503_SERVICE_UNAVAILABLE
|
||||||
default_detail ='No connection gateways available.'
|
default_detail = 'No connection gateways available.'
|
||||||
default_code = 'no_gateways'
|
default_code = 'no_gateways'
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import os
|
|||||||
import secrets
|
import secrets
|
||||||
import ssl
|
import ssl
|
||||||
import websockets
|
import websockets
|
||||||
from channels.generic.websocket import AsyncWebsocketConsumer
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
|
|
||||||
@ -91,35 +90,3 @@ class GatewayAdminConnection:
|
|||||||
async def close(self):
|
async def close(self):
|
||||||
await self.socket.close()
|
await self.socket.close()
|
||||||
await self.context.__aexit__(None, None, None)
|
await self.context.__aexit__(None, None, None)
|
||||||
|
|
||||||
|
|
||||||
class TCPConsumer(AsyncWebsocketConsumer):
|
|
||||||
async def connect(self):
|
|
||||||
self.closed = False
|
|
||||||
self.conn = GatewayConnection(
|
|
||||||
self.scope['url_route']['kwargs']['host'],
|
|
||||||
int(self.scope['url_route']['kwargs']['port']),
|
|
||||||
)
|
|
||||||
await self.conn.connect()
|
|
||||||
await self.accept()
|
|
||||||
self.reader = asyncio.get_event_loop().create_task(self.socket_reader())
|
|
||||||
|
|
||||||
async def disconnect(self, close_code):
|
|
||||||
self.closed = True
|
|
||||||
await self.conn.close()
|
|
||||||
|
|
||||||
async def receive(self, bytes_data):
|
|
||||||
await self.conn.send(bytes_data)
|
|
||||||
|
|
||||||
async def socket_reader(self):
|
|
||||||
while True:
|
|
||||||
if self.closed:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
data = await self.conn.recv(timeout=10)
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
continue
|
|
||||||
except websockets.exceptions.ConnectionClosed:
|
|
||||||
await self.close()
|
|
||||||
return
|
|
||||||
await self.send(bytes_data=data)
|
|
@ -1,3 +1,4 @@
|
|||||||
|
import fsspec
|
||||||
import logging
|
import logging
|
||||||
import requests
|
import requests
|
||||||
import shutil
|
import shutil
|
||||||
@ -6,6 +7,7 @@ import tempfile
|
|||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
@ -16,7 +18,9 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
version = options['version']
|
version = options['version']
|
||||||
target: Path = settings.APP_DIST_PATH / version
|
target = f'{settings.APP_DIST_STORAGE}/{version}'
|
||||||
|
|
||||||
|
fs = fsspec.filesystem(urlparse(settings.APP_DIST_STORAGE).scheme)
|
||||||
|
|
||||||
plugin_list = [
|
plugin_list = [
|
||||||
'tabby-web-container',
|
'tabby-web-container',
|
||||||
@ -51,9 +55,11 @@ class Command(BaseCommand):
|
|||||||
subprocess.check_call(
|
subprocess.check_call(
|
||||||
['tar', '-xzf', f.name, '-C', str(extraction_tmp)]
|
['tar', '-xzf', f.name, '-C', str(extraction_tmp)]
|
||||||
)
|
)
|
||||||
shutil.move(Path(extraction_tmp) / 'package', plugin_final_target)
|
shutil.move(
|
||||||
|
Path(extraction_tmp) / 'package', plugin_final_target
|
||||||
|
)
|
||||||
|
|
||||||
if target.exists():
|
if fs.exists(target):
|
||||||
shutil.rmtree(target)
|
fs.rm(target, recursive=True)
|
||||||
shutil.copytree(tempdir, target)
|
fs.mkdir(target)
|
||||||
target.chmod(0o755)
|
fs.put(str(tempdir), target, recursive=True)
|
||||||
|
@ -2,7 +2,6 @@ from django.urls import path, re_path, include
|
|||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
|
||||||
from . import api
|
from . import api
|
||||||
from . import consumers
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
|
|
||||||
@ -16,13 +15,9 @@ urlpatterns = [
|
|||||||
path('api/1/instance-info', api.InstanceInfoViewSet.as_view({'get': 'retrieve'})),
|
path('api/1/instance-info', api.InstanceInfoViewSet.as_view({'get': 'retrieve'})),
|
||||||
path('api/1/gateways/choose', api.ChooseGatewayViewSet.as_view({'post': 'retrieve'})),
|
path('api/1/gateways/choose', api.ChooseGatewayViewSet.as_view({'post': 'retrieve'})),
|
||||||
|
|
||||||
# re_path('^(|login|app)$', views.IndexView.as_view()),
|
re_path('^(|login|app)$', views.IndexView.as_view()),
|
||||||
|
path('terminal', views.TerminalView.as_view()),
|
||||||
|
|
||||||
# path('terminal', views.TerminalView.as_view()),
|
|
||||||
path('app-dist/<version>/<path:path>', views.AppDistView.as_view()),
|
path('app-dist/<version>/<path:path>', views.AppDistView.as_view()),
|
||||||
path('', include(router.urls)),
|
path('', include(router.urls)),
|
||||||
]
|
]
|
||||||
|
|
||||||
websocket_urlpatterns = [
|
|
||||||
re_path(r'^api/1/gateway/tcp/(?P<host>[^/]+):(?P<port>\d+)$', consumers.TCPConsumer.as_asgi()),
|
|
||||||
]
|
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
import os
|
import fsspec
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.http.response import HttpResponseRedirect
|
||||||
from django.views import static
|
from django.views import static
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
|
||||||
class IndexView(APIView):
|
class IndexView(APIView):
|
||||||
def get(self, request, format=None):
|
def get(self, request, format=None):
|
||||||
return static.serve(request, 'index.html', document_root=str(settings.BASE_DIR / 'build'))
|
return static.serve(request, 'index.html', document_root=str(settings.FRONTEND_BUILD_DIR))
|
||||||
|
|
||||||
|
|
||||||
class TerminalView(APIView):
|
class TerminalView(APIView):
|
||||||
def get(self, request, format=None):
|
def get(self, request, format=None):
|
||||||
response = static.serve(request, 'terminal.html', document_root=str(settings.BASE_DIR / 'build'))
|
response = static.serve(request, 'terminal.html', document_root=str(settings.FRONTEND_BUILD_DIR))
|
||||||
response['X-Frame-Options'] = 'SAMEORIGIN'
|
response['X-Frame-Options'] = 'SAMEORIGIN'
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
class AppDistView(APIView):
|
class AppDistView(APIView):
|
||||||
def get(self, request, version=None, path=None, format=None):
|
def get(self, request, version=None, path=None, format=None):
|
||||||
return static.serve(request, os.path.join(version, path), document_root=str(settings.APP_DIST_PATH))
|
fs = fsspec.filesystem(urlparse(settings.APP_DIST_STORAGE).scheme)
|
||||||
|
url = f'{settings.APP_DIST_STORAGE}/{version}/{path}'
|
||||||
|
return HttpResponseRedirect(fs.url(url))
|
||||||
# class BuildView(APIView):
|
|
||||||
# def get(self, request, path=None, format=None):
|
|
||||||
# return static.serve(request, path, document_root=str(settings.BASE_DIR / 'build'))
|
|
||||||
|
@ -4,15 +4,9 @@ import os
|
|||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tabby.settings')
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tabby.settings')
|
||||||
django.setup()
|
django.setup()
|
||||||
|
|
||||||
from channels.auth import AuthMiddlewareStack
|
from channels.routing import ProtocolTypeRouter
|
||||||
from channels.routing import ProtocolTypeRouter, URLRouter
|
|
||||||
from django.core.asgi import get_asgi_application
|
from django.core.asgi import get_asgi_application
|
||||||
|
|
||||||
from .app.urls import websocket_urlpatterns
|
|
||||||
|
|
||||||
application = ProtocolTypeRouter({
|
application = ProtocolTypeRouter({
|
||||||
'http': get_asgi_application(),
|
'http': get_asgi_application(),
|
||||||
'websocket': AuthMiddlewareStack(
|
|
||||||
URLRouter(websocket_urlpatterns),
|
|
||||||
),
|
|
||||||
})
|
})
|
||||||
|
@ -8,6 +8,7 @@ load_dotenv()
|
|||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
FRONTEND_BUILD_DIR = BASE_DIR / '../frontend/build'
|
||||||
|
|
||||||
# Quick-start development settings - unsuitable for production
|
# Quick-start development settings - unsuitable for production
|
||||||
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
|
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
|
||||||
@ -32,7 +33,6 @@ INSTALLED_APPS = [
|
|||||||
'django.contrib.sessions',
|
'django.contrib.sessions',
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
'channels',
|
|
||||||
'rest_framework',
|
'rest_framework',
|
||||||
'social_django',
|
'social_django',
|
||||||
'corsheaders',
|
'corsheaders',
|
||||||
@ -70,7 +70,6 @@ TEMPLATES = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
ASGI_APPLICATION = 'tabby.asgi.application'
|
|
||||||
WSGI_APPLICATION = 'tabby.wsgi.application'
|
WSGI_APPLICATION = 'tabby.wsgi.application'
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
@ -138,6 +137,7 @@ LOGGING = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
|
STATICFILES_DIRS = [FRONTEND_BUILD_DIR]
|
||||||
|
|
||||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ SOCIAL_AUTH_PIPELINE = (
|
|||||||
'social_core.pipeline.user.user_details',
|
'social_core.pipeline.user.user_details',
|
||||||
)
|
)
|
||||||
|
|
||||||
APP_DIST_PATH = Path(os.getenv('APP_DIST_PATH', BASE_DIR / 'app-dist'))
|
APP_DIST_STORAGE = os.getenv('APP_DIST_STORAGE', 'file://' + str(BASE_DIR / 'app-dist'))
|
||||||
NPM_REGISTRY = os.getenv('NPM_REGISTRY', 'https://registry.npmjs.org').rstrip('/')
|
NPM_REGISTRY = os.getenv('NPM_REGISTRY', 'https://registry.npmjs.org').rstrip('/')
|
||||||
|
|
||||||
FRONTEND_URL = None
|
FRONTEND_URL = None
|
||||||
|
@ -31,7 +31,7 @@ function start () {
|
|||||||
app.set('view engine', 'html')
|
app.set('view engine', 'html')
|
||||||
app.set('views', DIST_FOLDER)
|
app.set('views', DIST_FOLDER)
|
||||||
|
|
||||||
app.get('*.*', express.static(DIST_FOLDER, {
|
app.get('*.*', express.static(join(DIST_FOLDER, 'static'), {
|
||||||
maxAge: '1y',
|
maxAge: '1y',
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ module.exports = {
|
|||||||
output: {
|
output: {
|
||||||
path: outputPath,
|
path: outputPath,
|
||||||
pathinfo: true,
|
pathinfo: true,
|
||||||
publicPath: '/',
|
publicPath: '/static/',
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
chunkFilename: '[name].bundle.js',
|
chunkFilename: '[name].bundle.js',
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user