mirror of
https://github.com/revanced/revanced-releases-api.git
synced 2025-05-19 13:37:05 +02:00
commit
6060dd744a
@ -1,4 +1,4 @@
|
|||||||
ARG VARIANT="3.10-bullseye"
|
ARG VARIANT="3.11-bullseye"
|
||||||
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}
|
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}
|
||||||
|
|
||||||
ARG NODE_VERSION="none"
|
ARG NODE_VERSION="none"
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
// Update 'VARIANT' to pick a Python version: 3, 3.10, 3.9, 3.8, 3.7, 3.6
|
// 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.
|
// Append -bullseye or -buster to pin to an OS version.
|
||||||
// Use -bullseye variants on local on arm64/Apple Silicon.
|
// Use -bullseye variants on local on arm64/Apple Silicon.
|
||||||
"VARIANT": "3.10-bullseye",
|
"VARIANT": "3.11-bullseye",
|
||||||
// Options
|
// Options
|
||||||
"NODE_VERSION": "lts/*"
|
"NODE_VERSION": "lts/*"
|
||||||
}
|
}
|
||||||
|
2
.github/workflows/codeql_analysis.yml
vendored
2
.github/workflows/codeql_analysis.yml
vendored
@ -35,7 +35,7 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: '3.10.7'
|
python-version: '3.11.0'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
|
2
.github/workflows/mypy.yml
vendored
2
.github/workflows/mypy.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
|||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: 3.10.8
|
python-version: 3.11.0
|
||||||
architecture: x64
|
architecture: x64
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM python:3.10-slim
|
FROM python:3.11-slim
|
||||||
|
|
||||||
ARG GITHUB_TOKEN
|
ARG GITHUB_TOKEN
|
||||||
ENV GITHUB_TOKEN $GITHUB_TOKEN
|
ENV GITHUB_TOKEN $GITHUB_TOKEN
|
||||||
|
10
README.md
10
README.md
@ -8,7 +8,7 @@ This is a simple API that returns the latest ReVanced releases, patches and cont
|
|||||||
|
|
||||||
## Usage
|
## 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.
|
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
|
### API Endpoints
|
||||||
|
|
||||||
* [tools](https://releases.rvcd.win/tools) - Returns the latest version of all ReVanced tools and Vanced MicroG
|
* [tools](https://releases.revanced.app/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
|
* [patches](https://releases.revanced.app/patches) - Returns the latest version of all ReVanced patches
|
||||||
* [contributors](https://releases.rvcd.win/contributors) - Returns contributors for all ReVanced projects
|
* [contributors](https://releases.revanced.app/contributors) - Returns contributors for all ReVanced projects
|
||||||
* [announcement](https://releases.rvcd.win/announcement) - Returns the latest announcement for the ReVanced projects
|
* [announcement](https://releases.revanced.app/announcement) - Returns the latest announcement for the ReVanced projects
|
||||||
|
|
||||||
## Clients
|
## Clients
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import toml
|
|
||||||
from redis import asyncio as aioredis
|
from redis import asyncio as aioredis
|
||||||
|
|
||||||
import app.utils.Logger as Logger
|
import app.utils.Logger as Logger
|
||||||
@ -6,7 +6,9 @@ from app.utils.Generators import Generators
|
|||||||
from app.models.AnnouncementModels import AnnouncementCreateModel
|
from app.models.AnnouncementModels import AnnouncementCreateModel
|
||||||
from app.utils.RedisConnector import RedisConnector
|
from app.utils.RedisConnector import RedisConnector
|
||||||
|
|
||||||
config: dict = toml.load("config.toml")
|
from app.dependencies import load_config
|
||||||
|
|
||||||
|
config: dict = load_config()
|
||||||
|
|
||||||
class Announcements:
|
class Announcements:
|
||||||
"""Implements the announcements class for the ReVanced API"""
|
"""Implements the announcements class for the ReVanced API"""
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import os
|
import os
|
||||||
import toml
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from fastapi_paseto_auth import AuthPASETO
|
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):
|
class PasetoSettings(BaseModel):
|
||||||
authpaseto_secret_key: str = os.environ['SECRET_KEY']
|
authpaseto_secret_key: str = os.environ['SECRET_KEY']
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
import toml
|
|
||||||
import orjson
|
import orjson
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
import argon2
|
import argon2
|
||||||
@ -12,7 +12,9 @@ from app.utils.Generators import Generators
|
|||||||
from app.models.ClientModels import ClientModel
|
from app.models.ClientModels import ClientModel
|
||||||
from app.utils.RedisConnector import RedisConnector
|
from app.utils.RedisConnector import RedisConnector
|
||||||
|
|
||||||
config: dict = toml.load("config.toml")
|
from app.dependencies import load_config
|
||||||
|
|
||||||
|
config: dict = load_config()
|
||||||
|
|
||||||
class Clients:
|
class Clients:
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import toml
|
|
||||||
from redis import asyncio as aioredis
|
from redis import asyncio as aioredis
|
||||||
import app.utils.Logger as Logger
|
import app.utils.Logger as Logger
|
||||||
from app.models.MirrorModels import MirrorModel, MirrorStoreModel
|
from app.models.MirrorModels import MirrorModel, MirrorStoreModel
|
||||||
from app.utils.RedisConnector import RedisConnector
|
from app.utils.RedisConnector import RedisConnector
|
||||||
|
|
||||||
config: dict = toml.load("config.toml")
|
from app.dependencies import load_config
|
||||||
|
|
||||||
|
config: dict = load_config()
|
||||||
|
|
||||||
class Mirrors:
|
class Mirrors:
|
||||||
"""Implements the Mirror class for the ReVanced API"""
|
"""Implements the Mirror class for the ReVanced API"""
|
||||||
|
@ -1,55 +1,60 @@
|
|||||||
from toolz.dicttoolz import keyfilter
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import uvloop
|
import uvloop
|
||||||
import orjson
|
import orjson
|
||||||
from base64 import b64decode
|
from base64 import b64decode
|
||||||
|
from toolz.dicttoolz import keyfilter
|
||||||
|
import asyncstdlib.builtins as a
|
||||||
from app.utils.HTTPXClient import HTTPXClient
|
from app.utils.HTTPXClient import HTTPXClient
|
||||||
|
|
||||||
|
|
||||||
class Releases:
|
class Releases:
|
||||||
|
|
||||||
"""Implements the methods required to get the latest releases and patches from revanced repositories."""
|
"""Implements the methods required to get the latest releases and patches from revanced repositories."""
|
||||||
|
|
||||||
uvloop.install()
|
uvloop.install()
|
||||||
|
|
||||||
httpx_client = HTTPXClient.create()
|
httpx_client = HTTPXClient.create()
|
||||||
|
|
||||||
async def __get_release(self, repository: str) -> list:
|
async def __get_release(self, repository: str) -> list:
|
||||||
# Get assets from latest release in a given repository.
|
"""Get assets from latest release in a given repository.
|
||||||
#
|
|
||||||
# Args:
|
Args:
|
||||||
# repository (str): Github's standard username/repository notation
|
repository (str): Github's standard username/repository notation
|
||||||
#
|
|
||||||
# Returns:
|
Returns:
|
||||||
# dict: dictionary of filename and download url
|
dict: dictionary of filename and download url
|
||||||
|
"""
|
||||||
|
|
||||||
assets: list = []
|
assets: list = []
|
||||||
response = await self.httpx_client.get(f"https://api.github.com/repos/{repository}/releases/latest")
|
response = await self.httpx_client.get(f"https://api.github.com/repos/{repository}/releases/latest")
|
||||||
|
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
release_assets: dict = response.json()['assets']
|
release_assets: dict = response.json()['assets']
|
||||||
release_version: str = response.json()['tag_name']
|
release_version: str = response.json()['tag_name']
|
||||||
release_tarball: str = response.json()['tarball_url']
|
release_tarball: str = response.json()['tarball_url']
|
||||||
release_timestamp: str = response.json()['published_at']
|
release_timestamp: str = response.json()['published_at']
|
||||||
|
|
||||||
|
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:
|
if release_assets:
|
||||||
for asset in release_assets:
|
assets = await asyncio.gather(*[get_asset_data(asset) for asset in release_assets])
|
||||||
assets.append({ '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']
|
|
||||||
})
|
|
||||||
else:
|
else:
|
||||||
assets.append({ 'repository': repository,
|
no_release_assets_data: dict = {'repository': repository,
|
||||||
'version': release_version,
|
'version': release_version,
|
||||||
'timestamp': release_timestamp,
|
'timestamp': release_timestamp,
|
||||||
'name': f"{repository.split('/')[1]}-{release_version}.tar.gz",
|
'name': f"{repository.split('/')[1]}-{release_version}.tar.gz",
|
||||||
'browser_download_url': release_tarball,
|
'browser_download_url': release_tarball,
|
||||||
'content_type': 'application/gzip'
|
'content_type': 'application/gzip'
|
||||||
})
|
}
|
||||||
|
assets.append(no_release_assets_data)
|
||||||
|
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
async def get_latest_releases(self, repositories: list) -> dict:
|
async def get_latest_releases(self, repositories: list) -> dict:
|
||||||
@ -61,58 +66,60 @@ class Releases:
|
|||||||
Returns:
|
Returns:
|
||||||
dict: A dictionary containing assets from each repository
|
dict: A dictionary containing assets from each repository
|
||||||
"""
|
"""
|
||||||
|
|
||||||
releases: dict[str, list] = {}
|
releases: dict[str, list] = {}
|
||||||
releases['tools'] = []
|
releases['tools'] = []
|
||||||
|
|
||||||
results: list = await asyncio.gather(*[self.__get_release(repository) for repository in repositories])
|
results: list = await asyncio.gather(*[self.__get_release(repository) for repository in repositories])
|
||||||
|
|
||||||
for result in results:
|
releases['tools'] = [asset for result in results for asset in result]
|
||||||
for asset in result:
|
|
||||||
releases['tools'].append(asset)
|
|
||||||
|
|
||||||
return releases
|
return releases
|
||||||
|
|
||||||
async def __get_patches_json(self) -> dict:
|
async def __get_patches_json(self) -> dict:
|
||||||
# Get revanced-patches repository's README.md.
|
"""Get revanced-patches repository's README.md.
|
||||||
#
|
|
||||||
# Returns:
|
Returns:
|
||||||
# dict: JSON content
|
dict: JSON content
|
||||||
#
|
"""
|
||||||
|
|
||||||
response = await self.httpx_client.get(f"https://api.github.com/repos/revanced/revanced-patches/contents/patches.json")
|
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
|
return content
|
||||||
|
|
||||||
async def get_patches_json(self) -> dict:
|
async def get_patches_json(self) -> dict:
|
||||||
"""Get patches.json from revanced-patches repository.
|
"""Get patches.json from revanced-patches repository.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: Patches available for a given app
|
dict: Patches available for a given app
|
||||||
"""
|
"""
|
||||||
|
|
||||||
patches: dict = await self.__get_patches_json()
|
patches: dict = await self.__get_patches_json()
|
||||||
|
|
||||||
return patches
|
return patches
|
||||||
|
|
||||||
async def __get_contributors(self, repository: str) -> list:
|
async def __get_contributors(self, repository: str) -> list:
|
||||||
# Get contributors from a given repository.
|
"""Get contributors from a given repository.
|
||||||
#
|
|
||||||
# Args:
|
Args:
|
||||||
# repository (str): Github's standard username/repository notation
|
repository (str): Github's standard username/repository notation
|
||||||
#
|
|
||||||
# Returns:
|
Returns:
|
||||||
# list: a list of dictionaries containing the repository's contributors
|
list: a list of dictionaries containing the repository's contributors
|
||||||
|
"""
|
||||||
keep: set = {'login', 'avatar_url', 'html_url'}
|
|
||||||
|
keep: set = {'login', 'avatar_url', 'html_url', 'contributions'}
|
||||||
|
|
||||||
response = await self.httpx_client.get(f"https://api.github.com/repos/{repository}/contributors")
|
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()]
|
contributors: list = [keyfilter(lambda k: k in keep, contributor) for contributor in response.json()]
|
||||||
|
|
||||||
|
|
||||||
return contributors
|
return contributors
|
||||||
|
|
||||||
async def get_contributors(self, repositories: list) -> dict:
|
async def get_contributors(self, repositories: list) -> dict:
|
||||||
"""Runs get_contributors() asynchronously for each repository.
|
"""Runs get_contributors() asynchronously for each repository.
|
||||||
|
|
||||||
@ -122,22 +129,23 @@ class Releases:
|
|||||||
Returns:
|
Returns:
|
||||||
dict: A dictionary containing the contributors from each repository
|
dict: A dictionary containing the contributors from each repository
|
||||||
"""
|
"""
|
||||||
|
|
||||||
contributors: dict[str, list]
|
contributors: dict[str, list]
|
||||||
|
|
||||||
contributors = {}
|
contributors = {}
|
||||||
contributors['repositories'] = []
|
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])
|
results: list[dict] = await asyncio.gather(*[self.__get_contributors(repository) for repository in revanced_repositories])
|
||||||
|
|
||||||
for key, value in zip(revanced_repositories, results):
|
async for key, value in a.zip(revanced_repositories, results):
|
||||||
data = { 'name': key, 'contributors': value }
|
data = {'name': key, 'contributors': value}
|
||||||
contributors['repositories'].append(data)
|
contributors['repositories'].append(data)
|
||||||
|
|
||||||
return contributors
|
return contributors
|
||||||
|
|
||||||
async def get_commits(self, org: str, repository: str, path: str) -> dict:
|
async def get_commits(self, org: str, repository: str, path: str) -> dict:
|
||||||
"""Get commit history from a given repository.
|
"""Get commit history from a given repository.
|
||||||
|
|
||||||
@ -154,36 +162,46 @@ class Releases:
|
|||||||
Returns:
|
Returns:
|
||||||
dict: a dictionary containing the repository's latest commits
|
dict: a dictionary containing the repository's latest commits
|
||||||
"""
|
"""
|
||||||
|
|
||||||
payload: dict = {}
|
payload: dict = {}
|
||||||
payload["repository"] = f"{org}/{repository}"
|
payload["repository"] = f"{org}/{repository}"
|
||||||
payload["path"] = path
|
payload["path"] = path
|
||||||
payload["commits"] = []
|
payload["commits"] = []
|
||||||
|
|
||||||
if org == 'revanced' or org == 'vancedapp':
|
if org == 'revanced' or org == 'vancedapp':
|
||||||
_releases = await self.httpx_client.get(
|
_releases = await self.httpx_client.get(
|
||||||
f"https://api.github.com/repos/{org}/{repository}/releases?per_page=2"
|
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}"
|
||||||
)
|
)
|
||||||
|
|
||||||
releases = _releases.json()
|
if _response.status_code == 200:
|
||||||
|
response = _response.json()
|
||||||
since = releases[1]['created_at']
|
|
||||||
until = releases[0]['created_at']
|
async def get_commit_data(commit: dict) -> dict:
|
||||||
|
return {'sha': commit['sha'],
|
||||||
_response = await self.httpx_client.get(
|
'author': commit['commit']['author']['name'],
|
||||||
f"https://api.github.com/repos/{org}/{repository}/commits?path={path}&since={since}&until={until}"
|
'date': commit['commit']['author']['date'],
|
||||||
)
|
'message': commit['commit']['message'],
|
||||||
|
'url': commit['html_url']
|
||||||
response = _response.json()
|
}
|
||||||
|
|
||||||
for commit in response:
|
data: list = await asyncio.gather(*[get_commit_data(commit) for commit in response])
|
||||||
data: dict[str, str] = {}
|
|
||||||
data["sha"] = commit["sha"]
|
payload['commits'].append(data)
|
||||||
data["author"] = commit["commit"]["author"]["name"]
|
else:
|
||||||
data["message"] = commit["commit"]["message"]
|
raise ValueError("Error retrieving commits")
|
||||||
data["html_url"] = commit["html_url"]
|
|
||||||
payload['commits'].append(data)
|
|
||||||
|
|
||||||
return payload
|
|
||||||
else:
|
else:
|
||||||
raise Exception("Invalid organization.")
|
raise ValueError("Invalid organization.")
|
||||||
|
|
||||||
|
return payload
|
||||||
|
18
app/controllers/Socials.py
Normal file
18
app/controllers/Socials.py
Normal 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
|
@ -1,4 +1,4 @@
|
|||||||
import toml
|
import tomllib as toml
|
||||||
|
|
||||||
def load_config() -> dict:
|
def load_config() -> dict:
|
||||||
"""Loads the config.toml file.
|
"""Loads the config.toml file.
|
||||||
@ -6,4 +6,7 @@ def load_config() -> dict:
|
|||||||
Returns:
|
Returns:
|
||||||
dict: the config.toml file as a dict
|
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)
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import toml
|
|
||||||
import binascii
|
import binascii
|
||||||
from redis import Redis
|
from redis import Redis
|
||||||
|
|
||||||
@ -34,15 +34,18 @@ from app.routers import tools
|
|||||||
from app.routers import clients
|
from app.routers import clients
|
||||||
from app.routers import patches
|
from app.routers import patches
|
||||||
from app.routers import mirrors
|
from app.routers import mirrors
|
||||||
|
from app.routers import socials
|
||||||
from app.routers import changelogs
|
from app.routers import changelogs
|
||||||
from app.routers import contributors
|
from app.routers import contributors
|
||||||
from app.routers import announcement
|
from app.routers import announcement
|
||||||
|
|
||||||
|
from app.dependencies import load_config
|
||||||
|
|
||||||
"""Get latest ReVanced releases from GitHub API."""
|
"""Get latest ReVanced releases from GitHub API."""
|
||||||
|
|
||||||
# Load config
|
# Load config
|
||||||
|
|
||||||
config: dict = toml.load("config.toml")
|
config: dict = load_config()
|
||||||
|
|
||||||
# Create FastAPI instance
|
# Create FastAPI instance
|
||||||
|
|
||||||
@ -74,6 +77,7 @@ app.include_router(tools.router)
|
|||||||
app.include_router(patches.router)
|
app.include_router(patches.router)
|
||||||
app.include_router(contributors.router)
|
app.include_router(contributors.router)
|
||||||
app.include_router(changelogs.router)
|
app.include_router(changelogs.router)
|
||||||
|
app.include_router(socials.router)
|
||||||
app.include_router(auth.router)
|
app.include_router(auth.router)
|
||||||
app.include_router(clients.router)
|
app.include_router(clients.router)
|
||||||
app.include_router(announcement.router)
|
app.include_router(announcement.router)
|
||||||
|
@ -53,6 +53,7 @@ class ContributorFields(BaseModel):
|
|||||||
login: str
|
login: str
|
||||||
avatar_url: str
|
avatar_url: str
|
||||||
html_url: str
|
html_url: str
|
||||||
|
contributions: int
|
||||||
|
|
||||||
class ContributorsResponseFields(BaseModel):
|
class ContributorsResponseFields(BaseModel):
|
||||||
"""Implements the fields for each repository in the /contributors endpoint
|
"""Implements the fields for each repository in the /contributors endpoint
|
||||||
|
@ -107,3 +107,12 @@ class RevokedTokenResponse(BaseModel):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
revoked: bool
|
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
24
app/routers/socials.py
Normal 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()
|
@ -1,10 +1,12 @@
|
|||||||
import os
|
import os
|
||||||
import toml
|
|
||||||
from redis import asyncio as aioredis
|
from redis import asyncio as aioredis
|
||||||
|
|
||||||
|
from app.dependencies import load_config
|
||||||
|
|
||||||
# Load config
|
# Load config
|
||||||
|
|
||||||
config: dict = toml.load("config.toml")
|
config: dict = load_config()
|
||||||
|
|
||||||
# Redis connection parameters
|
# Redis connection parameters
|
||||||
|
|
||||||
|
15
config.toml
15
config.toml
@ -1,5 +1,4 @@
|
|||||||
[docs]
|
[docs]
|
||||||
|
|
||||||
title = "ReVanced Releases API"
|
title = "ReVanced Releases API"
|
||||||
description = """
|
description = """
|
||||||
## The official JSON API for ReVanced Releases 🚀
|
## The official JSON API for ReVanced Releases 🚀
|
||||||
@ -22,10 +21,9 @@ description = """
|
|||||||
3. Abuse of the API will result in IP blocks
|
3. Abuse of the API will result in IP blocks
|
||||||
|
|
||||||
"""
|
"""
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
|
|
||||||
[license]
|
[license]
|
||||||
|
|
||||||
name = "AGPL-3.0"
|
name = "AGPL-3.0"
|
||||||
url = "https://www.gnu.org/licenses/agpl-3.0.en.html"
|
url = "https://www.gnu.org/licenses/agpl-3.0.en.html"
|
||||||
|
|
||||||
@ -57,6 +55,13 @@ database = 5
|
|||||||
access_token_expires = false
|
access_token_expires = false
|
||||||
|
|
||||||
[app]
|
[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"
|
||||||
|
@ -3,7 +3,7 @@ version: "3.8"
|
|||||||
services:
|
services:
|
||||||
redis:
|
redis:
|
||||||
container_name: revanced-releases-api-redis
|
container_name: revanced-releases-api-redis
|
||||||
image: redis-stack-server:latest
|
image: redis/redis-stack-server:latest
|
||||||
environment:
|
environment:
|
||||||
- REDIS_ARGS=--save 60 1 --appendonly yes
|
- REDIS_ARGS=--save 60 1 --appendonly yes
|
||||||
volumes:
|
volumes:
|
||||||
@ -13,7 +13,7 @@ services:
|
|||||||
restart: always
|
restart: always
|
||||||
revanced-releases-api:
|
revanced-releases-api:
|
||||||
container_name: 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:
|
environment:
|
||||||
- GITHUB_TOKEN=YOUR_GITHUB_TOKEN
|
- GITHUB_TOKEN=YOUR_GITHUB_TOKEN
|
||||||
- REDIS_URL=revanced-releases-api-redis
|
- REDIS_URL=revanced-releases-api-redis
|
||||||
|
@ -4,7 +4,7 @@ version: "3.8"
|
|||||||
services:
|
services:
|
||||||
redis:
|
redis:
|
||||||
container_name: revanced-releases-api-redis
|
container_name: revanced-releases-api-redis
|
||||||
image: redis-stack-server:latest
|
image: redis/redis-stack-server:latest
|
||||||
environment:
|
environment:
|
||||||
- REDIS_ARGS=--save 60 1 --appendonly yes
|
- REDIS_ARGS=--save 60 1 --appendonly yes
|
||||||
volumes:
|
volumes:
|
||||||
@ -14,7 +14,7 @@ services:
|
|||||||
restart: always
|
restart: always
|
||||||
revanced-releases-api:
|
revanced-releases-api:
|
||||||
container_name: 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:
|
environment:
|
||||||
- GITHUB_TOKEN=YOUR_GITHUB_TOKEN
|
- GITHUB_TOKEN=YOUR_GITHUB_TOKEN
|
||||||
- REDIS_URL=revanced-releases-api-redis
|
- REDIS_URL=revanced-releases-api-redis
|
||||||
|
8
mypy.ini
8
mypy.ini
@ -1,5 +1,5 @@
|
|||||||
[mypy]
|
[mypy]
|
||||||
python_version = 3.10
|
python_version = 3.11
|
||||||
pretty = true
|
pretty = true
|
||||||
follow_imports = normal
|
follow_imports = normal
|
||||||
namespace_packages = true
|
namespace_packages = true
|
||||||
@ -75,4 +75,8 @@ ignore_missing_imports = True
|
|||||||
|
|
||||||
[mypy-asgiref.*]
|
[mypy-asgiref.*]
|
||||||
# No stubs available
|
# No stubs available
|
||||||
ignore_missing_imports = True
|
ignore_missing_imports = True
|
||||||
|
|
||||||
|
[mypy-tomllib.*]
|
||||||
|
# No stubs available
|
||||||
|
ignore_missing_imports = True
|
||||||
|
912
poetry.lock
generated
912
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,12 +1,12 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "revanced-releases-api"
|
name = "revanced-releases-api"
|
||||||
version = "0.1.0"
|
version = "1.1.0"
|
||||||
description = "JSON API for ReVanced Releases"
|
description = "JSON API for ReVanced Releases"
|
||||||
authors = ["Alexandre Teles <alexandre.teles@ufba.br>"]
|
authors = ["Alexandre Teles <alexandre.teles@ufba.br>"]
|
||||||
license = "AGPLv3"
|
license = "AGPLv3"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.10"
|
python = "^3.11"
|
||||||
fastapi = ">=0.85.0"
|
fastapi = ">=0.85.0"
|
||||||
httpx = {version = ">=0.23.0", extras = ["http2"]}
|
httpx = {version = ">=0.23.0", extras = ["http2"]}
|
||||||
httpx-cache = ">=0.6.0"
|
httpx-cache = ">=0.6.0"
|
||||||
@ -18,7 +18,7 @@ redis = ">=4.3.4"
|
|||||||
loguru = ">=0.6.0"
|
loguru = ">=0.6.0"
|
||||||
sentry-sdk = ">=1.9.8"
|
sentry-sdk = ">=1.9.8"
|
||||||
argon2-cffi = ">=21.3.0"
|
argon2-cffi = ">=21.3.0"
|
||||||
hypercorn = {extras = ["uvloop"], version = ">=0.14.3"}
|
uvloop = ">=0.17.0"
|
||||||
cytoolz = ">=0.12.0"
|
cytoolz = ">=0.12.0"
|
||||||
fastapi-paseto-auth = "^0.6.0"
|
fastapi-paseto-auth = "^0.6.0"
|
||||||
ujson = ">=5.5.0"
|
ujson = ">=5.5.0"
|
||||||
@ -26,6 +26,7 @@ hiredis = ">=2.0.0"
|
|||||||
aiofiles = ">=22.1.0"
|
aiofiles = ">=22.1.0"
|
||||||
uvicorn = ">=0.18.3"
|
uvicorn = ">=0.18.3"
|
||||||
gunicorn = ">=20.1.0"
|
gunicorn = ">=20.1.0"
|
||||||
|
asyncstdlib = ">=3.10.5"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
mypy = ">=0.971"
|
mypy = ">=0.971"
|
||||||
|
124
requirements.txt
124
requirements.txt
@ -1,63 +1,61 @@
|
|||||||
aiofiles==22.1.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.10" 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"
|
||||||
anyio==3.6.2 ; python_version >= "3.10" and python_version < "4.0"
|
argon2-cffi-bindings==21.2.0 ; python_version >= "3.11" 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.11" 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.11" and python_version < "4.0"
|
||||||
async-timeout==4.0.2 ; python_version >= "3.10" and python_version < "4.0"
|
asyncstdlib==3.10.5 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
attrs==21.4.0 ; python_version >= "3.10" and python_version < "4.0"
|
attrs==22.2.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
certifi==2022.9.24 ; python_version >= "3.10" 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.10" 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.10" 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.10" and python_version < "4.0" and sys_platform == "win32" or python_version >= "3.10" and python_version < "4.0" and platform_system == "Windows"
|
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.10" and python_version < "4.0"
|
cryptography==37.0.4 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
cytoolz==0.12.0 ; python_version >= "3.10" and python_version < "4.0"
|
cytoolz==0.12.1 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
fastapi-cache2==0.1.9 ; python_version >= "3.10" and python_version < "4.0"
|
deprecated==1.2.13 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
fastapi-paseto-auth==0.6.0 ; python_version >= "3.10" and python_version < "4.0"
|
fastapi-cache2==0.1.9 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
fastapi==0.85.0 ; python_version >= "3.10" and python_version < "4.0"
|
fastapi-paseto-auth==0.6.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
fasteners==0.17.3 ; python_version >= "3.10" and python_version < "4.0"
|
fastapi==0.85.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
gunicorn==20.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
fasteners==0.17.3 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
h11==0.14.0 ; python_version >= "3.10" and python_version < "4.0"
|
gunicorn==20.1.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
h2==4.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
h11==0.14.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
hiredis==2.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
h2==4.1.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
hpack==4.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
hiredis==2.1.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
httpcore==0.16.1 ; python_version >= "3.10" and python_version < "4.0"
|
hpack==4.0.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
httpx-cache==0.6.1 ; python_version >= "3.10" and python_version < "4.0"
|
httpcore==0.16.3 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
httpx==0.23.1 ; python_version >= "3.10" and python_version < "4.0"
|
httpx-cache==0.7.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
httpx[http2]==0.23.1 ; python_version >= "3.10" and python_version < "4.0"
|
httpx==0.23.1 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
hypercorn[uvloop]==0.14.3 ; python_version >= "3.10" 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.10" and python_version < "4.0"
|
hyperframe==6.0.1 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
idna==3.4 ; python_version >= "3.10" and python_version < "4.0"
|
idna==3.4 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
iso8601==1.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
iso8601==1.1.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
limits==1.6 ; python_version >= "3.10" 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.10" 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.10" and python_version < "4.0"
|
msgpack==1.0.4 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
orjson==3.8.2 ; python_version >= "3.10" and python_version < "4.0"
|
orjson==3.8.3 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
packaging==21.3 ; python_version >= "3.10" 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.10" 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.10" and python_version < "4.0"
|
pendulum==2.1.2 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
priority==2.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
pycparser==2.21 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
pycparser==2.21 ; python_version >= "3.10" and python_version < "4.0"
|
pycryptodomex==3.16.0 ; python_version >= "3.11" 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.11" and python_version < "4.0"
|
||||||
pydantic==1.10.2 ; python_version >= "3.10" and python_version < "4.0"
|
pyseto==1.6.10 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
pyparsing==3.0.9 ; python_version >= "3.10" and python_version < "4.0"
|
python-dateutil==2.8.2 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
pyseto==1.6.10 ; python_version >= "3.10" and python_version < "4.0"
|
pytzdata==2020.1 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
python-dateutil==2.8.2 ; python_version >= "3.10" and python_version < "4.0"
|
redis==4.4.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
pytzdata==2020.1 ; python_version >= "3.10" and python_version < "4.0"
|
rfc3986[idna2008]==1.5.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
redis==4.3.5 ; python_version >= "3.10" and python_version < "4.0"
|
sentry-sdk==1.12.1 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
rfc3986[idna2008]==1.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
setuptools==65.6.3 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
sentry-sdk==1.11.1 ; python_version >= "3.10" and python_version < "4.0"
|
six==1.16.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
setuptools==65.6.0 ; python_version >= "3.10" and python_version < "4.0"
|
slowapi==0.1.7 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
six==1.16.0 ; python_version >= "3.10" and python_version < "4.0"
|
sniffio==1.3.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
slowapi==0.1.6 ; python_version >= "3.10" and python_version < "4.0"
|
starlette==0.20.4 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
sniffio==1.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
toml==0.10.2 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
starlette==0.20.4 ; python_version >= "3.10" and python_version < "4.0"
|
toolz==0.12.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
toml==0.10.2 ; python_version >= "3.10" and python_version < "4.0"
|
typing-extensions==4.4.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
toolz==0.12.0 ; python_version >= "3.10" and python_version < "4.0"
|
ujson==5.6.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
typing-extensions==4.4.0 ; python_version >= "3.10" and python_version < "4.0"
|
urllib3==1.26.13 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
ujson==5.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
uvicorn==0.20.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
urllib3==1.26.12 ; python_version >= "3.10" and python_version < "4"
|
uvloop==0.17.0 ; python_version >= "3.11" and python_version < "4.0"
|
||||||
uvicorn==0.20.0 ; python_version >= "3.10" and python_version < "4.0"
|
win32-setctime==1.1.0 ; python_version >= "3.11" and python_version < "4.0" and sys_platform == "win32"
|
||||||
uvloop==0.17.0 ; platform_system != "Windows" and python_version >= "3.10" and python_version < "4.0"
|
wrapt==1.14.1 ; python_version >= "3.11" 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"
|
|
||||||
|
8
run.py
8
run.py
@ -1,13 +1,13 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import toml
|
|
||||||
import logging
|
import logging
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
from app.main import app
|
from app.main import app
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from types import FrameType
|
from types import FrameType
|
||||||
from typing import Any, Optional
|
from typing import Any
|
||||||
from multiprocessing import cpu_count
|
from multiprocessing import cpu_count
|
||||||
from gunicorn.glogging import Logger
|
from gunicorn.glogging import Logger
|
||||||
from gunicorn.app.base import BaseApplication
|
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.httpx import HttpxIntegration
|
||||||
from sentry_sdk.integrations.gnu_backtrace import GnuBacktraceIntegration
|
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
|
# Enable sentry logging
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user