bump dependencies

use json provider interface for quart
This commit is contained in:
Luna 2022-08-13 16:55:13 -03:00
parent 3c815cf872
commit 768611cc4e
10 changed files with 94 additions and 55 deletions

View File

@ -1,4 +1,4 @@
image: python:3.9-alpine image: python:3.10-alpine
variables: variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"

View File

@ -29,7 +29,8 @@ from litecord.errors import MessageNotFound, Forbidden
from litecord.enums import MessageType, ChannelType, GUILD_CHANS from litecord.enums import MessageType, ChannelType, GUILD_CHANS
from litecord.schemas import validate, MESSAGE_CREATE from litecord.schemas import validate, MESSAGE_CREATE
from litecord.utils import pg_set_json, query_tuple_from_args, extract_limit from litecord.utils import query_tuple_from_args, extract_limit
from litecord.json import pg_set_json
from litecord.permissions import get_permissions from litecord.permissions import get_permissions
from litecord.embed.sanitizer import fill_embed from litecord.embed.sanitizer import fill_embed

View File

@ -52,7 +52,7 @@ from litecord.common.messages import (
from litecord.embed.sanitizer import fill_embed, fetch_mediaproxy_img from litecord.embed.sanitizer import fill_embed, fetch_mediaproxy_img
from litecord.embed.messages import process_url_embed, is_media_url from litecord.embed.messages import process_url_embed, is_media_url
from litecord.embed.schemas import EmbedURL from litecord.embed.schemas import EmbedURL
from litecord.utils import pg_set_json from litecord.json import pg_set_json
from litecord.enums import MessageType from litecord.enums import MessageType
from litecord.images import STATIC_IMAGE_MIMES from litecord.images import STATIC_IMAGE_MIMES

View File

@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import json import json
import earl import earl
from litecord.utils import LitecordJSONEncoder from litecord.json import LitecordJSONEncoder
def encode_json(payload) -> str: def encode_json(payload) -> str:

69
litecord/json.py Normal file
View File

@ -0,0 +1,69 @@
"""
Litecord
Copyright (C) 2018-2021 Luna Mendes and Litecord Contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import json
from typing import Any
from decimal import Decimal
from uuid import UUID
from dataclasses import asdict, is_dataclass
import quart.json.provider
class LitecordJSONEncoder(json.JSONEncoder):
"""Custom JSON encoder for Litecord. Useful for json.dumps"""
def default(self, value: Any):
if isinstance(value, (Decimal, UUID)):
return str(value)
if is_dataclass(value):
return asdict(value)
if hasattr(value, "to_json"):
return value.to_json
return super().default(self, value)
class LitecordJSONProvider(quart.json.provider.DefaultJSONProvider):
"""Custom JSON provider for Quart."""
def __init__(self, *args, **kwargs):
self.encoder = LitecordJSONEncoder(**kwargs)
def default(self, value: Any):
self.encoder.default(value)
async def pg_set_json(con):
"""Set JSON and JSONB codecs for an asyncpg connection."""
await con.set_type_codec(
"json",
encoder=lambda v: json.dumps(v, cls=LitecordJSONEncoder),
decoder=json.loads,
schema="pg_catalog",
)
await con.set_type_codec(
"jsonb",
encoder=lambda v: json.dumps(v, cls=LitecordJSONEncoder),
decoder=json.loads,
schema="pg_catalog",
)

View File

@ -33,7 +33,7 @@ from litecord.blueprints.channel.reactions import (
from litecord.blueprints.user.billing import PLAN_ID_TO_TYPE from litecord.blueprints.user.billing import PLAN_ID_TO_TYPE
from litecord.types import timestamp_ from litecord.types import timestamp_
from litecord.utils import pg_set_json from litecord.json import pg_set_json
log = Logger(__name__) log = Logger(__name__)

View File

@ -18,14 +18,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
import asyncio import asyncio
import json
import secrets import secrets
import datetime import datetime
import re import re
from typing import Any, Iterable, Optional, Sequence, List, Dict, Union from typing import Any, Iterable, Optional, Sequence, List, Dict, Union
from logbook import Logger from logbook import Logger
from quart.json import JSONEncoder
from quart import current_app as app from quart import current_app as app
from litecord.common.messages import message_view from litecord.common.messages import message_view
@ -156,35 +154,6 @@ def mmh3(inp_str: str, seed: int = 0):
return _u(h1) >> 0 return _u(h1) >> 0
class LitecordJSONEncoder(JSONEncoder):
"""Custom JSON encoder for Litecord."""
def default(self, value: Any):
"""By default, this will try to get the to_json attribute of a given
value being JSON encoded."""
try:
return value.to_json
except AttributeError:
return super().default(value)
async def pg_set_json(con):
"""Set JSON and JSONB codecs for an asyncpg connection."""
await con.set_type_codec(
"json",
encoder=lambda v: json.dumps(v, cls=LitecordJSONEncoder),
decoder=json.loads,
schema="pg_catalog",
)
await con.set_type_codec(
"jsonb",
encoder=lambda v: json.dumps(v, cls=LitecordJSONEncoder),
decoder=json.loads,
schema="pg_catalog",
)
def yield_chunks(input_list: Sequence[Any], chunk_size: int): def yield_chunks(input_list: Sequence[Any], chunk_size: int):
"""Yield successive n-sized chunks from l. """Yield successive n-sized chunks from l.

View File

@ -7,19 +7,19 @@ license = "GPLv3-only"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.9" python = "^3.9"
bcrypt = "^3.2.0" bcrypt = "^3.2.2"
itsdangerous = "^1.1.0" itsdangerous = "^2.1.2"
asyncpg = "^0.24.0" asyncpg = "^0.26.0"
websockets = "^10.0" websockets = "^10.3"
Earl-ETF = "^2.1.2" Earl-ETF = "^2.1.2"
logbook = "^1.5.3" logbook = "^1.5.3"
Cerberus = "^1.3.4" Cerberus = "^1.3.4"
quart = {git = "https://gitlab.com/pgjones/quart", rev = "c1ac142c6c51709765045f830b242950099b2295"} quart = "^0.18.0"
pillow = "^8.3.2" pillow = "^9.2.0"
aiohttp = "^3.7.4" aiohttp = "^3.8.1"
zstandard = "^0.15.2" zstandard = "^0.18.0"
winter = {git = "https://gitlab.com/elixire/winter"} winter = {git = "https://gitlab.com/elixire/winter"}
wsproto = "^1.0.0" wsproto = "^1.1.0"

4
run.py
View File

@ -105,7 +105,7 @@ from litecord.pubsub.lazy_guild import LazyGuildManager
from litecord.gateway.gateway import websocket_handler from litecord.gateway.gateway import websocket_handler
from litecord.utils import LitecordJSONEncoder from litecord.json import LitecordJSONProvider
# == HACKY PATCH == # == HACKY PATCH ==
# this MUST be removed once Hypercorn gets py3.10 support. # this MUST be removed once Hypercorn gets py3.10 support.
@ -135,7 +135,7 @@ def make_app():
logging.getLogger("websockets").setLevel(logbook.INFO) logging.getLogger("websockets").setLevel(logbook.INFO)
# use our custom json encoder for custom data types # use our custom json encoder for custom data types
app.json_encoder = LitecordJSONEncoder app.json_provider_class = LitecordJSONProvider
return app return app

16
tox.ini
View File

@ -1,22 +1,22 @@
[tox] [tox]
envlist = py3.9 envlist = py3.10
isolated_build = true isolated_build = true
[testenv] [testenv]
ignore_errors = true ignore_errors = true
deps = deps =
pytest==6.2.5 pytest==7.1.2
pytest-asyncio==0.15.1 pytest-asyncio==0.19.0
pytest-cov==2.12.1 pytest-cov==3.0.0
flake8==3.9.2 flake8==5.0.4
black==21.6b0 black==22.6.0
mypy==0.910 mypy==0.971
pytest-instafail==0.4.2 pytest-instafail==0.4.2
commands = commands =
python3 ./manage.py migrate python3 ./manage.py migrate
black --check litecord run.py tests manage black --check litecord run.py tests manage
flake8 litecord run.py tests manage flake8 litecord run.py tests manage
pytest {posargs:tests} pytest --asyncio-mode=auto {posargs:tests}
[flake8] [flake8]
max-line-length = 88 max-line-length = 88