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 # api/__init__.py
from sanic import Blueprint from sanic import Blueprint
import importlib
import pkgutil
from api.github import github blueprints = []
from api.ping import ping for _, module_name, _ in pkgutil.iter_modules(["api"]):
from api.socials import socials # Import the module
from api.info import info module = importlib.import_module(f"api.{module_name}")
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
api = Blueprint.group( # Add the module's blueprint to the list, if it exists
login, if hasattr(module, module_name):
ping, blueprints.append(getattr(module, module_name))
github,
info, # Create the Blueprint group with the dynamically imported blueprints
socials, api = Blueprint.group(*blueprints, url_prefix="/")
donations,
announcements,
compat,
robots,
url_prefix="/",
)

View File

@ -20,10 +20,11 @@ from data.models import AnnouncementDbModel, AttachmentDbModel
import sanic_beskar import sanic_beskar
from api.models.announcements import AnnouncementResponseModel from api.models.announcements import AnnouncementResponseModel
from config import api_version from api.utils.limiter import limiter
from api.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") @announcements.get("/announcements")

View File

@ -1,5 +1,4 @@
import asyncio import asyncio
from json import loads
import os import os
from operator import eq from operator import eq
from typing import Optional from typing import Optional
@ -7,9 +6,9 @@ from typing import Optional
import ujson import ujson
from aiohttp import ClientResponse from aiohttp import ClientResponse
from sanic import SanicException from sanic import SanicException
from toolz import filter, map, partial from cytoolz import filter, map, partial
from toolz.dicttoolz import get_in, keyfilter from cytoolz.dicttoolz import get_in, keyfilter
from toolz.itertoolz import mapcat, pluck from cytoolz.itertoolz import mapcat, pluck
from api.backends.backend import Backend, Repository from api.backends.backend import Backend, Repository
from api.backends.entities import * from api.backends.entities import *

View File

@ -20,12 +20,12 @@ from api.models.github import *
from api.models.compat import ToolsResponseModel, ContributorsResponseModel from api.models.compat import ToolsResponseModel, ContributorsResponseModel
from config import compat_repositories, owner from config import compat_repositories, owner
github: Blueprint = Blueprint("old") compat: Blueprint = Blueprint("old")
github_backend: Github = Github() github_backend: Github = Github()
@github.get("/tools") @compat.get("/tools")
@openapi.definition( @openapi.definition(
summary="Get patching tools' latest version.", response=[ToolsResponseModel] summary="Get patching tools' latest version.", response=[ToolsResponseModel]
) )
@ -62,7 +62,7 @@ async def tools(request: Request) -> JSONResponse:
return json(data, status=200) return json(data, status=200)
@github.get("/contributors") @compat.get("/contributors")
@openapi.definition( @openapi.definition(
summary="Get organization-wise contributors.", response=[ContributorsResponseModel] 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 sanic_ext import openapi
from api.models.donations import DonationsResponseModel 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") @donations.get("/donations")

View File

@ -17,9 +17,11 @@ from sanic_ext import openapi
from api.backends.entities import Release, Contributor from api.backends.entities import Release, Contributor
from api.backends.github import Github, GithubRepository from api.backends.github import Github, GithubRepository
from api.models.github import * 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() github_backend: Github = Github()

View File

@ -10,9 +10,11 @@ from sanic.response import JSONResponse, json
from sanic_ext import openapi from sanic_ext import openapi
from api.models.info import InfoResponseModel 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") @info.get("/info")

View File

@ -10,13 +10,13 @@ from sanic.response import JSONResponse, json
from sanic_ext import openapi from sanic_ext import openapi
from sanic_beskar.exceptions import AuthenticationError from sanic_beskar.exceptions import AuthenticationError
from api.auth import beskar from api.utils.auth import beskar
from api.limiter import limiter from api.utils.limiter import limiter
from config import api_version from api.utils.versioning import get_version
module_name = "login"
login: Blueprint = Blueprint("login", version=api_version) login: Blueprint = Blueprint(module_name, version=get_version(module_name))
@login.post("/login") @login.post("/login")

View File

@ -7,9 +7,10 @@ Routes:
from sanic import Blueprint, HTTPResponse, Request, response from sanic import Blueprint, HTTPResponse, Request, response
from sanic_ext import openapi 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") @ping.head("/ping")

View File

@ -14,7 +14,6 @@ from config import social_links, api_version
socials: Blueprint = Blueprint("socials", version=api_version) socials: Blueprint = Blueprint("socials", version=api_version)
@socials.get("/socials") @socials.get("/socials")
@openapi.definition( @openapi.definition(
summary="Get ReVanced socials", 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 api import api
from config import openapi_title, openapi_version, openapi_description, hostnames from config import openapi_title, openapi_version, openapi_description, hostnames
from api.limiter import configure_limiter from api.utils.limiter import configure_limiter
from api.auth import configure_auth from api.utils.auth import configure_auth
import sentry_sdk import sentry_sdk
@ -65,7 +65,6 @@ for src, dest in REDIRECTS.items():
@app.on_request @app.on_request
async def domain_check(request) -> HTTPResponse: async def domain_check(request) -> HTTPResponse:
print(request.host)
if request.host not in hostnames: if request.host not in hostnames:
return sanic.response.redirect(f"https://api.revanced.app/{request.path}") return sanic.response.redirect(f"https://api.revanced.app/{request.path}")

View File

@ -16,6 +16,12 @@ default_repository: str = ".github"
# API Versioning # API Versioning
api_versions: dict[str, list[str]] = {
"old": ["compat"],
"v2": ["announcements", "donations", "github", "info", "login", "ping", "socials"],
"v3": ["connections"],
}
api_version: str = "v2" api_version: str = "v2"
openapi_version: str = "2.0.0" openapi_version: str = "2.0.0"
openapi_title: str = "ReVanced API" openapi_title: str = "ReVanced API"