feat: better versioning engine

This commit is contained in:
Alexandre Teles 2023-11-21 01:01:13 -03:00 committed by Alexandre Teles (afterSt0rm)
parent 73252524f1
commit 8d36663610
15 changed files with 58 additions and 48 deletions

View File

@ -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="/")

View File

@ -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")

View File

@ -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 *

View File

@ -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]
)

View File

@ -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")

View File

@ -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()

View File

@ -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")

View File

@ -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")

View File

@ -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")

View File

@ -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",

8
api/utils/versioning.py Normal file
View File

@ -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"

5
app.py
View File

@ -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}")

View File

@ -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"