Merge pull request #155 from ReVanced/dev

feat: closes #153, closes #150, closes #147, closes #146
This commit is contained in:
Alexandre Teles (afterSt0rm) 2024-01-16 19:06:55 -03:00 committed by GitHub
commit 517f175516
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 901 additions and 13654 deletions

View File

@ -28,9 +28,9 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: "3.11.6" python-version: "3.11.7"
- name: Install project dependencies - name: Install project dependencies
run: | run: |
@ -40,15 +40,15 @@ jobs:
fi fi
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v3
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
queries: security-and-quality queries: security-and-quality
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v2 uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2 uses: github/codeql-action/analyze@v3
with: with:
category: "/language:${{matrix.language}}" category: "/language:${{matrix.language}}"

View File

@ -1,48 +0,0 @@
name: "PyTest & Codecov | Testing and Code Coverage"
on:
push:
branches: [dev]
pull_request:
types: [opened, reopened, edited, synchronize]
workflow_dispatch:
env:
default_branch: dev
jobs:
pytest:
name: pytest
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11.6"
- name: Install project dependencies
run: |
python -m pip install --upgrade pip
if [ -f requirements.txt ];
then pip install -r requirements.txt;
fi
- name: Run pytest
uses: pavelzw/pytest-action@v2
with:
custom-arguments: "--cov --cov-report=xml"
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@ -12,7 +12,7 @@ repos:
- id: check-toml - id: check-toml
- id: check-merge-conflict - id: check-merge-conflict
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 23.11.0 rev: 23.12.1
hooks: hooks:
- id: black - id: black
language_version: python3.11 language_version: python3.11

View File

@ -3,10 +3,7 @@
--- ---
![License: AGPLv3](https://img.shields.io/github/license/revanced/revanced-api) ![License: AGPLv3](https://img.shields.io/github/license/revanced/revanced-api)
[![codecov](https://codecov.io/gh/ReVanced/revanced-api/branch/dev/graph/badge.svg?token=10H8D2CRQO)](https://codecov.io/gh/ReVanced/revanced-api)
[![Build and Publish Docker Image](https://github.com/revanced/revanced-api/actions/workflows/main.yml/badge.svg)](https://github.com/revanced/revanced-api/actions/workflows/main.yml) [![Build and Publish Docker Image](https://github.com/revanced/revanced-api/actions/workflows/main.yml/badge.svg)](https://github.com/revanced/revanced-api/actions/workflows/main.yml)
[![Qodana | Code Quality Scan](https://github.com/revanced/revanced-api/actions/workflows/qodana.yml/badge.svg)](https://github.com/revanced/revanced-api/actions/workflows/qodana.yml)
[![PyTest | Testing and Code Coverage](https://github.com/revanced/revanced-api/actions/workflows/pytest.yml/badge.svg)](https://github.com/revanced/revanced-api/actions/workflows/pytest.yml)
--- ---

View File

@ -5,7 +5,7 @@ import pkgutil
from api.utils.versioning import get_version from api.utils.versioning import get_version
# Dynamically import all modules in the 'api' package, excluding subdirectories # Dynamically import all modules in the 'api' package, excluding subdirectories
versioned_blueprints = {} versioned_blueprints: dict[str, list] = {}
for finder, module_name, ispkg in pkgutil.iter_modules(["api"]): for finder, module_name, ispkg in pkgutil.iter_modules(["api"]):
if not ispkg: if not ispkg:
# Import the module # Import the module
@ -20,7 +20,7 @@ for finder, module_name, ispkg in pkgutil.iter_modules(["api"]):
# Create Blueprint groups for each version # Create Blueprint groups for each version
api = [] api = []
for version, blueprints in versioned_blueprints.items(): for version, blueprints in versioned_blueprints.items():
if version == "old": if version == "old" or version == "v0":
group = Blueprint.group(*blueprints, url_prefix="/") group = Blueprint.group(*blueprints, url_prefix="/")
else: else:
group = Blueprint.group(*blueprints, version=version, url_prefix="/") group = Blueprint.group(*blueprints, version=version, url_prefix="/")

View File

@ -102,13 +102,19 @@ class Contributor(dict):
html_url: str, html_url: str,
contributions: Optional[int] = None, contributions: Optional[int] = None,
bio: Optional[str] = None, bio: Optional[str] = None,
keys: Optional[str] = None,
): ):
match contributions, bio: match contributions, bio, keys:
case None, None: case None, None, None:
dict.__init__( dict.__init__(
self, login=login, avatar_url=avatar_url, html_url=html_url, bio=bio self,
login=login,
avatar_url=avatar_url,
html_url=html_url,
bio=bio,
keys=keys,
) )
case int(_), None: case int(_), None, None:
dict.__init__( dict.__init__(
self, self,
login=login, login=login,
@ -116,7 +122,7 @@ class Contributor(dict):
html_url=html_url, html_url=html_url,
contributions=contributions, contributions=contributions,
) )
case None, str(_): case None, str(_), None:
dict.__init__( dict.__init__(
self, self,
login=login, login=login,
@ -124,7 +130,7 @@ class Contributor(dict):
html_url=html_url, html_url=html_url,
bio=bio, bio=bio,
) )
case int(_), str(_): case int(_), str(_), str(_):
dict.__init__( dict.__init__(
self, self,
login=login, login=login,
@ -132,6 +138,16 @@ class Contributor(dict):
html_url=html_url, html_url=html_url,
contributions=contributions, contributions=contributions,
bio=bio, bio=bio,
keys=keys,
)
case None, str(_), str(_):
dict.__init__(
self,
login=login,
avatar_url=avatar_url,
html_url=html_url,
bio=bio,
keys=keys,
) )
case _: case _:
raise ValueError("Invalid arguments") raise ValueError("Invalid arguments")

View File

@ -1,7 +1,7 @@
import asyncio import asyncio
import os import os
from operator import eq from operator import eq
from typing import Optional from typing import Any, Optional
import ujson import ujson
from aiohttp import ClientResponse from aiohttp import ClientResponse
@ -107,6 +107,11 @@ class Github(Backend):
contributor, contributor,
) )
if team_view:
filter_contributor[
"keys"
] = f"{base_url.replace('api.', '')}/{filter_contributor['login']}.gpg"
return Contributor(**filter_contributor) return Contributor(**filter_contributor)
@staticmethod @staticmethod
@ -372,7 +377,7 @@ class Github(Backend):
list[dict[str, str]]: A JSON object containing the contributors. list[dict[str, str]]: A JSON object containing the contributors.
""" """
def transform(data: dict, repository: GithubRepository) -> list: def transform(data: dict, repository: GithubRepository) -> dict[str, Any]:
"""Transforms a dictionary from the input list into a list of dictionaries with the desired structure. """Transforms a dictionary from the input list into a list of dictionaries with the desired structure.
Args: Args:

View File

@ -2,17 +2,17 @@
This module provides endpoints for pinging the API. This module provides endpoints for pinging the API.
Routes: Routes:
- HEAD /ping: Ping the API. - GET /ping: Ping the API.
""" """
import os 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
ping: Blueprint = Blueprint(os.path.basename(__file__).strip(".py")) ping: Blueprint = Blueprint(os.path.basename(__file__).rstrip(".py"))
@ping.head("/ping") @ping.get("/ping")
@openapi.summary("Ping the API") @openapi.summary("Ping the API")
async def root(request: Request) -> HTTPResponse: async def root(request: Request) -> HTTPResponse:
""" """

View File

@ -1,5 +1,8 @@
# API Configuration # API Configuration
from typing import Any
backend: str = "github" backend: str = "github"
redis: dict[str, str | int] = {"host": "localhost", "port": 6379} redis: dict[str, str | int] = {"host": "localhost", "port": 6379}
hostnames: list[str] = [ hostnames: list[str] = [
@ -137,7 +140,7 @@ links: list[dict[str, str | bool]] = [
}, },
] ]
default_info: dict[str, str | list[str | bool] | bool] = { default_info: dict[str, Any] = {
"name": "ReVanced", "name": "ReVanced",
"about": "ReVanced was born out of Vanced's discontinuation and it is our goal to continue the legacy of what Vanced left behind. Thanks to ReVanced Patcher, it's possible to create long-lasting patches for nearly any Android app. ReVanced's patching system is designed to allow patches to work on new versions of the apps automatically with bare minimum maintenance.", "about": "ReVanced was born out of Vanced's discontinuation and it is our goal to continue the legacy of what Vanced left behind. Thanks to ReVanced Patcher, it's possible to create long-lasting patches for nearly any Android app. ReVanced's patching system is designed to allow patches to work on new versions of the apps automatically with bare minimum maintenance.",
"branding": { "branding": {

View File

@ -1,24 +0,0 @@
import asyncio
import pytest
from sanic import Sanic
from api import api
@pytest.fixture
def app() -> Sanic:
app: Sanic = Sanic("ReVanced-API")
app.blueprint(api)
app.config.TOUCHUP = False
return app
@pytest.fixture(scope="session")
def event_loop():
try:
loop = asyncio.get_running_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
yield loop
loop.close()

View File

@ -22,3 +22,9 @@ ignore_missing_imports = True
[mypy-sanic_testing.*] [mypy-sanic_testing.*]
ignore_missing_imports = True ignore_missing_imports = True
[mypy-fire.*]
ignore_missing_imports = True
[mypy-cytoolz.*]
ignore_missing_imports = True

1808
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -7,34 +7,27 @@ license = "AGPLv3"
readme = "README.md" readme = "README.md"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.11" python = ">=3.11,<3.13"
aiohttp = { version = "^3.8.6", extras = ["speedups"] } aiohttp = { version = "^3.9.1", extras = ["speedups"] }
sanic = { version = "^23.6.0", extras = ["ext"] } sanic = { version = "^23.12.1", extras = ["ext"] }
ujson = "^5.8.0" ujson = "^5.9.0"
asyncstdlib = "^3.10.9" asyncstdlib = "^3.12.0"
pydantic = "^1.10.13"
cytoolz = "^0.12.2" cytoolz = "^0.12.2"
beautifulsoup4 = "^4.12.2" beautifulsoup4 = "^4.12.2"
setuptools = "^69.0.2" lxml = "^5.1.0"
lxml = "^4.9.3" sqlalchemy = "^2.0.25"
mypy = "^1.7.0" sanic-beskar = "^2.3.2"
types-ujson = "^5.8.0.1"
types-aiofiles = "^23.2.0.0"
sanic-testing = "^23.6.0"
pytest-asyncio = "^0.21.1"
types-beautifulsoup4 = "^4.12.0.7"
pytest-md = "^0.2.0"
pytest-emoji = "^0.2.0"
coverage = "^7.3.2"
pytest-cov = "^4.1.0"
pytest = "^7.4.3"
sqlalchemy = "^2.0.23"
sanic-beskar = "^2.2.12"
bson = "^0.5.10" bson = "^0.5.10"
fastpbkdf2 = "^0.2" fastpbkdf2 = "^0.2"
cryptography = "^41.0.5" cryptography = "^41.0.7"
sanic-limiter = { git = "https://github.com/Omegastick/sanic-limiter" } sanic-limiter = { git = "https://github.com/Omegastick/sanic-limiter" }
sentry-sdk = { extras = ["sanic"], version = "^1.35.0" } sentry-sdk = { extras = ["sanic"], version = "^1.39.2" }
[tool.poetry.dev-dependencies]
mypy = "^1.8.0"
types-ujson = "^5.9.0.0"
types-aiofiles = "^23.2.0.20240106"
types-beautifulsoup4 = "^4.12.0.20240106"
[tool.pytest.ini_options] [tool.pytest.ini_options]
asyncio_mode = "auto" asyncio_mode = "auto"

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +0,0 @@
version: "1.0"
linter: jetbrains/qodana-python:2023.1-eap
include:
- name: CheckDependencyLicenses
exclude:
- name: PyInterpreterInspection
- name: PyUnresolvedReferencesInspection

View File

@ -1,85 +1,70 @@
aiodns==3.1.1 ; (sys_platform == "linux" or sys_platform == "darwin") and python_version >= "3.11" and python_version < "4.0" aiodns==3.1.1 ; (sys_platform == "linux" or sys_platform == "darwin") and python_version >= "3.11" and python_version < "3.13"
aiofiles==23.2.1 ; python_version >= "3.11" and python_version < "4.0" aiofiles==23.2.1 ; python_version >= "3.11" and python_version < "3.13"
aiohttp[speedups]==3.9.0 ; python_version >= "3.11" and python_version < "4.0" aiohttp[speedups]==3.9.1 ; python_version >= "3.11" and python_version < "3.13"
aiosignal==1.3.1 ; python_version >= "3.11" and python_version < "4.0" aiosignal==1.3.1 ; python_version >= "3.11" and python_version < "3.13"
anyio==4.0.0 ; python_version >= "3.11" and python_version < "4.0" anyio==4.2.0 ; python_version >= "3.11" and python_version < "3.13"
argon2-cffi==23.1.0 ; python_version >= "3.11" and python_version < "4.0" argon2-cffi==23.1.0 ; python_version >= "3.11" and python_version < "3.13"
argon2-cffi-bindings==21.2.0 ; python_version >= "3.11" and python_version < "4.0" argon2-cffi-bindings==21.2.0 ; python_version >= "3.11" and python_version < "3.13"
asyncstdlib==3.10.9 ; python_version >= "3.11" and python_version < "4.0" asyncstdlib==3.12.0 ; python_version >= "3.11" and python_version < "3.13"
attrs==23.1.0 ; python_version >= "3.11" and python_version < "4.0" attrs==23.2.0 ; python_version >= "3.11" and python_version < "3.13"
beautifulsoup4==4.12.2 ; python_version >= "3.11" and python_version < "4.0" beautifulsoup4==4.12.2 ; python_version >= "3.11" and python_version < "3.13"
brotli==1.1.0 ; platform_python_implementation == "CPython" and python_version >= "3.11" and python_version < "4.0" brotli==1.1.0 ; platform_python_implementation == "CPython" and python_version >= "3.11" and python_version < "3.13"
brotlicffi==1.1.0.0 ; platform_python_implementation != "CPython" and python_version >= "3.11" and python_version < "4.0" brotlicffi==1.1.0.0 ; platform_python_implementation != "CPython" and python_version >= "3.11" and python_version < "3.13"
bson==0.5.10 ; python_version >= "3.11" and python_version < "4.0" bson==0.5.10 ; python_version >= "3.11" and python_version < "3.13"
certifi==2023.11.17 ; python_version >= "3.11" and python_version < "4.0" certifi==2023.11.17 ; python_version >= "3.11" and python_version < "3.13"
cffi==1.16.0 ; python_version >= "3.11" and python_version < "4.0" cffi==1.16.0 ; python_version >= "3.11" and python_version < "3.13"
colorama==0.4.6 ; python_version >= "3.11" and python_version < "4.0" and sys_platform == "win32" cryptography==41.0.7 ; python_version >= "3.11" and python_version < "3.13"
coverage==7.3.2 ; python_version >= "3.11" and python_version < "4.0" cytoolz==0.12.2 ; python_version >= "3.11" and python_version < "3.13"
coverage[toml]==7.3.2 ; python_version >= "3.11" and python_version < "4.0" deprecated==1.2.14 ; python_version >= "3.11" and python_version < "3.13"
cryptography==41.0.5 ; python_version >= "3.11" and python_version < "4.0" fastpbkdf2==0.2 ; python_version >= "3.11" and python_version < "3.13"
cytoolz==0.12.2 ; python_version >= "3.11" and python_version < "4.0" frozenlist==1.4.1 ; python_version >= "3.11" and python_version < "3.13"
deprecated==1.2.14 ; python_version >= "3.11" and python_version < "4.0" greenlet==3.0.3 ; python_version >= "3.11" and python_version < "3.13" and (platform_machine == "aarch64" or platform_machine == "ppc64le" or platform_machine == "x86_64" or platform_machine == "amd64" or platform_machine == "AMD64" or platform_machine == "win32" or platform_machine == "WIN32")
fastpbkdf2==0.2 ; python_version >= "3.11" and python_version < "4.0" html5tagger==1.3.0 ; python_version >= "3.11" and python_version < "3.13"
frozenlist==1.4.0 ; python_version >= "3.11" and python_version < "4.0" httptools==0.6.1 ; python_version >= "3.11" and python_version < "3.13"
greenlet==3.0.1 ; python_version >= "3.11" and python_version < "4.0" and platform_machine == "aarch64" or python_version >= "3.11" and python_version < "4.0" and platform_machine == "ppc64le" or python_version >= "3.11" and python_version < "4.0" and platform_machine == "x86_64" or python_version >= "3.11" and python_version < "4.0" and platform_machine == "amd64" or python_version >= "3.11" and python_version < "4.0" and platform_machine == "AMD64" or python_version >= "3.11" and python_version < "4.0" and platform_machine == "win32" or python_version >= "3.11" and python_version < "4.0" and platform_machine == "WIN32" idna==3.6 ; python_version >= "3.11" and python_version < "3.13"
h11==0.14.0 ; python_version >= "3.11" and python_version < "4.0" importlib-resources==6.1.1 ; python_version >= "3.11" and python_version < "3.13"
html5tagger==1.3.0 ; python_version >= "3.11" and python_version < "4.0" iso8601==2.1.0 ; python_version >= "3.11" and python_version < "3.13"
httpcore==1.0.2 ; python_version >= "3.11" and python_version < "4.0" jinja2==3.1.3 ; python_version >= "3.11" and python_version < "3.13"
httptools==0.6.1 ; python_version >= "3.11" and python_version < "4.0" limits==3.7.0 ; python_version >= "3.11" and python_version < "3.13"
httpx==0.25.1 ; python_version >= "3.11" and python_version < "4.0" lxml==5.1.0 ; python_version >= "3.11" and python_version < "3.13"
idna==3.4 ; python_version >= "3.11" and python_version < "4.0" markupsafe==2.1.3 ; python_version >= "3.11" and python_version < "3.13"
importlib-resources==6.1.1 ; python_version >= "3.11" and python_version < "4.0" multidict==6.0.4 ; python_version >= "3.11" and python_version < "3.13"
iniconfig==2.0.0 ; python_version >= "3.11" and python_version < "4.0" mypy==1.8.0 ; python_version >= "3.11" and python_version < "3.13"
iso8601==2.1.0 ; python_version >= "3.11" and python_version < "4.0" mypy-extensions==1.0.0 ; python_version >= "3.11" and python_version < "3.13"
jinja2==3.1.2 ; python_version >= "3.11" and python_version < "4.0" packaging==23.2 ; python_version >= "3.11" and python_version < "3.13"
limits==3.6.0 ; python_version >= "3.11" and python_version < "4.0" passlib==1.7.4 ; python_version >= "3.11" and python_version < "3.13"
lxml==4.9.3 ; python_version >= "3.11" and python_version < "4.0" pendulum==3.0.0 ; python_version >= "3.11" and python_version < "3.13"
markupsafe==2.1.3 ; python_version >= "3.11" and python_version < "4.0" py-buzz==4.1.0 ; python_version >= "3.11" and python_version < "3.13"
multidict==6.0.4 ; python_version >= "3.11" and python_version < "4.0" pycares==4.4.0 ; (sys_platform == "linux" or sys_platform == "darwin") and python_version >= "3.11" and python_version < "3.13"
mypy==1.7.0 ; python_version >= "3.11" and python_version < "4.0" pycparser==2.21 ; python_version >= "3.11" and python_version < "3.13"
mypy-extensions==1.0.0 ; python_version >= "3.11" and python_version < "4.0" pycryptodomex==3.20.0 ; python_version >= "3.11" and python_version < "3.13"
packaging==23.2 ; python_version >= "3.11" and python_version < "4.0" pyjwt==2.8.0 ; python_version >= "3.11" and python_version < "3.13"
passlib==1.7.4 ; python_version >= "3.11" and python_version < "4.0" pyseto==1.7.7 ; python_version >= "3.11" and python_version < "3.13"
pendulum==2.1.2 ; python_version >= "3.11" and python_version < "4.0" pytest==7.4.4 ; python_version >= "3.11" and python_version < "3.13"
pluggy==1.3.0 ; python_version >= "3.11" and python_version < "4.0" pytest-asyncio==0.23.3 ; python_version >= "3.11" and python_version < "3.13"
py-buzz==4.1.0 ; python_version >= "3.11" and python_version < "4.0" pytest-cov==4.1.0 ; python_version >= "3.11" and python_version < "3.13"
pycares==4.4.0 ; (sys_platform == "linux" or sys_platform == "darwin") and python_version >= "3.11" and python_version < "4.0" pytest-emoji==0.2.0 ; python_version >= "3.11" and python_version < "3.13"
pycparser==2.21 ; python_version >= "3.11" and python_version < "4.0" pytest-md==0.2.0 ; python_version >= "3.11" and python_version < "3.13"
pycryptodomex==3.19.0 ; python_version >= "3.11" and python_version < "4.0" python-dateutil==2.8.2 ; python_version >= "3.11" and python_version < "3.13"
pydantic==1.10.13 ; python_version >= "3.11" and python_version < "4.0" pyyaml==6.0.1 ; python_version >= "3.11" and python_version < "3.13"
pyjwt==2.8.0 ; python_version >= "3.11" and python_version < "4.0" sanic==23.12.1 ; python_version >= "3.11" and python_version < "3.13"
pyseto==1.7.6 ; python_version >= "3.11" and python_version < "4.0" sanic-beskar==2.3.2 ; python_version >= "3.11" and python_version < "3.13"
pytest==7.4.3 ; python_version >= "3.11" and python_version < "4.0" sanic-ext==23.12.0 ; python_version >= "3.11" and python_version < "3.13"
pytest-asyncio==0.21.1 ; python_version >= "3.11" and python_version < "4.0" sanic-limiter @ git+https://github.com/Omegastick/sanic-limiter@843e13144aa21d843ce212a7c1db31b72ce8a103 ; python_version >= "3.11" and python_version < "3.13"
pytest-cov==4.1.0 ; python_version >= "3.11" and python_version < "4.0" sanic-routing==23.12.0 ; python_version >= "3.11" and python_version < "3.13"
pytest-emoji==0.2.0 ; python_version >= "3.11" and python_version < "4.0" sanic-testing==23.12.0 ; python_version >= "3.11" and python_version < "3.13"
pytest-md==0.2.0 ; python_version >= "3.11" and python_version < "4.0" sanic[ext]==23.12.1 ; python_version >= "3.11" and python_version < "3.13"
python-dateutil==2.8.2 ; python_version >= "3.11" and python_version < "4.0" sentry-sdk[sanic]==1.39.2 ; python_version >= "3.11" and python_version < "3.13"
pytzdata==2020.1 ; python_version >= "3.11" and python_version < "4.0" six==1.16.0 ; python_version >= "3.11" and python_version < "3.13"
pyyaml==6.0.1 ; python_version >= "3.11" and python_version < "4.0" soupsieve==2.5 ; python_version >= "3.11" and python_version < "3.13"
sanic==23.6.0 ; python_version >= "3.11" and python_version < "4.0" sqlalchemy==2.0.25 ; python_version >= "3.11" and python_version < "3.13"
sanic-beskar==2.2.12 ; python_version >= "3.11" and python_version < "4.0" toolz==0.12.0 ; python_version >= "3.11" and python_version < "3.13"
sanic-ext==23.6.0 ; python_version >= "3.11" and python_version < "4.0" tracerite==1.1.1 ; python_version >= "3.11" and python_version < "3.13"
sanic-limiter @ git+https://github.com/Omegastick/sanic-limiter ; python_version >= "3.11" and python_version < "4.0" typing-extensions==4.9.0 ; python_version >= "3.11" and python_version < "3.13"
sanic-routing==23.6.0 ; python_version >= "3.11" and python_version < "4.0" tzdata==2023.4 ; python_version >= "3.11" and python_version < "3.13"
sanic-testing==23.6.0 ; python_version >= "3.11" and python_version < "4.0" ujson==5.9.0 ; python_version >= "3.11" and python_version < "3.13"
sanic[ext]==23.6.0 ; python_version >= "3.11" and python_version < "4.0" urllib3==2.1.0 ; python_version >= "3.11" and python_version < "3.13"
sentry-sdk[sanic]==1.36.0 ; python_version >= "3.11" and python_version < "4.0" uvloop==0.19.0 ; sys_platform != "win32" and implementation_name == "cpython" and python_version >= "3.11" and python_version < "3.13"
setuptools==68.2.2 ; python_version >= "3.11" and python_version < "4.0" websockets==12.0 ; python_version >= "3.11" and python_version < "3.13"
six==1.16.0 ; python_version >= "3.11" and python_version < "4.0" wrapt==1.16.0 ; python_version >= "3.11" and python_version < "3.13"
sniffio==1.3.0 ; python_version >= "3.11" and python_version < "4.0" yarl==1.9.4 ; python_version >= "3.11" and python_version < "3.13"
soupsieve==2.5 ; python_version >= "3.11" and python_version < "4.0"
sqlalchemy==2.0.23 ; python_version >= "3.11" and python_version < "4.0"
toolz==0.12.0 ; python_version >= "3.11" and python_version < "4.0"
tracerite==1.1.1 ; python_version >= "3.11" and python_version < "4.0"
types-aiofiles==23.2.0.0 ; python_version >= "3.11" and python_version < "4.0"
types-beautifulsoup4==4.12.0.7 ; python_version >= "3.11" and python_version < "4.0"
types-html5lib==1.1.11.15 ; python_version >= "3.11" and python_version < "4.0"
types-ujson==5.8.0.1 ; python_version >= "3.11" and python_version < "4.0"
typing-extensions==4.8.0 ; python_version >= "3.11" and python_version < "4.0"
ujson==5.8.0 ; python_version >= "3.11" and python_version < "4.0"
urllib3==2.1.0 ; python_version >= "3.11" and python_version < "4.0"
uvloop==0.19.0 ; sys_platform != "win32" and implementation_name == "cpython" and python_version >= "3.11" and python_version < "4.0"
websockets==12.0 ; python_version >= "3.11" and python_version < "4.0"
wrapt==1.16.0 ; python_version >= "3.11" and python_version < "4.0"
yarl==1.9.3 ; python_version >= "3.11" and python_version < "4.0"

View File

View File

@ -1,17 +0,0 @@
# import pytest
# from sanic import Sanic
# from api.models.appinfo import AppInfoModel
# from config import api_version, apkdl_testing_package
# # socials
# @pytest.mark.asyncio
# async def test_socials(app: Sanic):
# _, response = await app.asgi_client.get(
# f"/{api_version}/app/info/{apkdl_testing_package}"
# )
# assert response.status == 200
# assert AppInfoModel(app_info=response.json["app_info"])

View File

@ -1,22 +0,0 @@
import pytest
from sanic import Sanic
from api.models.compat import ToolsResponseModel, ContributorsResponseModel
# compatibility layer
@pytest.mark.asyncio
async def test_compat_tools(app: Sanic):
_, response = await app.asgi_client.get(f"/tools")
assert response.status == 200
assert ToolsResponseModel(tools=[tool for tool in response.json["tools"]])
@pytest.mark.asyncio
async def test_compat_contributors(app: Sanic):
_, response = await app.asgi_client.get(f"/contributors")
assert response.status == 200
assert ContributorsResponseModel(
repositories=[repo for repo in response.json["repositories"]]
)

View File

@ -1,15 +0,0 @@
import pytest
from sanic import Sanic
from api.models.donations import DonationsResponseModel
from config import api_version
# donations
@pytest.mark.asyncio
async def test_donations(app: Sanic):
_, response = await app.asgi_client.get(f"/{api_version}/donations")
assert response.status == 200
assert DonationsResponseModel(**response.json)

View File

@ -1,110 +0,0 @@
import pytest
from sanic import Sanic
from sanic_testing.testing import TestingResponse
from api.models.github import (
AssetFields,
MetadataFields,
PatchesResponseFields,
ReleaseListResponseModel,
ReleaseResponseModel,
SingleReleaseResponseModel,
ContributorsFields,
ContributorsModel,
PatchesModel,
TeamMemberFields,
TeamMembersModel,
)
from config import github_testing_repository, github_testing_tag, api_version
# utils
async def __test_single_release(response: TestingResponse) -> bool:
try:
assert response.status == 200
assert SingleReleaseResponseModel(
release=ReleaseResponseModel(
metadata=MetadataFields(**response.json["release"]["metadata"]),
assets=[
AssetFields(**asset) for asset in response.json["release"]["assets"]
],
)
)
return True
except AssertionError:
return False
# github
@pytest.mark.asyncio
async def test_releases(app: Sanic):
_, response = await app.asgi_client.get(
f"/{api_version}/{github_testing_repository}/releases"
)
assert response.status == 200
assert ReleaseListResponseModel(
releases=[
ReleaseResponseModel(
metadata=MetadataFields(**release["metadata"]),
assets=[AssetFields(**asset) for asset in release["assets"]],
)
for release in response.json["releases"]
]
)
@pytest.mark.asyncio
async def test_latest_release(app: Sanic):
_, response = await app.asgi_client.get(
f"/{api_version}/{github_testing_repository}/releases/latest"
)
_, response_dev = await app.asgi_client.get(
f"/{api_version}/{github_testing_repository}/releases/latest?dev=true"
)
assert await __test_single_release(response)
assert await __test_single_release(response_dev)
@pytest.mark.asyncio
async def test_release_by_tag(app: Sanic):
_, response = await app.asgi_client.get(
f"/{api_version}/{github_testing_repository}/releases/tag/{github_testing_tag}"
)
assert await __test_single_release(response)
@pytest.mark.asyncio
async def test_contributors(app: Sanic):
_, response = await app.asgi_client.get(
f"/{api_version}/{github_testing_repository}/contributors"
)
assert ContributorsModel(
contributors=[
ContributorsFields(**contributor)
for contributor in response.json["contributors"]
]
)
@pytest.mark.asyncio
async def test_patches(app: Sanic):
_, response = await app.asgi_client.get(
f"/{api_version}/patches/{github_testing_tag}"
)
assert PatchesModel(
patches=[PatchesResponseFields(**patch) for patch in response.json["patches"]]
)
@pytest.mark.asyncio
async def test_team_members(app: Sanic):
_, response = await app.asgi_client.get(f"/{api_version}/team/members")
assert TeamMembersModel(
members=[TeamMemberFields(**member) for member in response.json["members"]]
)

View File

@ -1,16 +0,0 @@
import pytest
from sanic import Sanic
from api.models.info import InfoResponseModel
from config import api_version
# info
@pytest.mark.asyncio
async def test_info(app: Sanic):
_, response = await app.asgi_client.get(f"/{api_version}/info")
assert response.status == 200
print(response.json)
assert InfoResponseModel(**response.json)

View File

@ -1,12 +0,0 @@
import pytest
from sanic import Sanic
from config import api_version
# ping
@pytest.mark.asyncio
async def test_ping(app: Sanic):
_, response = await app.asgi_client.head(f"/{api_version}/ping")
assert response.status == 204

View File

@ -1,15 +0,0 @@
import pytest
from sanic import Sanic
from api.models.socials import SocialsResponseModel
from config import api_version
# socials
@pytest.mark.asyncio
async def test_socials(app: Sanic):
_, response = await app.asgi_client.get(f"/{api_version}/socials")
assert response.status == 200
assert SocialsResponseModel(**response.json)