feat(v1-api): support api v1
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
from .achievement import UserAchievement, UserAchievementResp
|
||||
from .auth import OAuthClient, OAuthToken
|
||||
from .auth import OAuthClient, OAuthToken, V1APIKeys
|
||||
from .beatmap import (
|
||||
Beatmap,
|
||||
BeatmapResp,
|
||||
@@ -109,6 +109,7 @@ __all__ = [
|
||||
"UserResp",
|
||||
"UserStatistics",
|
||||
"UserStatisticsResp",
|
||||
"V1APIKeys",
|
||||
]
|
||||
|
||||
for i in __all__:
|
||||
|
||||
@@ -5,7 +5,15 @@ from typing import TYPE_CHECKING
|
||||
from app.models.model import UTCBaseModel
|
||||
|
||||
from sqlalchemy import Column, DateTime
|
||||
from sqlmodel import JSON, BigInteger, Field, ForeignKey, Relationship, SQLModel, Text
|
||||
from sqlmodel import (
|
||||
JSON,
|
||||
BigInteger,
|
||||
Field,
|
||||
ForeignKey,
|
||||
Relationship,
|
||||
SQLModel,
|
||||
Text,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .lazer_user import User
|
||||
@@ -41,3 +49,13 @@ class OAuthClient(SQLModel, table=True):
|
||||
owner_id: int = Field(
|
||||
sa_column=Column(BigInteger, ForeignKey("lazer_users.id"), index=True)
|
||||
)
|
||||
|
||||
|
||||
class V1APIKeys(SQLModel, table=True):
|
||||
__tablename__ = "v1_api_keys" # pyright: ignore[reportAssignmentType]
|
||||
id: int | None = Field(default=None, primary_key=True)
|
||||
name: str = Field(max_length=100, index=True)
|
||||
key: str = Field(default_factory=secrets.token_hex, index=True)
|
||||
owner_id: int = Field(
|
||||
sa_column=Column(BigInteger, ForeignKey("lazer_users.id"), index=True)
|
||||
)
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
import hashlib
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from app.calculator import calculate_beatmap_attribute
|
||||
from app.config import settings
|
||||
from app.models.beatmap import BeatmapRankStatus
|
||||
from app.models.beatmap import BeatmapAttributes, BeatmapRankStatus
|
||||
from app.models.mods import APIMod
|
||||
from app.models.score import MODE_TO_INT, GameMode
|
||||
|
||||
from .beatmap_playcounts import BeatmapPlaycounts
|
||||
from .beatmapset import Beatmapset, BeatmapsetResp
|
||||
|
||||
from redis.asyncio import Redis
|
||||
from sqlalchemy import Column, DateTime
|
||||
from sqlmodel import VARCHAR, Field, Relationship, SQLModel, col, func, select
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
@@ -195,3 +200,24 @@ class BeatmapResp(BeatmapBase):
|
||||
)
|
||||
).one()
|
||||
return cls.model_validate(beatmap_)
|
||||
|
||||
|
||||
async def calculate_beatmap_attributes(
|
||||
beatmap_id: int,
|
||||
ruleset: GameMode,
|
||||
mods_: list[APIMod],
|
||||
redis: Redis,
|
||||
fetcher: "Fetcher",
|
||||
):
|
||||
key = (
|
||||
f"beatmap:{beatmap_id}:{ruleset}:"
|
||||
f"{hashlib.md5(str(mods_).encode()).hexdigest()}:attributes"
|
||||
)
|
||||
if await redis.exists(key):
|
||||
return BeatmapAttributes.model_validate_json(await redis.get(key)) # pyright: ignore[reportArgumentType]
|
||||
resp = await fetcher.get_or_fetch_beatmap_raw(redis, beatmap_id)
|
||||
attr = await asyncio.get_event_loop().run_in_executor(
|
||||
None, calculate_beatmap_attribute, resp, ruleset, mods_
|
||||
)
|
||||
await redis.set(key, attr.model_dump_json())
|
||||
return attr
|
||||
|
||||
Reference in New Issue
Block a user