Merge pull request #53 from revanced/dev

New Feature Pack
This commit is contained in:
Alexandre Teles 2022-12-26 19:41:41 -03:00 committed by GitHub
commit 6060dd744a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 801 additions and 614 deletions

View File

@ -1,4 +1,4 @@
ARG VARIANT="3.10-bullseye"
ARG VARIANT="3.11-bullseye"
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}
ARG NODE_VERSION="none"

View File

@ -9,7 +9,7 @@
// Update 'VARIANT' to pick a Python version: 3, 3.10, 3.9, 3.8, 3.7, 3.6
// Append -bullseye or -buster to pin to an OS version.
// Use -bullseye variants on local on arm64/Apple Silicon.
"VARIANT": "3.10-bullseye",
"VARIANT": "3.11-bullseye",
// Options
"NODE_VERSION": "lts/*"
}

View File

@ -35,7 +35,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10.7'
python-version: '3.11.0'
- name: Install dependencies
run: |
python -m pip install --upgrade pip

View File

@ -12,7 +12,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: 3.10.8
python-version: 3.11.0
architecture: x64
- name: Checkout
uses: actions/checkout@v3

View File

@ -1,4 +1,4 @@
FROM python:3.10-slim
FROM python:3.11-slim
ARG GITHUB_TOKEN
ENV GITHUB_TOKEN $GITHUB_TOKEN

View File

@ -8,7 +8,7 @@ This is a simple API that returns the latest ReVanced releases, patches and cont
## Usage
The API is available at [https://releases.rvcd.win/](https://releases.rvcd.win/).
The API is available at [https://releases.revanced.app/](https://releases.revanced.app/).
You can deploy your own instance by cloning this repository, editing the `docker-compose.yml` file to include your GitHub token and running `docker-compose up` or `docker-compose up --build` if you want to build the image locally instead of pulling from GHCR. Optionally you can run the application without Docker by running `poetry install` and `poetry run ./run.sh`. In this case, you'll also need a redis server and setup the following environment variables on your system.
@ -27,10 +27,10 @@ If you don't have a Sentry instance, we recommend using [GlitchTip](https://glit
### API Endpoints
* [tools](https://releases.rvcd.win/tools) - Returns the latest version of all ReVanced tools and Vanced MicroG
* [patches](https://releases.rvcd.win/patches) - Returns the latest version of all ReVanced patches
* [contributors](https://releases.rvcd.win/contributors) - Returns contributors for all ReVanced projects
* [announcement](https://releases.rvcd.win/announcement) - Returns the latest announcement for the ReVanced projects
* [tools](https://releases.revanced.app/tools) - Returns the latest version of all ReVanced tools and Vanced MicroG
* [patches](https://releases.revanced.app/patches) - Returns the latest version of all ReVanced patches
* [contributors](https://releases.revanced.app/contributors) - Returns contributors for all ReVanced projects
* [announcement](https://releases.revanced.app/announcement) - Returns the latest announcement for the ReVanced projects
## Clients

View File

@ -1,4 +1,4 @@
import toml
from redis import asyncio as aioredis
import app.utils.Logger as Logger
@ -6,7 +6,9 @@ from app.utils.Generators import Generators
from app.models.AnnouncementModels import AnnouncementCreateModel
from app.utils.RedisConnector import RedisConnector
config: dict = toml.load("config.toml")
from app.dependencies import load_config
config: dict = load_config()
class Announcements:
"""Implements the announcements class for the ReVanced API"""

View File

@ -1,11 +1,13 @@
from datetime import timedelta
import os
import toml
from datetime import timedelta
from pydantic import BaseModel
from fastapi_paseto_auth import AuthPASETO
config: dict = toml.load("config.toml")
from app.dependencies import load_config
config: dict = load_config()
class PasetoSettings(BaseModel):
authpaseto_secret_key: str = os.environ['SECRET_KEY']

View File

@ -1,5 +1,5 @@
from time import sleep
import toml
import orjson
from typing import Optional
import argon2
@ -12,7 +12,9 @@ from app.utils.Generators import Generators
from app.models.ClientModels import ClientModel
from app.utils.RedisConnector import RedisConnector
config: dict = toml.load("config.toml")
from app.dependencies import load_config
config: dict = load_config()
class Clients:

View File

@ -1,10 +1,12 @@
import toml
from redis import asyncio as aioredis
import app.utils.Logger as Logger
from app.models.MirrorModels import MirrorModel, MirrorStoreModel
from app.utils.RedisConnector import RedisConnector
config: dict = toml.load("config.toml")
from app.dependencies import load_config
config: dict = load_config()
class Mirrors:
"""Implements the Mirror class for the ReVanced API"""

View File

@ -1,11 +1,11 @@
from toolz.dicttoolz import keyfilter
import asyncio
import uvloop
import orjson
from base64 import b64decode
from toolz.dicttoolz import keyfilter
import asyncstdlib.builtins as a
from app.utils.HTTPXClient import HTTPXClient
class Releases:
"""Implements the methods required to get the latest releases and patches from revanced repositories."""
@ -15,13 +15,14 @@ class Releases:
httpx_client = HTTPXClient.create()
async def __get_release(self, repository: str) -> list:
# Get assets from latest release in a given repository.
#
# Args:
# repository (str): Github's standard username/repository notation
#
# Returns:
# dict: dictionary of filename and download url
"""Get assets from latest release in a given repository.
Args:
repository (str): Github's standard username/repository notation
Returns:
dict: dictionary of filename and download url
"""
assets: list = []
response = await self.httpx_client.get(f"https://api.github.com/repos/{repository}/releases/latest")
@ -32,24 +33,28 @@ class Releases:
release_tarball: str = response.json()['tarball_url']
release_timestamp: str = response.json()['published_at']
if release_assets:
for asset in release_assets:
assets.append({ 'repository': repository,
async def get_asset_data(asset: dict) -> dict:
return {'repository': repository,
'version': release_version,
'timestamp': asset['updated_at'],
'name': asset['name'],
'size': asset['size'],
'browser_download_url': asset['browser_download_url'],
'content_type': asset['content_type']
})
}
if release_assets:
assets = await asyncio.gather(*[get_asset_data(asset) for asset in release_assets])
else:
assets.append({ 'repository': repository,
no_release_assets_data: dict = {'repository': repository,
'version': release_version,
'timestamp': release_timestamp,
'name': f"{repository.split('/')[1]}-{release_version}.tar.gz",
'browser_download_url': release_tarball,
'content_type': 'application/gzip'
})
}
assets.append(no_release_assets_data)
return assets
async def get_latest_releases(self, repositories: list) -> dict:
@ -67,21 +72,20 @@ class Releases:
results: list = await asyncio.gather(*[self.__get_release(repository) for repository in repositories])
for result in results:
for asset in result:
releases['tools'].append(asset)
releases['tools'] = [asset for result in results for asset in result]
return releases
async def __get_patches_json(self) -> dict:
# Get revanced-patches repository's README.md.
#
# Returns:
# dict: JSON content
#
"""Get revanced-patches repository's README.md.
Returns:
dict: JSON content
"""
response = await self.httpx_client.get(f"https://api.github.com/repos/revanced/revanced-patches/contents/patches.json")
content = orjson.loads(b64decode(response.json()['content']).decode('utf-8'))
content = orjson.loads(
b64decode(response.json()['content']).decode('utf-8'))
return content
@ -91,26 +95,29 @@ class Releases:
Returns:
dict: Patches available for a given app
"""
patches: dict = await self.__get_patches_json()
return patches
async def __get_contributors(self, repository: str) -> list:
# Get contributors from a given repository.
#
# Args:
# repository (str): Github's standard username/repository notation
#
# Returns:
# list: a list of dictionaries containing the repository's contributors
"""Get contributors from a given repository.
keep: set = {'login', 'avatar_url', 'html_url'}
Args:
repository (str): Github's standard username/repository notation
Returns:
list: a list of dictionaries containing the repository's contributors
"""
keep: set = {'login', 'avatar_url', 'html_url', 'contributions'}
response = await self.httpx_client.get(f"https://api.github.com/repos/{repository}/contributors")
# Looping over each contributor, filtering each contributor so that
# keyfilter() returns a dictionary with only the key-value pairs that are in the "keep" set.
contributors: list = [keyfilter(lambda k: k in keep, contributor) for contributor in response.json()]
return contributors
async def get_contributors(self, repositories: list) -> dict:
@ -128,12 +135,13 @@ class Releases:
contributors = {}
contributors['repositories'] = []
revanced_repositories = [repository for repository in repositories if 'revanced' in repository]
revanced_repositories = [
repository for repository in repositories if 'revanced' in repository]
results: list[dict] = await asyncio.gather(*[self.__get_contributors(repository) for repository in revanced_repositories])
for key, value in zip(revanced_repositories, results):
data = { 'name': key, 'contributors': value }
async for key, value in a.zip(revanced_repositories, results):
data = {'name': key, 'contributors': value}
contributors['repositories'].append(data)
return contributors
@ -165,25 +173,35 @@ class Releases:
f"https://api.github.com/repos/{org}/{repository}/releases?per_page=2"
)
if _releases.status_code == 200:
releases = _releases.json()
if any(releases):
since = releases[1]['created_at']
until = releases[0]['created_at']
else:
raise ValueError("No releases found")
_response = await self.httpx_client.get(
f"https://api.github.com/repos/{org}/{repository}/commits?path={path}&since={since}&until={until}"
)
if _response.status_code == 200:
response = _response.json()
for commit in response:
data: dict[str, str] = {}
data["sha"] = commit["sha"]
data["author"] = commit["commit"]["author"]["name"]
data["message"] = commit["commit"]["message"]
data["html_url"] = commit["html_url"]
async def get_commit_data(commit: dict) -> dict:
return {'sha': commit['sha'],
'author': commit['commit']['author']['name'],
'date': commit['commit']['author']['date'],
'message': commit['commit']['message'],
'url': commit['html_url']
}
data: list = await asyncio.gather(*[get_commit_data(commit) for commit in response])
payload['commits'].append(data)
else:
raise ValueError("Error retrieving commits")
else:
raise ValueError("Invalid organization.")
return payload
else:
raise Exception("Invalid organization.")

View File

@ -0,0 +1,18 @@
from app.dependencies import load_config
config: dict = load_config()
class Socials:
"""Implements the code infrastructure for the socials page."""
async def get_socials(self) -> dict:
"""Get socials from config.toml.
Returns:
dict: A dictionary containing socials from config.toml
"""
socials: dict = config['socials']
return socials

View File

@ -1,4 +1,4 @@
import toml
import tomllib as toml
def load_config() -> dict:
"""Loads the config.toml file.
@ -6,4 +6,7 @@ def load_config() -> dict:
Returns:
dict: the config.toml file as a dict
"""
return toml.load("config.toml")
with open('config.toml', 'rb') as config_file:
return toml.load(config_file)

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
import os
import toml
import binascii
from redis import Redis
@ -34,15 +34,18 @@ from app.routers import tools
from app.routers import clients
from app.routers import patches
from app.routers import mirrors
from app.routers import socials
from app.routers import changelogs
from app.routers import contributors
from app.routers import announcement
from app.dependencies import load_config
"""Get latest ReVanced releases from GitHub API."""
# Load config
config: dict = toml.load("config.toml")
config: dict = load_config()
# Create FastAPI instance
@ -74,6 +77,7 @@ app.include_router(tools.router)
app.include_router(patches.router)
app.include_router(contributors.router)
app.include_router(changelogs.router)
app.include_router(socials.router)
app.include_router(auth.router)
app.include_router(clients.router)
app.include_router(announcement.router)

View File

@ -53,6 +53,7 @@ class ContributorFields(BaseModel):
login: str
avatar_url: str
html_url: str
contributions: int
class ContributorsResponseFields(BaseModel):
"""Implements the fields for each repository in the /contributors endpoint

View File

@ -107,3 +107,12 @@ class RevokedTokenResponse(BaseModel):
"""
revoked: bool
class SocialsResponseModel(BaseModel):
"""Implements the JSON response model for the /socials endpoint.
Args:
BaseModel (pydantic.BaseModel): BaseModel from pydantic
"""
__root__: dict[ str, str ]

24
app/routers/socials.py Normal file
View File

@ -0,0 +1,24 @@
from fastapi_cache.decorator import cache
from fastapi import APIRouter, Request, Response
import app.models.ResponseModels as ResponseModels
from app.controllers.Socials import Socials
from app.dependencies import load_config
router = APIRouter()
socials = Socials()
config: dict = load_config()
@router.get('/socials', response_model=ResponseModels.SocialsResponseModel, tags=['ReVanced Socials'])
@cache(config['cache']['expire'])
async def get_socials(request: Request, response: Response) -> dict:
"""Get ReVanced social links.
Returns:
json: dictionary of ReVanced social links
"""
return await socials.get_socials()

View File

@ -1,10 +1,12 @@
import os
import toml
from redis import asyncio as aioredis
from app.dependencies import load_config
# Load config
config: dict = toml.load("config.toml")
config: dict = load_config()
# Redis connection parameters

View File

@ -1,5 +1,4 @@
[docs]
title = "ReVanced Releases API"
description = """
## The official JSON API for ReVanced Releases 🚀
@ -22,10 +21,9 @@ description = """
3. Abuse of the API will result in IP blocks
"""
version = "1.0.0"
version = "1.1.0"
[license]
name = "AGPL-3.0"
url = "https://www.gnu.org/licenses/agpl-3.0.en.html"
@ -57,6 +55,13 @@ database = 5
access_token_expires = false
[app]
repositories = ["TeamVanced/VancedMicroG", "revanced/revanced-patcher", "revanced/revanced-patches", "revanced/revanced-integrations", "revanced/revanced-manager", "revanced/revanced-cli", "revanced/revanced-website", "revanced/revanced-releases-api"]
repositories = ["TeamVanced/VancedMicroG", "revanced/revanced-cli", "revanced/revanced-patcher", "revanced/revanced-patches", "revanced/revanced-integrations", "revanced/revanced-manager", "revanced/revanced-website", "revanced/revanced-releases-api"]
[socials]
website = "https://revanced.app"
github = "https://github.com/revanced"
twitter = "https://twitter.com/revancedapp"
discord = "https://revanced.app/discord"
reddit = "https://www.reddit.com/r/revancedapp"
telegram = "https://t.me/app_revanced"
youtube = "https://www.youtube.com/@ReVanced"

View File

@ -3,7 +3,7 @@ version: "3.8"
services:
redis:
container_name: revanced-releases-api-redis
image: redis-stack-server:latest
image: redis/redis-stack-server:latest
environment:
- REDIS_ARGS=--save 60 1 --appendonly yes
volumes:
@ -13,7 +13,7 @@ services:
restart: always
revanced-releases-api:
container_name: revanced-releases-api
image: ghcr.io/alexandreteles/revanced-releases-api:latest
image: ghcr.io/revanced/revanced-releases-api:latest
environment:
- GITHUB_TOKEN=YOUR_GITHUB_TOKEN
- REDIS_URL=revanced-releases-api-redis

View File

@ -4,7 +4,7 @@ version: "3.8"
services:
redis:
container_name: revanced-releases-api-redis
image: redis-stack-server:latest
image: redis/redis-stack-server:latest
environment:
- REDIS_ARGS=--save 60 1 --appendonly yes
volumes:
@ -14,7 +14,7 @@ services:
restart: always
revanced-releases-api:
container_name: revanced-releases-api
image: ghcr.io/alexandreteles/revanced-releases-api:latest
image: ghcr.io/revanced/revanced-releases-api:latest
environment:
- GITHUB_TOKEN=YOUR_GITHUB_TOKEN
- REDIS_URL=revanced-releases-api-redis

View File

@ -1,5 +1,5 @@
[mypy]
python_version = 3.10
python_version = 3.11
pretty = true
follow_imports = normal
namespace_packages = true
@ -76,3 +76,7 @@ ignore_missing_imports = True
[mypy-asgiref.*]
# No stubs available
ignore_missing_imports = True
[mypy-tomllib.*]
# No stubs available
ignore_missing_imports = True

912
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
[tool.poetry]
name = "revanced-releases-api"
version = "0.1.0"
version = "1.1.0"
description = "JSON API for ReVanced Releases"
authors = ["Alexandre Teles <alexandre.teles@ufba.br>"]
license = "AGPLv3"
[tool.poetry.dependencies]
python = "^3.10"
python = "^3.11"
fastapi = ">=0.85.0"
httpx = {version = ">=0.23.0", extras = ["http2"]}
httpx-cache = ">=0.6.0"
@ -18,7 +18,7 @@ redis = ">=4.3.4"
loguru = ">=0.6.0"
sentry-sdk = ">=1.9.8"
argon2-cffi = ">=21.3.0"
hypercorn = {extras = ["uvloop"], version = ">=0.14.3"}
uvloop = ">=0.17.0"
cytoolz = ">=0.12.0"
fastapi-paseto-auth = "^0.6.0"
ujson = ">=5.5.0"
@ -26,6 +26,7 @@ hiredis = ">=2.0.0"
aiofiles = ">=22.1.0"
uvicorn = ">=0.18.3"
gunicorn = ">=20.1.0"
asyncstdlib = ">=3.10.5"
[tool.poetry.dev-dependencies]
mypy = ">=0.971"

View File

@ -1,63 +1,61 @@
aiofiles==22.1.0 ; python_version >= "3.10" and python_version < "4.0"
aiorwlock==1.3.0 ; python_version >= "3.10" and python_version < "4.0"
anyio==3.6.2 ; python_version >= "3.10" and python_version < "4.0"
argon2-cffi-bindings==21.2.0 ; python_version >= "3.10" and python_version < "4.0"
argon2-cffi==21.3.0 ; python_version >= "3.10" and python_version < "4.0"
async-timeout==4.0.2 ; python_version >= "3.10" and python_version < "4.0"
attrs==21.4.0 ; python_version >= "3.10" and python_version < "4.0"
certifi==2022.9.24 ; python_version >= "3.10" and python_version < "4.0"
cffi==1.15.1 ; python_version >= "3.10" and python_version < "4.0"
click==8.1.3 ; python_version >= "3.10" and python_version < "4.0"
colorama==0.4.6 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "win32" or python_version >= "3.10" and python_version < "4.0" and platform_system == "Windows"
cryptography==37.0.4 ; python_version >= "3.10" and python_version < "4.0"
cytoolz==0.12.0 ; python_version >= "3.10" and python_version < "4.0"
fastapi-cache2==0.1.9 ; python_version >= "3.10" and python_version < "4.0"
fastapi-paseto-auth==0.6.0 ; python_version >= "3.10" and python_version < "4.0"
fastapi==0.85.0 ; python_version >= "3.10" and python_version < "4.0"
fasteners==0.17.3 ; python_version >= "3.10" and python_version < "4.0"
gunicorn==20.1.0 ; python_version >= "3.10" and python_version < "4.0"
h11==0.14.0 ; python_version >= "3.10" and python_version < "4.0"
h2==4.1.0 ; python_version >= "3.10" and python_version < "4.0"
hiredis==2.0.0 ; python_version >= "3.10" and python_version < "4.0"
hpack==4.0.0 ; python_version >= "3.10" and python_version < "4.0"
httpcore==0.16.1 ; python_version >= "3.10" and python_version < "4.0"
httpx-cache==0.6.1 ; python_version >= "3.10" and python_version < "4.0"
httpx==0.23.1 ; python_version >= "3.10" and python_version < "4.0"
httpx[http2]==0.23.1 ; python_version >= "3.10" and python_version < "4.0"
hypercorn[uvloop]==0.14.3 ; python_version >= "3.10" and python_version < "4.0"
hyperframe==6.0.1 ; python_version >= "3.10" and python_version < "4.0"
idna==3.4 ; python_version >= "3.10" and python_version < "4.0"
iso8601==1.1.0 ; python_version >= "3.10" and python_version < "4.0"
limits==1.6 ; python_version >= "3.10" and python_version < "4.0"
loguru==0.6.0 ; python_version >= "3.10" and python_version < "4.0"
msgpack==1.0.4 ; python_version >= "3.10" and python_version < "4.0"
orjson==3.8.2 ; python_version >= "3.10" and python_version < "4.0"
packaging==21.3 ; python_version >= "3.10" and python_version < "4.0"
passlib[argon2]==1.7.4 ; python_version >= "3.10" and python_version < "4.0"
pendulum==2.1.2 ; python_version >= "3.10" and python_version < "4.0"
priority==2.0.0 ; python_version >= "3.10" and python_version < "4.0"
pycparser==2.21 ; python_version >= "3.10" and python_version < "4.0"
pycryptodomex==3.15.0 ; python_version >= "3.10" and python_version < "4.0"
pydantic==1.10.2 ; python_version >= "3.10" and python_version < "4.0"
pyparsing==3.0.9 ; python_version >= "3.10" and python_version < "4.0"
pyseto==1.6.10 ; python_version >= "3.10" and python_version < "4.0"
python-dateutil==2.8.2 ; python_version >= "3.10" and python_version < "4.0"
pytzdata==2020.1 ; python_version >= "3.10" and python_version < "4.0"
redis==4.3.5 ; python_version >= "3.10" and python_version < "4.0"
rfc3986[idna2008]==1.5.0 ; python_version >= "3.10" and python_version < "4.0"
sentry-sdk==1.11.1 ; python_version >= "3.10" and python_version < "4.0"
setuptools==65.6.0 ; python_version >= "3.10" and python_version < "4.0"
six==1.16.0 ; python_version >= "3.10" and python_version < "4.0"
slowapi==0.1.6 ; python_version >= "3.10" and python_version < "4.0"
sniffio==1.3.0 ; python_version >= "3.10" and python_version < "4.0"
starlette==0.20.4 ; python_version >= "3.10" and python_version < "4.0"
toml==0.10.2 ; python_version >= "3.10" and python_version < "4.0"
toolz==0.12.0 ; python_version >= "3.10" and python_version < "4.0"
typing-extensions==4.4.0 ; python_version >= "3.10" and python_version < "4.0"
ujson==5.5.0 ; python_version >= "3.10" and python_version < "4.0"
urllib3==1.26.12 ; python_version >= "3.10" and python_version < "4"
uvicorn==0.20.0 ; python_version >= "3.10" and python_version < "4.0"
uvloop==0.17.0 ; platform_system != "Windows" and python_version >= "3.10" and python_version < "4.0"
win32-setctime==1.1.0 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "win32"
wsproto==1.2.0 ; python_version >= "3.10" and python_version < "4.0"
aiofiles==22.1.0 ; python_version >= "3.11" and python_version < "4.0"
aiorwlock==1.3.0 ; python_version >= "3.11" and python_version < "4.0"
anyio==3.6.2 ; python_version >= "3.11" and python_version < "4.0"
argon2-cffi-bindings==21.2.0 ; python_version >= "3.11" and python_version < "4.0"
argon2-cffi==21.3.0 ; python_version >= "3.11" and python_version < "4.0"
async-timeout==4.0.2 ; python_version >= "3.11" and python_version < "4.0"
asyncstdlib==3.10.5 ; python_version >= "3.11" and python_version < "4.0"
attrs==22.2.0 ; python_version >= "3.11" and python_version < "4.0"
certifi==2022.12.7 ; python_version >= "3.11" and python_version < "4.0"
cffi==1.15.1 ; python_version >= "3.11" and python_version < "4.0"
click==8.1.3 ; python_version >= "3.11" and python_version < "4.0"
colorama==0.4.6 ; python_version >= "3.11" and python_version < "4.0" and sys_platform == "win32" or python_version >= "3.11" and python_version < "4.0" and platform_system == "Windows"
cryptography==37.0.4 ; python_version >= "3.11" and python_version < "4.0"
cytoolz==0.12.1 ; python_version >= "3.11" and python_version < "4.0"
deprecated==1.2.13 ; python_version >= "3.11" and python_version < "4.0"
fastapi-cache2==0.1.9 ; python_version >= "3.11" and python_version < "4.0"
fastapi-paseto-auth==0.6.0 ; python_version >= "3.11" and python_version < "4.0"
fastapi==0.85.0 ; python_version >= "3.11" and python_version < "4.0"
fasteners==0.17.3 ; python_version >= "3.11" and python_version < "4.0"
gunicorn==20.1.0 ; python_version >= "3.11" and python_version < "4.0"
h11==0.14.0 ; python_version >= "3.11" and python_version < "4.0"
h2==4.1.0 ; python_version >= "3.11" and python_version < "4.0"
hiredis==2.1.0 ; python_version >= "3.11" and python_version < "4.0"
hpack==4.0.0 ; python_version >= "3.11" and python_version < "4.0"
httpcore==0.16.3 ; python_version >= "3.11" and python_version < "4.0"
httpx-cache==0.7.0 ; python_version >= "3.11" and python_version < "4.0"
httpx==0.23.1 ; python_version >= "3.11" and python_version < "4.0"
httpx[http2]==0.23.1 ; python_version >= "3.11" and python_version < "4.0"
hyperframe==6.0.1 ; python_version >= "3.11" and python_version < "4.0"
idna==3.4 ; python_version >= "3.11" and python_version < "4.0"
iso8601==1.1.0 ; python_version >= "3.11" and python_version < "4.0"
limits==2.8.0 ; python_version >= "3.11" and python_version < "4.0"
loguru==0.6.0 ; python_version >= "3.11" and python_version < "4.0"
msgpack==1.0.4 ; python_version >= "3.11" and python_version < "4.0"
orjson==3.8.3 ; python_version >= "3.11" and python_version < "4.0"
packaging==22.0 ; python_version >= "3.11" and python_version < "4.0"
passlib[argon2]==1.7.4 ; python_version >= "3.11" and python_version < "4.0"
pendulum==2.1.2 ; python_version >= "3.11" and python_version < "4.0"
pycparser==2.21 ; python_version >= "3.11" and python_version < "4.0"
pycryptodomex==3.16.0 ; python_version >= "3.11" and python_version < "4.0"
pydantic==1.10.2 ; python_version >= "3.11" and python_version < "4.0"
pyseto==1.6.10 ; python_version >= "3.11" and python_version < "4.0"
python-dateutil==2.8.2 ; python_version >= "3.11" and python_version < "4.0"
pytzdata==2020.1 ; python_version >= "3.11" and python_version < "4.0"
redis==4.4.0 ; python_version >= "3.11" and python_version < "4.0"
rfc3986[idna2008]==1.5.0 ; python_version >= "3.11" and python_version < "4.0"
sentry-sdk==1.12.1 ; python_version >= "3.11" and python_version < "4.0"
setuptools==65.6.3 ; python_version >= "3.11" and python_version < "4.0"
six==1.16.0 ; python_version >= "3.11" and python_version < "4.0"
slowapi==0.1.7 ; python_version >= "3.11" and python_version < "4.0"
sniffio==1.3.0 ; python_version >= "3.11" and python_version < "4.0"
starlette==0.20.4 ; python_version >= "3.11" and python_version < "4.0"
toml==0.10.2 ; python_version >= "3.11" and python_version < "4.0"
toolz==0.12.0 ; python_version >= "3.11" and python_version < "4.0"
typing-extensions==4.4.0 ; python_version >= "3.11" and python_version < "4.0"
ujson==5.6.0 ; python_version >= "3.11" and python_version < "4.0"
urllib3==1.26.13 ; python_version >= "3.11" and python_version < "4.0"
uvicorn==0.20.0 ; python_version >= "3.11" and python_version < "4.0"
uvloop==0.17.0 ; python_version >= "3.11" and python_version < "4.0"
win32-setctime==1.1.0 ; python_version >= "3.11" and python_version < "4.0" and sys_platform == "win32"
wrapt==1.14.1 ; python_version >= "3.11" and python_version < "4.0"

8
run.py
View File

@ -1,13 +1,13 @@
import os
import sys
import toml
import logging
import sentry_sdk
from app.main import app
from loguru import logger
from fastapi import FastAPI
from types import FrameType
from typing import Any, Optional
from typing import Any
from multiprocessing import cpu_count
from gunicorn.glogging import Logger
from gunicorn.app.base import BaseApplication
@ -15,7 +15,9 @@ from sentry_sdk.integrations.redis import RedisIntegration
from sentry_sdk.integrations.httpx import HttpxIntegration
from sentry_sdk.integrations.gnu_backtrace import GnuBacktraceIntegration
config: dict = toml.load("config.toml")
from app.dependencies import load_config
config: dict = load_config()
# Enable sentry logging