Skip to content

Commit

Permalink
update python version to 3.10;
Browse files Browse the repository at this point in the history
update dependencies;
replace Union's with "|" and Optional's with "| None";
remove python 3.9 from github actions
  • Loading branch information
RuslanUC committed Jul 27, 2024
1 parent 9805f9f commit bc515b5
Show file tree
Hide file tree
Showing 54 changed files with 852 additions and 907 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
timeout-minutes: 15
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12"]
database: ["mariadb", "sqlite", "mysql"]

steps:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Unofficial discord backend implementation in python.

# Setup
**Requirements:**
- Python 3.9+
- Python 3.10+
- Poetry (Optional)

**Setup**:
Expand Down
4 changes: 2 additions & 2 deletions STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,5 @@
- [x] Create, edit, delete
- [ ] Commands:
- [x] Slash commands
- [ ] User commands (?)
- [ ] Message commands (?)
- [ ] User commands (?, I forgot)
- [ ] Message commands (?, I forgot)
1,079 changes: 537 additions & 542 deletions poetry.lock

Large diffs are not rendered by default.

29 changes: 14 additions & 15 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "yepcord-server"
version = "1.0.0b4"
version = "1.0.0b5"
description = "YEPCord - Free open source selfhostable fully discord-compatible chat"
authors = ["RuslanUC <dev_ruslan_uc@protonmail.com>"]
license = "AGPL-3.0"
Expand All @@ -22,7 +22,6 @@ classifiers = [
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand All @@ -36,31 +35,31 @@ classifiers = [
yepcord = "yepcord.cli:main"

[tool.poetry.dependencies]
python = "^3.9"
quart = "0.19.5"
aiofiles = "23.2.1"
python = "^3.10"
quart = "0.19.6"
aiofiles = "24.1.0"
websockets = "12.0"
uvicorn = "0.29.0"
uvicorn = "0.30.3"
aiohttp = "3.9.5"
python-magic = "0.4.27"
pillow = "10.3.0"
pillow = "10.4.0"
protobuf = "4.25.3"
python-dateutil = "2.9.0.post0"
cryptography = "42.0.7"
emoji = "2.11.1"
cryptography = "43.0.0"
emoji = "2.12.1"
six = "1.16.0"
bcrypt = "4.1.3"
quart-schema = "0.19.1"
pydantic = "2.7.1"
bcrypt = "4.2.0"
quart-schema = "0.20.0"
pydantic = "2.8.2"
werkzeug = "3.0.3"
aioftp = "0.22.3"
orjson = "3.10.3"
orjson = "3.10.6"
mailers = {version = "3.0.5", extras = ["smtp"]}
redis = ">=4.6.0"
click = "8.1.7"
maxminddb = "2.6.1"
maxminddb = "2.6.2"
wget = "3.2"
tortoise-orm = {extras = ["aiosqlite", "asyncmy", "accel"], version = "^0.20.0"}
tortoise-orm = {extras = ["aiosqlite", "asyncmy", "accel"], version = "^0.21.5"}
uvloop = "0.19.0"
async-timeout = "^4.0.3"
aerich = "^0.7.2"
Expand Down
17 changes: 8 additions & 9 deletions tests/api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from contextlib import asynccontextmanager
from datetime import datetime, timedelta
from hashlib import sha256
from typing import Optional, Union

from quart.typing import TestWebsocketConnectionProtocol

Expand All @@ -17,7 +16,7 @@
TestClientType = _app.test_client_class


async def create_user(app: TestClientType, email: str, password: str, username: str, *, exp_code: int=200) -> Optional[str]:
async def create_user(app: TestClientType, email: str, password: str, username: str, *, exp_code: int=200) -> str | None:
response = await app.post('/api/v9/auth/register', json={
"username": username,
"email": email,
Expand Down Expand Up @@ -254,9 +253,9 @@ class RemoteAuthClient:
def __init__(self, on_fingerprint=None, on_userdata=None, on_token=None, on_cancel=None, on_pending_login=None):
from cryptography.hazmat.primitives.asymmetric import rsa

self.privKey: Optional[rsa.RSAPrivateKey] = None
self.pubKey: Optional[rsa.RSAPublicKey] = None
self.pubKeyS: Optional[str] = None
self.privKey: rsa.RSAPrivateKey | None = None
self.pubKey: rsa.RSAPublicKey | None = None
self.pubKeyS: str | None = None

self.heartbeatTask = None

Expand All @@ -266,7 +265,7 @@ def __init__(self, on_fingerprint=None, on_userdata=None, on_token=None, on_canc
self.on_cancel = on_cancel
self.on_pending_login = on_pending_login

self.results: dict[str, Union[Optional[str], bool]] = {
self.results: dict[str, str | None | bool] = {
"fingerprint": None,
"userdata": None,
"token": None,
Expand Down Expand Up @@ -375,7 +374,7 @@ async def gateway_cm(gw_app):

class GatewayClient:
class EventListener:
def __init__(self, event: GatewayOp, dispatch_event: Optional[str], future: asyncio.Future, raw: bool):
def __init__(self, event: GatewayOp, dispatch_event: str | None, future: asyncio.Future, raw: bool):
self.event = event
self.dispatch_event = dispatch_event
self.future = future
Expand All @@ -387,8 +386,8 @@ def __init__(self, token: str):

self.running = True
self.loop = asyncio.get_event_loop()
self.heartbeatTask: Optional[asyncio.Task] = None
self.mainTask: Optional[asyncio.Task] = None
self.heartbeatTask: asyncio.Task | None = None
self.mainTask: asyncio.Task | None = None

self.handlers = {
GatewayOp.HELLO: self.handle_hello
Expand Down
5 changes: 2 additions & 3 deletions yepcord/gateway/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import warnings
from json import dumps as jdumps
from typing import Optional, Union

from quart import Websocket
from redis.asyncio import Redis
Expand All @@ -47,7 +46,7 @@ def __init__(self, ws, gateway: Gateway):
self.z = getattr(ws, "zlib", None)
self.id = self.user_id = None
self.is_bot = False
self.cached_presence: Optional[Presence] = None
self.cached_presence: Presence | None = None

@property
def connected(self):
Expand Down Expand Up @@ -295,7 +294,7 @@ def __init__(self, core: Core):
self.presences = Presences(self)
self.ev = GatewayEvents(self)

self.redis: Union[Redis, FakeRedis, None] = None
self.redis: Redis | FakeRedis | None = None

async def init(self):
await self.broker.start()
Expand Down
4 changes: 2 additions & 2 deletions yepcord/gateway/presences.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from __future__ import annotations

from json import loads, dumps
from typing import Optional, TYPE_CHECKING
from typing import TYPE_CHECKING

from ..yepcord.config import Config

Expand Down Expand Up @@ -78,7 +78,7 @@ async def set_or_refresh(self, user_id: int, presence: Presence = None, overwrit
await pipe.expire(f"presence_{user_id}", int(Config.GATEWAY_KEEP_ALIVE_DELAY * 1.25))
await pipe.execute()

async def get(self, user_id: int) -> Optional[Presence]:
async def get(self, user_id: int) -> Presence | None:
if (presence := await self._gateway.redis.get(f"presence_{user_id}")) is None:
return
return Presence(user_id, **loads(presence))
5 changes: 2 additions & 3 deletions yepcord/gateway/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from enum import Enum, auto
from typing import Optional

from redis.asyncio import Redis

Expand All @@ -38,7 +37,7 @@ class TokenType(Enum):
BOT = auto()


def get_token_type(token: str) -> Optional[TokenType]:
def get_token_type(token: str) -> TokenType | None:
if not token:
return

Expand All @@ -55,7 +54,7 @@ def get_token_type(token: str) -> Optional[TokenType]:
return TokenType.USER if len(token) == 3 else TokenType.BOT


async def init_redis_pool() -> Optional[Redis]:
async def init_redis_pool() -> Redis | None:
if not Config.REDIS_URL:
return
return Redis.from_url(
Expand Down
5 changes: 2 additions & 3 deletions yepcord/remote_auth/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from hashlib import sha256
from os import urandom
from time import time
from typing import Optional

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric.padding import OAEP, MGF1
Expand All @@ -47,8 +46,8 @@ def __init__(self, ws: Websocket, version: int, gateway):
self.version = version
self.gw = gateway

self.pubkey: Optional[RSAPublicKey] = None
self.fingerprint: Optional[str] = None
self.pubkey: RSAPublicKey | None = None
self.fingerprint: str | None = None

def encrypt(self, data: bytes):
return self.pubkey.encrypt(data, OAEP(mgf=MGF1(algorithm=SHA256()), algorithm=SHA256(), label=None))
Expand Down
29 changes: 14 additions & 15 deletions yepcord/rest_api/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"""

from time import time
from typing import Union, Optional, Callable, Awaitable, TypeVar
from typing import Callable, Awaitable, TypeVar

from fast_depends import Depends
from quart import request
Expand All @@ -31,12 +31,12 @@
from yepcord.yepcord.snowflake import Snowflake
from yepcord.yepcord.utils import b64decode

SessionsType = Union[Session, Authorization, Bot]
SessionsType = Session | Authorization | Bot
T = TypeVar("T")
P = ParamSpec("P")


def depRaise(func: Callable[P, Awaitable[Optional[T]]], status_code: int, error: dict) -> Callable[P, Awaitable[T]]:
def depRaise(func: Callable[P, Awaitable[T | None]], status_code: int, error: dict) -> Callable[P, Awaitable[T]]:
async def wrapper(res=Depends(func)):
if res is None:
raise InvalidDataErr(status_code, error)
Expand All @@ -45,7 +45,7 @@ async def wrapper(res=Depends(func)):
return wrapper


async def depSessionO() -> Optional[SessionsType]:
async def depSessionO() -> SessionsType | None:
if session := await getSessionFromToken(request.headers.get("Authorization", "")):
return session

Expand All @@ -57,7 +57,7 @@ async def _depUser_with_user(session: SessionsType = Depends(depSession)) -> Use
return session.user


async def _depUser_without_user(session: Optional[SessionsType] = Depends(depSessionO)) -> Optional[User]:
async def _depUser_without_user(session: SessionsType | None = Depends(depSessionO)) -> User | None:
if session:
return session.user

Expand All @@ -66,7 +66,7 @@ def depUser(allow_without_user: bool = False):
return _depUser_without_user if allow_without_user else _depUser_with_user


async def depChannelO(channel_id: Optional[int] = None, user: User = Depends(depUser())) -> Optional[Channel]:
async def depChannelO(channel_id: int | None = None, user: User = Depends(depUser())) -> Channel | None:
if (channel := await getCore().getChannel(channel_id)) is None:
return
if not await getCore().getUserByChannel(channel, user.id):
Expand All @@ -75,8 +75,7 @@ async def depChannelO(channel_id: Optional[int] = None, user: User = Depends(dep
return channel


async def depChannelONoAuth(channel_id: Optional[int] = None, user: Optional[User] = Depends(depUser(True))) \
-> Optional[Channel]:
async def depChannelONoAuth(channel_id: int | None = None, user: User | None = Depends(depUser(True))) -> Channel | None:
if user is None:
return
return await depChannelO(channel_id, user)
Expand All @@ -85,7 +84,7 @@ async def depChannelONoAuth(channel_id: Optional[int] = None, user: Optional[Use
depChannel = depRaise(depChannelO, 404, Errors.make(10003))


async def depWebhookO(webhook: Optional[int] = None, token: Optional[str] = None) -> Optional[Webhook]:
async def depWebhookO(webhook: int | None = None, token: str | None = None) -> Webhook | None:
if webhook is None or token is None:
return
webhook = await Webhook.get_or_none(id=webhook).select_related("channel")
Expand All @@ -99,10 +98,10 @@ async def depWebhookO(webhook: Optional[int] = None, token: Optional[str] = None

async def depMessageO(
message: int,
channel: Optional[Channel] = Depends(depChannelONoAuth),
webhook: Optional[Webhook] = Depends(depWebhookO),
user: Optional[User] = Depends(depUser(True)),
) -> Optional[Message]:
channel: Channel | None = Depends(depChannelONoAuth),
webhook: Webhook | None = Depends(depWebhookO),
user: User | None = Depends(depUser(True)),
) -> Message | None:
if webhook:
message = await Message.get_or_none(id=message, webhook_id=webhook.id).select_related(*Message.DEFAULT_RELATED)
elif channel is not None and user is not None:
Expand All @@ -119,7 +118,7 @@ async def depMessageO(
depMessage = depRaise(depMessageO, 404, Errors.make(10008))


async def depInvite(invite: Optional[str] = None) -> Invite:
async def depInvite(invite: str | None = None) -> Invite:
try:
invite_id = int.from_bytes(b64decode(invite), "big")
if not (inv := await getCore().getInvite(invite_id)):
Expand All @@ -132,7 +131,7 @@ async def depInvite(invite: Optional[str] = None) -> Invite:
return invite


async def depGuildO(guild: Optional[int] = None, user: User = Depends(depUser())) -> Optional[Guild]:
async def depGuildO(guild: int | None = None, user: User = Depends(depUser())) -> Guild | None:
if (guild := await getCore().getGuild(guild)) is None:
return
if not await GuildMember.filter(guild=guild, user=user).exists():
Expand Down
Loading

0 comments on commit bc515b5

Please sign in to comment.