mirror of
https://github.com/revanced/revanced-api.git
synced 2025-05-02 15:44:33 +02:00
refactor: move versioning efforts to initalization
This commit is contained in:
parent
8d36663610
commit
42c88290b1
@ -2,15 +2,26 @@
|
|||||||
from sanic import Blueprint
|
from sanic import Blueprint
|
||||||
import importlib
|
import importlib
|
||||||
import pkgutil
|
import pkgutil
|
||||||
|
from api.utils.versioning import get_version
|
||||||
|
|
||||||
blueprints = []
|
# Dynamically import all modules in the 'api' package, excluding subdirectories
|
||||||
for _, module_name, _ in pkgutil.iter_modules(["api"]):
|
versioned_blueprints = {}
|
||||||
|
for finder, module_name, ispkg in pkgutil.iter_modules(["api"]):
|
||||||
|
if not ispkg:
|
||||||
# Import the module
|
# Import the module
|
||||||
module = importlib.import_module(f"api.{module_name}")
|
module = importlib.import_module(f"api.{module_name}")
|
||||||
|
|
||||||
# Add the module's blueprint to the list, if it exists
|
# Add the module's blueprint to the versioned list, if it exists
|
||||||
if hasattr(module, module_name):
|
if hasattr(module, module_name):
|
||||||
blueprints.append(getattr(module, module_name))
|
blueprint = getattr(module, module_name)
|
||||||
|
version = get_version(module_name)
|
||||||
|
versioned_blueprints.setdefault(version, []).append(blueprint)
|
||||||
|
|
||||||
# Create the Blueprint group with the dynamically imported blueprints
|
# Create Blueprint groups for each version
|
||||||
api = Blueprint.group(*blueprints, url_prefix="/")
|
api = []
|
||||||
|
for version, blueprints in versioned_blueprints.items():
|
||||||
|
if version == "old":
|
||||||
|
group = Blueprint.group(*blueprints, url_prefix="/")
|
||||||
|
else:
|
||||||
|
group = Blueprint.group(*blueprints, version=version, url_prefix="/")
|
||||||
|
api.append(group)
|
||||||
|
@ -10,6 +10,7 @@ Routes:
|
|||||||
- DELETE /announcements/<announcement_id:int>: Delete an announcement.
|
- DELETE /announcements/<announcement_id:int>: Delete an announcement.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
import datetime
|
import datetime
|
||||||
from sanic import Blueprint, Request
|
from sanic import Blueprint, Request
|
||||||
from sanic.response import JSONResponse, json
|
from sanic.response import JSONResponse, json
|
||||||
@ -21,10 +22,8 @@ import sanic_beskar
|
|||||||
|
|
||||||
from api.models.announcements import AnnouncementResponseModel
|
from api.models.announcements import AnnouncementResponseModel
|
||||||
from api.utils.limiter import limiter
|
from api.utils.limiter import limiter
|
||||||
from api.utils.versioning import get_version
|
|
||||||
|
|
||||||
module_name = "announcements"
|
announcements: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
|
||||||
announcements: Blueprint = Blueprint(module_name, version=get_version(module_name))
|
|
||||||
|
|
||||||
|
|
||||||
@announcements.get("/announcements")
|
@announcements.get("/announcements")
|
||||||
|
@ -9,8 +9,7 @@ Routes:
|
|||||||
- GET /patches/<tag:str>: Retrieve a list of patches for a given release tag.
|
- GET /patches/<tag:str>: Retrieve a list of patches for a given release tag.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
import os
|
||||||
|
|
||||||
from sanic import Blueprint, Request
|
from sanic import Blueprint, Request
|
||||||
from sanic.response import JSONResponse, json
|
from sanic.response import JSONResponse, json
|
||||||
from sanic_ext import openapi
|
from sanic_ext import openapi
|
||||||
@ -20,7 +19,7 @@ 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
|
||||||
|
|
||||||
compat: Blueprint = Blueprint("old")
|
compat: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
|
||||||
|
|
||||||
github_backend: Github = Github()
|
github_backend: Github = Github()
|
||||||
|
|
||||||
|
32
api/connections.py
Normal file
32
api/connections.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
"""
|
||||||
|
This module provides a blueprint for the connections endpoint.
|
||||||
|
|
||||||
|
Routes:
|
||||||
|
- GET /connections: Get ReVanced connection links.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
from sanic import Blueprint, Request
|
||||||
|
from sanic.response import JSONResponse, json
|
||||||
|
from sanic_ext import openapi
|
||||||
|
|
||||||
|
from api.models.socials import ConnectionsResponseModel
|
||||||
|
from config import social_links
|
||||||
|
|
||||||
|
connections: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
|
||||||
|
|
||||||
|
|
||||||
|
@connections.get("/connections")
|
||||||
|
@openapi.definition(
|
||||||
|
summary="Get ReVanced connection links",
|
||||||
|
response=[ConnectionsResponseModel],
|
||||||
|
)
|
||||||
|
async def root(request: Request) -> JSONResponse:
|
||||||
|
"""
|
||||||
|
Returns a JSONResponse with a dictionary containing ReVanced connection links.
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
- JSONResponse: A Sanic JSONResponse instance containing a dictionary with the connection links.
|
||||||
|
"""
|
||||||
|
data: dict[str, dict] = {"connections": social_links}
|
||||||
|
return json(data, status=200)
|
@ -5,16 +5,16 @@ Routes:
|
|||||||
- GET /donations: Get ReVanced donation links and wallets.
|
- GET /donations: Get ReVanced donation links and wallets.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
from sanic import Blueprint, Request
|
from sanic import Blueprint, Request
|
||||||
from sanic.response import JSONResponse, json
|
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 wallets, links
|
from config import wallets, links
|
||||||
from api.utils.versioning import get_version
|
|
||||||
|
|
||||||
module_name = "donations"
|
donations: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
|
||||||
donations: Blueprint = Blueprint(module_name, version=get_version(module_name))
|
|
||||||
|
|
||||||
|
|
||||||
@donations.get("/donations")
|
@donations.get("/donations")
|
||||||
|
@ -10,6 +10,7 @@ Routes:
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
from sanic import Blueprint, Request
|
from sanic import Blueprint, Request
|
||||||
from sanic.response import JSONResponse, json
|
from sanic.response import JSONResponse, json
|
||||||
from sanic_ext import openapi
|
from sanic_ext import openapi
|
||||||
@ -18,10 +19,8 @@ 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
|
from config import owner, default_repository
|
||||||
from api.utils.versioning import get_version
|
|
||||||
|
|
||||||
module_name = "github"
|
github: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
|
||||||
github: Blueprint = Blueprint("github", version=get_version(module_name))
|
|
||||||
|
|
||||||
github_backend: Github = Github()
|
github_backend: Github = Github()
|
||||||
|
|
||||||
|
@ -5,16 +5,15 @@ Routes:
|
|||||||
- GET /info: Get info about the owner of the API.
|
- GET /info: Get info about the owner of the API.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
from sanic import Blueprint, Request
|
from sanic import Blueprint, Request
|
||||||
from sanic.response import JSONResponse, json
|
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 default_info
|
from config import default_info
|
||||||
from api.utils.versioning import get_version
|
|
||||||
|
|
||||||
module_name = "info"
|
info: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
|
||||||
info: Blueprint = Blueprint("info", version=get_version(module_name))
|
|
||||||
|
|
||||||
|
|
||||||
@info.get("/info")
|
@info.get("/info")
|
||||||
|
@ -5,6 +5,7 @@ Routes:
|
|||||||
- POST /login: Login to the API
|
- POST /login: Login to the API
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
from sanic import Blueprint, Request
|
from sanic import Blueprint, Request
|
||||||
from sanic.response import JSONResponse, json
|
from sanic.response import JSONResponse, json
|
||||||
from sanic_ext import openapi
|
from sanic_ext import openapi
|
||||||
@ -13,10 +14,7 @@ from sanic_beskar.exceptions import AuthenticationError
|
|||||||
from api.utils.auth import beskar
|
from api.utils.auth import beskar
|
||||||
from api.utils.limiter import limiter
|
from api.utils.limiter import limiter
|
||||||
|
|
||||||
from api.utils.versioning import get_version
|
login: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
|
||||||
|
|
||||||
module_name = "login"
|
|
||||||
login: Blueprint = Blueprint(module_name, version=get_version(module_name))
|
|
||||||
|
|
||||||
|
|
||||||
@login.post("/login")
|
@login.post("/login")
|
||||||
|
@ -11,7 +11,7 @@ class SocialFields(BaseModel):
|
|||||||
preferred: bool
|
preferred: bool
|
||||||
|
|
||||||
|
|
||||||
class SocialsResponseModel(BaseModel):
|
class ConnectionsResponseModel(BaseModel):
|
||||||
"""
|
"""
|
||||||
A Pydantic BaseModel that represents a dictionary of social links.
|
A Pydantic BaseModel that represents a dictionary of social links.
|
||||||
"""
|
"""
|
||||||
@ -21,3 +21,15 @@ class SocialsResponseModel(BaseModel):
|
|||||||
A dictionary where the keys are the names of the social networks, and
|
A dictionary where the keys are the names of the social networks, and
|
||||||
the values are the links to the profiles or pages.
|
the values are the links to the profiles or pages.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ConnectionsResponseModel(BaseModel):
|
||||||
|
"""
|
||||||
|
A Pydantic BaseModel that represents a dictionary of connection links.
|
||||||
|
"""
|
||||||
|
|
||||||
|
connections: list[SocialFields]
|
||||||
|
"""
|
||||||
|
A dictionary where the keys are the names of the social networks, and
|
||||||
|
the values are the links to the profiles or pages.
|
||||||
|
"""
|
||||||
|
@ -5,12 +5,11 @@ Routes:
|
|||||||
- HEAD /ping: Ping the API.
|
- HEAD /ping: Ping the API.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
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 api.utils.versioning import get_version
|
|
||||||
|
|
||||||
module_name = "ping"
|
ping: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
|
||||||
ping: Blueprint = Blueprint(module_name, version=get_version(module_name))
|
|
||||||
|
|
||||||
|
|
||||||
@ping.head("/ping")
|
@ping.head("/ping")
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
|
import os
|
||||||
from sanic import Blueprint
|
from sanic import Blueprint
|
||||||
from sanic.response import text
|
from sanic.response import text
|
||||||
|
|
||||||
|
|
||||||
robots: Blueprint = Blueprint("robots")
|
robots: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
|
||||||
|
|
||||||
|
|
||||||
@robots.get("/robots.txt")
|
@robots.get("/robots.txt")
|
||||||
|
@ -5,19 +5,21 @@ Routes:
|
|||||||
- GET /socials: Get ReVanced socials.
|
- GET /socials: Get ReVanced socials.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
from sanic import Blueprint, Request
|
from sanic import Blueprint, Request
|
||||||
from sanic.response import JSONResponse, json
|
from sanic.response import JSONResponse, json
|
||||||
from sanic_ext import openapi
|
from sanic_ext import openapi
|
||||||
|
|
||||||
from api.models.socials import SocialsResponseModel
|
from api.models.socials import ConnectionsResponseModel
|
||||||
from config import social_links, api_version
|
from config import social_links
|
||||||
|
|
||||||
|
socials: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
|
||||||
|
|
||||||
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",
|
||||||
response=[SocialsResponseModel],
|
response=[ConnectionsResponseModel],
|
||||||
)
|
)
|
||||||
async def root(request: Request) -> JSONResponse:
|
async def root(request: Request) -> JSONResponse:
|
||||||
"""
|
"""
|
||||||
|
21
app.py
21
app.py
@ -15,15 +15,14 @@ from api.utils.auth import configure_auth
|
|||||||
|
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
|
|
||||||
if os.environ.get("SENTRY_DSN"):
|
# if os.environ.get("SENTRY_DSN"):
|
||||||
sentry_sdk.init(
|
# sentry_sdk.init(
|
||||||
dsn=os.environ["SENTRY_DSN"],
|
# dsn=os.environ["SENTRY_DSN"],
|
||||||
enable_tracing=True,
|
# enable_tracing=True,
|
||||||
traces_sample_rate=1.0,
|
# traces_sample_rate=1.0,
|
||||||
debug=True,
|
# )
|
||||||
)
|
# else:
|
||||||
else:
|
# print("WARNING: Sentry DSN not set, not enabling Sentry")
|
||||||
print("WARNING: Sentry DSN not set, not enabling Sentry")
|
|
||||||
|
|
||||||
REDIRECTS = {
|
REDIRECTS = {
|
||||||
"/": "/docs/swagger",
|
"/": "/docs/swagger",
|
||||||
@ -50,7 +49,9 @@ configure_auth(app)
|
|||||||
# sanic-limiter
|
# sanic-limiter
|
||||||
configure_limiter(app)
|
configure_limiter(app)
|
||||||
|
|
||||||
app.blueprint(api)
|
|
||||||
|
for endpoint in api:
|
||||||
|
app.blueprint(api)
|
||||||
|
|
||||||
# https://sanic.dev/en/guide/how-to/static-redirects.html
|
# https://sanic.dev/en/guide/how-to/static-redirects.html
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from sanic import Sanic
|
from sanic import Sanic
|
||||||
|
|
||||||
from api.models.socials import SocialsResponseModel
|
from api.models.socials import ConnectionsResponseModel
|
||||||
|
|
||||||
from config import api_version
|
from config import api_version
|
||||||
|
|
||||||
@ -12,4 +12,4 @@ from config import api_version
|
|||||||
async def test_socials(app: Sanic):
|
async def test_socials(app: Sanic):
|
||||||
_, response = await app.asgi_client.get(f"/{api_version}/socials")
|
_, response = await app.asgi_client.get(f"/{api_version}/socials")
|
||||||
assert response.status == 200
|
assert response.status == 200
|
||||||
assert SocialsResponseModel(**response.json)
|
assert ConnectionsResponseModel(**response.json)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user