diff --git a/api/__init__.py b/api/__init__.py index af00dda..4c54019 100644 --- a/api/__init__.py +++ b/api/__init__.py @@ -1,25 +1,16 @@ # api/__init__.py from sanic import Blueprint +import importlib +import pkgutil -from api.github import github -from api.ping import ping -from api.socials import socials -from api.info import info -from api.compat import github as compat -from api.donations import donations -from api.announcements import announcements -from api.login import login -from api.robots import robots +blueprints = [] +for _, module_name, _ in pkgutil.iter_modules(["api"]): + # Import the module + module = importlib.import_module(f"api.{module_name}") -api = Blueprint.group( - login, - ping, - github, - info, - socials, - donations, - announcements, - compat, - robots, - url_prefix="/", -) + # Add the module's blueprint to the list, if it exists + if hasattr(module, module_name): + blueprints.append(getattr(module, module_name)) + +# Create the Blueprint group with the dynamically imported blueprints +api = Blueprint.group(*blueprints, url_prefix="/") diff --git a/api/announcements.py b/api/announcements.py index 2e4c176..112d017 100644 --- a/api/announcements.py +++ b/api/announcements.py @@ -20,10 +20,11 @@ from data.models import AnnouncementDbModel, AttachmentDbModel import sanic_beskar from api.models.announcements import AnnouncementResponseModel -from config import api_version -from api.limiter import limiter +from api.utils.limiter import limiter +from api.utils.versioning import get_version -announcements: Blueprint = Blueprint("announcements", version=api_version) +module_name = "announcements" +announcements: Blueprint = Blueprint(module_name, version=get_version(module_name)) @announcements.get("/announcements") diff --git a/api/backends/github.py b/api/backends/github.py index b7bb875..3ef60a7 100644 --- a/api/backends/github.py +++ b/api/backends/github.py @@ -1,5 +1,4 @@ import asyncio -from json import loads import os from operator import eq from typing import Optional @@ -7,9 +6,9 @@ from typing import Optional import ujson from aiohttp import ClientResponse from sanic import SanicException -from toolz import filter, map, partial -from toolz.dicttoolz import get_in, keyfilter -from toolz.itertoolz import mapcat, pluck +from cytoolz import filter, map, partial +from cytoolz.dicttoolz import get_in, keyfilter +from cytoolz.itertoolz import mapcat, pluck from api.backends.backend import Backend, Repository from api.backends.entities import * diff --git a/api/compat.py b/api/compat.py index b60a689..c6f5255 100644 --- a/api/compat.py +++ b/api/compat.py @@ -20,12 +20,12 @@ from api.models.github import * from api.models.compat import ToolsResponseModel, ContributorsResponseModel from config import compat_repositories, owner -github: Blueprint = Blueprint("old") +compat: Blueprint = Blueprint("old") github_backend: Github = Github() -@github.get("/tools") +@compat.get("/tools") @openapi.definition( summary="Get patching tools' latest version.", response=[ToolsResponseModel] ) @@ -62,7 +62,7 @@ async def tools(request: Request) -> JSONResponse: return json(data, status=200) -@github.get("/contributors") +@compat.get("/contributors") @openapi.definition( summary="Get organization-wise contributors.", response=[ContributorsResponseModel] ) diff --git a/api/donations.py b/api/donations.py index 32e7ea8..8e00f32 100644 --- a/api/donations.py +++ b/api/donations.py @@ -10,9 +10,11 @@ from sanic.response import JSONResponse, json from sanic_ext import openapi from api.models.donations import DonationsResponseModel -from config import api_version, wallets, links +from config import wallets, links +from api.utils.versioning import get_version -donations: Blueprint = Blueprint("donations", version=api_version) +module_name = "donations" +donations: Blueprint = Blueprint(module_name, version=get_version(module_name)) @donations.get("/donations") diff --git a/api/github.py b/api/github.py index 8d76dea..0979d1d 100644 --- a/api/github.py +++ b/api/github.py @@ -17,9 +17,11 @@ from sanic_ext import openapi from api.backends.entities import Release, Contributor from api.backends.github import Github, GithubRepository from api.models.github import * -from config import owner, default_repository, api_version +from config import owner, default_repository +from api.utils.versioning import get_version -github: Blueprint = Blueprint("github", version=api_version) +module_name = "github" +github: Blueprint = Blueprint("github", version=get_version(module_name)) github_backend: Github = Github() diff --git a/api/info.py b/api/info.py index 18b8375..2fcacd7 100644 --- a/api/info.py +++ b/api/info.py @@ -10,9 +10,11 @@ from sanic.response import JSONResponse, json from sanic_ext import openapi from api.models.info import InfoResponseModel -from config import api_version, default_info +from config import default_info +from api.utils.versioning import get_version -info: Blueprint = Blueprint("info", version=api_version) +module_name = "info" +info: Blueprint = Blueprint("info", version=get_version(module_name)) @info.get("/info") diff --git a/api/login.py b/api/login.py index 9eeede1..652d6c0 100644 --- a/api/login.py +++ b/api/login.py @@ -10,13 +10,13 @@ from sanic.response import JSONResponse, json from sanic_ext import openapi from sanic_beskar.exceptions import AuthenticationError -from api.auth import beskar -from api.limiter import limiter +from api.utils.auth import beskar +from api.utils.limiter import limiter -from config import api_version +from api.utils.versioning import get_version - -login: Blueprint = Blueprint("login", version=api_version) +module_name = "login" +login: Blueprint = Blueprint(module_name, version=get_version(module_name)) @login.post("/login") diff --git a/api/ping.py b/api/ping.py index a544294..274ead5 100644 --- a/api/ping.py +++ b/api/ping.py @@ -7,9 +7,10 @@ Routes: from sanic import Blueprint, HTTPResponse, Request, response from sanic_ext import openapi -from config import api_version +from api.utils.versioning import get_version -ping: Blueprint = Blueprint("ping", version=api_version) +module_name = "ping" +ping: Blueprint = Blueprint(module_name, version=get_version(module_name)) @ping.head("/ping") diff --git a/api/socials.py b/api/socials.py index ac24b54..996cd21 100644 --- a/api/socials.py +++ b/api/socials.py @@ -14,7 +14,6 @@ from config import social_links, api_version socials: Blueprint = Blueprint("socials", version=api_version) - @socials.get("/socials") @openapi.definition( summary="Get ReVanced socials", diff --git a/api/auth.py b/api/utils/auth.py similarity index 100% rename from api/auth.py rename to api/utils/auth.py diff --git a/api/limiter.py b/api/utils/limiter.py similarity index 100% rename from api/limiter.py rename to api/utils/limiter.py diff --git a/api/utils/versioning.py b/api/utils/versioning.py new file mode 100644 index 0000000..ad69dd4 --- /dev/null +++ b/api/utils/versioning.py @@ -0,0 +1,8 @@ +from cytoolz import keyfilter +from config import api_versions + + +def get_version(value: str) -> str: + result = keyfilter(lambda key: value in api_versions[key], api_versions) + + return list(result.keys())[0] if result else "v0" diff --git a/app.py b/app.py index 1134ae8..db5f484 100644 --- a/app.py +++ b/app.py @@ -10,8 +10,8 @@ from sanic_ext import Config from api import api from config import openapi_title, openapi_version, openapi_description, hostnames -from api.limiter import configure_limiter -from api.auth import configure_auth +from api.utils.limiter import configure_limiter +from api.utils.auth import configure_auth import sentry_sdk @@ -65,7 +65,6 @@ for src, dest in REDIRECTS.items(): @app.on_request async def domain_check(request) -> HTTPResponse: - print(request.host) if request.host not in hostnames: return sanic.response.redirect(f"https://api.revanced.app/{request.path}") diff --git a/config.py b/config.py index 6ef3231..02ea01b 100644 --- a/config.py +++ b/config.py @@ -16,6 +16,12 @@ default_repository: str = ".github" # API Versioning +api_versions: dict[str, list[str]] = { + "old": ["compat"], + "v2": ["announcements", "donations", "github", "info", "login", "ping", "socials"], + "v3": ["connections"], +} + api_version: str = "v2" openapi_version: str = "2.0.0" openapi_title: str = "ReVanced API"