diff --git a/Dockerfile.frontend b/Dockerfile.frontend index d6ec0f0..e93dcae 100644 --- a/Dockerfile.frontend +++ b/Dockerfile.frontend @@ -8,7 +8,7 @@ RUN bun install --prod --frozen-lockfile COPY frontend . RUN bun run build -FROM caddy:2.7-alpine +FROM caddy:2.8-alpine WORKDIR /app diff --git a/backend/api/v1/articles.py b/backend/api/v1/articles.py index f91ca5c..0f6e727 100644 --- a/backend/api/v1/articles.py +++ b/backend/api/v1/articles.py @@ -1,7 +1,6 @@ from datetime import datetime, timedelta -from typing import Annotated, Any, Dict, Optional, cast +from typing import Annotated, Dict, Optional -from bson import ObjectId from jkit.article import Article from jkit.constants import ARTICLE_SLUG_REGEX from jkit.exceptions import ResourceUnavailableError @@ -19,8 +18,10 @@ success, ) +from models.jianshu.article_earning_ranking_record import ( + ArticleEarningRankingRecordDocument, +) from utils.config import config -from utils.db import ARTICLE_FP_RANK_COLLECTION # fmt: off splitter = AbilityJiebaPossegSplitterV1( @@ -36,62 +37,47 @@ async def get_latest_onrank_record( - author_url: str, *, minimum_ranking: Optional[int] = None -) -> Optional[Dict[str, Any]]: - cursor = ( - ARTICLE_FP_RANK_COLLECTION.find( - { - "author.url": author_url, - "ranking": { - "$lte": minimum_ranking if minimum_ranking else 100, - }, - } - ) - .sort("date", -1) - .limit(1) + author_slug: str, *, minimum_ranking: Optional[int] = None +) -> Optional[ArticleEarningRankingRecordDocument]: + # TODO + return await ArticleEarningRankingRecordDocument.find_one( + { + "authorSlug": author_slug, + "ranking": { # type: ignore + "$lte": minimum_ranking if minimum_ranking else 100, + }, + }, + sort={"date": "DESC"}, ) - try: - return await cursor.next() - except StopAsyncIteration: - return None - async def get_pervious_onrank_record( - onrank_record: Dict[str, Any], minimum_ranking: Optional[int] = None -) -> Optional[Dict[str, Any]]: - cursor = ( - ARTICLE_FP_RANK_COLLECTION.find( - { - "_id": {"$lt": ObjectId(onrank_record["_id"])}, - "author.url": onrank_record["author"]["url"], - "ranking": { - "$lte": minimum_ranking if minimum_ranking else 100, - }, - } - ) - .sort("_id", -1) - .limit(1) + onrank_record: ArticleEarningRankingRecordDocument, + minimum_ranking: Optional[int] = None, +) -> Optional[ArticleEarningRankingRecordDocument]: + return await ArticleEarningRankingRecordDocument.find_one( + { + "_id": {"$lt": onrank_record._id}, + "authorSlug": onrank_record.author_slug, + "ranking": { # type: ignore + "$lte": minimum_ranking if minimum_ranking else 100, + }, + }, + sort={"_id": "DESC"}, ) - try: - return await cursor.next() - except StopAsyncIteration: - return None - -async def caculate_next_can_recommend_date(author_url: str) -> Optional[datetime]: - counted_article_urls = set() +async def get_earliest_can_recommend_date(author_slug: str) -> Optional[datetime]: + counted_article_slugs = set() latest_onrank_record = await get_latest_onrank_record( - author_url, minimum_ranking=85 + author_slug, minimum_ranking=85 ) if not latest_onrank_record: - # 作者没有上榜文章,或全部上榜文章均低于 85 名 return None - interval_days = 10 if latest_onrank_record["ranking"] <= 30 else 7 - counted_article_urls.add(latest_onrank_record["article"]["url"]) + interval_days = 10 if latest_onrank_record.ranking <= 30 else 7 + counted_article_slugs.add(latest_onrank_record.article.slug) now_record = latest_onrank_record while True: @@ -99,25 +85,23 @@ async def caculate_next_can_recommend_date(author_url: str) -> Optional[datetime now_record, minimum_ranking=85 ) if not pervious_record: - # 没有更多文章 - return cast(datetime, now_record["date"]) + timedelta(days=interval_days) - if pervious_record["article"]["url"] in counted_article_urls: - # 该文章之前计算过间隔 + return latest_onrank_record.date + timedelta(days=interval_days) + if pervious_record.article.slug in counted_article_slugs: now_record = pervious_record continue - counted_article_urls.add(pervious_record["article"]["url"]) + counted_article_slugs.add(pervious_record.article.slug) if ( - now_record["ranking"] <= 30 - and (now_record["date"] - pervious_record["date"]).days + 1 >= 10 + now_record.ranking <= 30 + and (now_record.date - pervious_record.date).days + 1 >= 10 ) or ( - now_record["ranking"] > 30 - and (now_record["date"] - pervious_record["date"]).days + 1 >= 7 + now_record.ranking > 30 + and (now_record.date - pervious_record.date).days + 1 >= 7 ): - return cast(datetime, now_record["date"]) + timedelta(days=interval_days) + return latest_onrank_record.date + timedelta(days=interval_days) - if pervious_record["ranking"] <= 30: + if pervious_record.ranking <= 30: interval_days += 10 else: interval_days += 7 @@ -231,10 +215,10 @@ async def get_LP_recommend_check_handler( # noqa: N802 article_info = await article.info - author_url = article_info.author_info.to_user_obj().url + author_slug = article_info.author_info.to_user_obj().slug article_title = article_info.title article_fp_reward = article_info.earned_fp_amount - article_next_can_recommend_date = await caculate_next_can_recommend_date(author_url) + article_next_can_recommend_date = await get_earliest_can_recommend_date(author_slug) can_recommend_now = article_fp_reward < 35 and ( not article_next_can_recommend_date diff --git a/backend/api/v1/jpep/ftn_macket.py b/backend/api/v1/jpep/ftn_macket.py index a0c057a..cce9d84 100644 --- a/backend/api/v1/jpep/ftn_macket.py +++ b/backend/api/v1/jpep/ftn_macket.py @@ -1,6 +1,6 @@ from asyncio import gather from datetime import datetime, timedelta -from typing import Annotated, Any, Dict, Literal, Optional +from typing import Annotated, Dict, Literal, Optional from jkit.jpep.platform_settings import PlatformSettings from litestar import Response, Router, get @@ -13,7 +13,7 @@ ) from sspeedup.time_helper import get_start_time -from utils.db import JPEP_FTN_MACKET_COLLECTION +from models.jpep.ftn_trade_order import FTNTradeOrderDocument RANGE_TO_TIMEDELTA: Dict[str, timedelta] = { "24h": timedelta(hours=24), @@ -32,78 +32,58 @@ async def get_data_update_time() -> datetime: - result = ( - await JPEP_FTN_MACKET_COLLECTION.find( - {}, - { - "_id": 0, - "fetch_time": 1, - }, - ) - .sort("fetch_time", -1) - .limit(1) - .next() - ) - return result["fetch_time"] + latest_record = await FTNTradeOrderDocument.find_one(sort={"fetchTime": "DESC"}) + + return latest_record.fetch_time # type: ignore -async def get_latest_order(type_: Literal["buy", "sell"]) -> Optional[Dict[str, Any]]: +async def get_latest_order( + type_: Literal["buy", "sell"], +) -> Optional[FTNTradeOrderDocument]: time = await get_data_update_time() - try: - return ( - await JPEP_FTN_MACKET_COLLECTION.find( - { - "fetch_time": time, - "trade_type": type_, - "amount.tradable": {"$ne": 0}, - } - ) - .sort("price", 1 if type_ == "buy" else -1) - .limit(1) - .next() - ) - except StopAsyncIteration: # 该侧没有挂单 - return None + + return await FTNTradeOrderDocument.find_one( + {"fetchTime": time, "type": type_, "amount.tradable": {"$ne": 0}}, + sort={"price": "ASC" if type_ == "buy" else "DESC"}, + ) async def get_current_amount(type_: Literal["buy", "sell"]) -> Optional[int]: time = await get_data_update_time() - try: - result = await JPEP_FTN_MACKET_COLLECTION.aggregate( - [ - { - "$match": { - "fetch_time": time, - "trade_type": type_, - } - }, - { - "$group": { - "_id": None, - "sum": { - "$sum": "$amount.tradable", - }, + result = await FTNTradeOrderDocument.aggregate_one( + [ + { + "$match": { + "fetchTime": time, + "type": type_, + } + }, + { + "$group": { + "_id": None, + "sum": { + "$sum": "$amount.tradable", }, }, - ] - ).next() - return result["sum"] - except StopIteration: # 该侧没有挂单 - return None + }, + ] + ) + + return result["sum"] if result else None async def get_price_history( type_: Literal["buy", "sell"], td: timedelta, time_unit: str ) -> Dict[datetime, float]: - result = JPEP_FTN_MACKET_COLLECTION.aggregate( + result = FTNTradeOrderDocument.aggregate_many( [ { "$match": { - "trade_type": type_, - "fetch_time": { + "fetchTime": { "$gte": get_start_time(td), }, + "type": type_, }, }, { @@ -111,13 +91,13 @@ async def get_price_history( "_id": ( { "$dateTrunc": { - "date": "$fetch_time", + "date": "$fetchTime", "unit": time_unit, }, } ) if time_unit != "minute" - else "$fetch_time", + else "$fetchTime", "price": { "$min" if type_ == "buy" else "$max": "$price", }, @@ -137,19 +117,19 @@ async def get_price_history( async def get_amount_history( type_: Literal["buy", "sell"], td: timedelta, time_unit: str ) -> Dict[datetime, float]: - result = JPEP_FTN_MACKET_COLLECTION.aggregate( + result = FTNTradeOrderDocument.aggregate_many( [ { "$match": { - "trade_type": type_, - "fetch_time": { + "fetchTime": { "$gte": get_start_time(td), }, + "type": type_, }, }, { "$group": { - "_id": "$fetch_time", + "_id": "$fetchTime", "amount": { "$sum": "$amount.tradable", }, @@ -189,12 +169,12 @@ async def get_current_amount_distribution( ) -> Dict[float, int]: time = await get_data_update_time() - result = JPEP_FTN_MACKET_COLLECTION.aggregate( + result = FTNTradeOrderDocument.aggregate_many( [ { "$match": { - "fetch_time": time, - "trade_type": type_, + "fetchTime": time, + "type": type_, }, }, { @@ -272,8 +252,8 @@ async def get_current_price_handler() -> Response: get_latest_order("buy"), get_latest_order("sell") ) - buy_price = buy_order["price"] if buy_order else None - sell_price = sell_order["price"] if sell_order else None + buy_price = buy_order.price if buy_order else None + sell_price = sell_order.price if sell_order else None return success( data=GetCurrentPriceResponse( diff --git a/backend/api/v1/lottery.py b/backend/api/v1/lottery.py index 3c8f2a1..4beaa38 100644 --- a/backend/api/v1/lottery.py +++ b/backend/api/v1/lottery.py @@ -2,17 +2,22 @@ from datetime import datetime, timedelta from typing import Annotated, Dict, List, Literal, Optional +from jkit.identifier_convert import user_slug_to_url from litestar import Response, Router, get from litestar.params import Parameter +from litestar.status_codes import HTTP_500_INTERNAL_SERVER_ERROR from msgspec import Struct from sspeedup.api.litestar import ( RESPONSE_STRUCT_CONFIG, + Code, + fail, generate_response_spec, success, ) from sspeedup.time_helper import get_start_time -from utils.db import LOTTERY_COLLECTION +from models.jianshu.lottery_win_record import LotteryWinRecordDocument +from models.jianshu.user import UserDocument REWARD_NAMES: List[str] = [ "收益加成卡100", @@ -36,7 +41,7 @@ async def get_summary_wins_count(td: Optional[timedelta]) -> Dict[str, int]: - db_result = LOTTERY_COLLECTION.aggregate( + db_result = LotteryWinRecordDocument.aggregate_many( [ { "$match": { @@ -47,7 +52,7 @@ async def get_summary_wins_count(td: Optional[timedelta]) -> Dict[str, int]: }, { "$group": { - "_id": "$reward_name", + "_id": "$awardName", "count": { "$sum": 1, }, @@ -66,10 +71,10 @@ async def get_summary_winners_count(td: Optional[timedelta]) -> Dict[str, int]: for reward_name in REWARD_NAMES: result[reward_name] = len( - await LOTTERY_COLLECTION.distinct( - "user.id", + await LotteryWinRecordDocument.get_collection().distinct( + "userSlug", { - "reward_name": reward_name, + "awardName": reward_name, "time": { "$gte": get_start_time(td), }, @@ -123,7 +128,7 @@ def get_summary_rarity(wins_count: Dict[str, int]) -> Dict[str, float]: async def get_rewards_wins_history( td: timedelta, time_unit: str ) -> Dict[datetime, int]: - result = LOTTERY_COLLECTION.aggregate( + result = LotteryWinRecordDocument.aggregate_many( [ { "$match": { @@ -175,7 +180,7 @@ async def get_rewards_handler() -> Response: ) -class GetRecordItem(Struct, **RESPONSE_STRUCT_CONFIG): +class GetRecordsItem(Struct, **RESPONSE_STRUCT_CONFIG): time: datetime reward_name: str user_name: str @@ -183,7 +188,7 @@ class GetRecordItem(Struct, **RESPONSE_STRUCT_CONFIG): class GetRecordsResponse(Struct, **RESPONSE_STRUCT_CONFIG): - records: List[GetRecordItem] + records: List[GetRecordsItem] @get( @@ -200,28 +205,32 @@ async def get_records_handler( Optional[List[str]], Parameter(description="排除奖项列表", max_items=10) ] = None, ) -> Response: - result = ( - LOTTERY_COLLECTION.find( - { - "reward_name": { - "$nin": excluded_awards if excluded_awards else [], - }, - } - ) - .sort("time", -1) - .skip(offset) - .limit(limit) - ) + records: List[GetRecordsItem] = [] + async for item in LotteryWinRecordDocument.find_many( + { + "award_name": { + "$nin": excluded_awards if excluded_awards else [], + }, + }, + sort={"time": "DESC"}, + skip=offset, + limit=limit, + ): + user = await UserDocument.find_one({"slug": item.user_slug}) + if not user: + return fail( + http_code=HTTP_500_INTERNAL_SERVER_ERROR, + api_code=Code.UNKNOWN_SERVER_ERROR, + ) - records: List[GetRecordItem] = [ - GetRecordItem( - time=item["time"], - reward_name=item["reward_name"], - user_name=item["user"]["name"], - user_url=item["user"]["url"], + records.append( + GetRecordsItem( + time=item.time, + reward_name=item.award_name, + user_name=user.name or item.user_slug, + user_url=user_slug_to_url(item.user_slug), + ) ) - async for item in result - ] return success( data=GetRecordsResponse( diff --git a/backend/api/v1/status.py b/backend/api/v1/status.py index e5a126a..1e4dc17 100644 --- a/backend/api/v1/status.py +++ b/backend/api/v1/status.py @@ -4,8 +4,8 @@ from litestar import Response, Router, get from litestar.params import Parameter from litestar.status_codes import HTTP_400_BAD_REQUEST -from motor.core import AgnosticCollection from msgspec import Struct +from sshared.mongo import Document from sspeedup.api.code import Code from sspeedup.api.litestar import ( RESPONSE_STRUCT_CONFIG, @@ -14,47 +14,39 @@ success, ) -from utils.config import config -from utils.db import ( - ARTICLE_FP_RANK_COLLECTION, - JPEP_FTN_MACKET_COLLECTION, - LOTTERY_COLLECTION, - LP_COLLECTIONS_COLLECTION, +from models.jianshu.article_earning_ranking_record import ( + ArticleEarningRankingRecordDocument, ) +from models.jianshu.lottery_win_record import LotteryWinRecordDocument +from models.jpep.ftn_trade_order import FTNTradeOrderDocument +from utils.config import config from utils.tools_config import TOOLS_CONFIG, ToolStatus -COLLECTION_STRING_TO_OBJ: Dict[str, AgnosticCollection] = { - "article_FP_rank": ARTICLE_FP_RANK_COLLECTION, - "lottery": LOTTERY_COLLECTION, - "LP_collections": LP_COLLECTIONS_COLLECTION, - "JPEP_FTN_market": JPEP_FTN_MACKET_COLLECTION, +COLLECTION_STRING_TO_OBJ: Dict[str, type[Document]] = { + "article_earning_ranking_records": ArticleEarningRankingRecordDocument, + "lottery_win_records": LotteryWinRecordDocument, + "FTN_trade_orders": FTNTradeOrderDocument, } async def get_last_update_time( - collection: AgnosticCollection, + collection: type[Document], sort_key: str, sort_direction: Literal["asc", "desc"], ) -> Optional[datetime]: - try: - db_result = ( - await collection.find() - .sort(sort_key, 1 if sort_direction == "asc" else -1) - .limit(1) - .next() - ) - return db_result[sort_key] - except StopAsyncIteration: - return None + latest_record = await collection.find_one( + sort={sort_key: "ASC" if sort_direction == "asc" else "DESC"} + ) + + # 获取到的是数据记录对象,将其转换为字典 + # 然后通过驼峰样式的 sort_key 获取到数据更新时间 + return latest_record.to_dict()[sort_key] if latest_record else None async def get_data_count( - collection: AgnosticCollection, mode: Literal["accurate", "estimated"] + collection: type[Document], mode: Literal["accurate", "estimated"] ) -> int: - if mode == "accurate": - return await collection.count_documents({}) - - return await collection.estimated_document_count() + return await collection.count(fast=mode == "estimated") class GetResponse(Struct, **RESPONSE_STRUCT_CONFIG): diff --git a/backend/api/v1/users.py b/backend/api/v1/users.py index 5f1cd0d..4c12496 100644 --- a/backend/api/v1/users.py +++ b/backend/api/v1/users.py @@ -3,6 +3,7 @@ from jkit.constants import USER_SLUG_REGEX from jkit.exceptions import ResourceUnavailableError +from jkit.identifier_convert import article_slug_to_url, user_slug_to_url from jkit.user import MembershipEnum, User from litestar import Response, Router, get from litestar.params import Parameter @@ -16,7 +17,11 @@ success, ) -from utils.db import ARTICLE_FP_RANK_COLLECTION, LOTTERY_COLLECTION +from models.jianshu.article_earning_ranking_record import ( + ArticleEarningRankingRecordDocument, +) +from models.jianshu.lottery_win_record import LotteryWinRecordDocument +from models.jianshu.user import UserDocument class GetVipInfoResponse(Struct, **RESPONSE_STRUCT_CONFIG): @@ -109,26 +114,23 @@ async def get_lottery_win_records( msg="用户 Slug 无效", ) - result = ( - LOTTERY_COLLECTION.find( - { - "user.url": user.url, - "reward_name": { - "$nin": excluded_awards if excluded_awards else [], - }, - } - ) - .skip(offset) - .limit(limit) - ) - - records: List[GetLotteryWinRecordItem] = [ - GetLotteryWinRecordItem( - time=item["time"], - reward_name=item["reward_name"], + records: List[GetLotteryWinRecordItem] = [] + async for item in LotteryWinRecordDocument.find_many( + { + "userSlug": user.slug, + "awardName": { + "$nin": excluded_awards if excluded_awards else [], + }, + }, + skip=offset, + limit=limit, + ): + records.append( + GetLotteryWinRecordItem( + time=item.time, + reward_name=item.award_name, + ) ) - async for item in result - ] return success( data=GetLotteryWinRecordsResponse( @@ -179,23 +181,26 @@ async def get_on_article_rank_records_handler( msg="用户 Slug 无效", ) - result = ( - ARTICLE_FP_RANK_COLLECTION.find({"author.url": user.url}) - .sort(order_by, 1 if order_direction == "asc" else -1) - .skip(offset) - .limit(limit) - ) - - records: List[GetOnArticleRankRecordItem] = [ - GetOnArticleRankRecordItem( - date=item["date"], - ranking=item["ranking"], - article_title=item["article"]["title"], - article_url=item["article"]["url"], - FP_reward=item["reward"]["to_author"], + records: List[GetOnArticleRankRecordItem] = [] + async for item in ArticleEarningRankingRecordDocument.find_many( + { + "authorSlug": user.slug, + }, + sort={order_by: "ASC" if order_direction == "asc" else "DESC"}, + skip=offset, + limit=limit, + ): + records.append( + GetOnArticleRankRecordItem( + date=item.date, + ranking=item.ranking, + # TODO + article_title=item.article.title, # type: ignore + # TODO + article_url=article_slug_to_url(item.article.slug), # type: ignore + FP_reward=item.earning.to_author, + ) ) - async for item in result - ] return success( data=GetOnArticleRankRecordsResponse( @@ -223,23 +228,30 @@ async def get_on_article_rank_records_by_user_name_handler( offset: Annotated[int, Parameter(description="分页偏移", ge=0)] = 0, limit: Annotated[int, Parameter(description="结果数量", gt=0, lt=100)] = 20, ) -> Response: - result = ( - ARTICLE_FP_RANK_COLLECTION.find({"author.name": user_name}) - .sort(order_by, 1 if order_direction == "asc" else -1) - .skip(offset) - .limit(limit) - ) + user = await UserDocument.find_one({"name": user_name}) + if not user: # 没有找到对应昵称的用户 + return success(data=GetOnArticleRankRecordsResponse(records=[])) - records: List[GetOnArticleRankRecordItem] = [ - GetOnArticleRankRecordItem( - date=item["date"], - ranking=item["ranking"], - article_title=item["article"]["title"], - article_url=item["article"]["url"], - FP_reward=item["reward"]["to_author"], + records: List[GetOnArticleRankRecordItem] = [] + async for item in ArticleEarningRankingRecordDocument.find_many( + { + "authorSlug": user.slug, + }, + sort={order_by: "ASC" if order_direction == "asc" else "DESC"}, + skip=offset, + limit=limit, + ): + records.append( + GetOnArticleRankRecordItem( + date=item.date, + ranking=item.ranking, + # TODO + article_title=item.article.title, # type: ignore + # TODO + article_url=article_slug_to_url(item.article.slug), # type: ignore + FP_reward=item.earning.to_author, + ) ) - async for item in result - ] return success( data=GetOnArticleRankRecordsResponse( @@ -277,26 +289,21 @@ async def get_on_article_rank_summary_handler( msg="用户 Slug 无效", ) - records = ARTICLE_FP_RANK_COLLECTION.find( - {"author.url": user.url}, - {"_id": False, "ranking": True}, - ) - top10 = 0 top30 = 0 top50 = 0 total = 0 - async for item in records: - ranking = item["ranking"] - if ranking <= 10: + async for item in ArticleEarningRankingRecordDocument.find_many( + {"authorSlug": user.slug} + ): + total += 1 + if item.ranking <= 10: top10 += 1 - if ranking <= 30: + if item.ranking <= 30: top30 += 1 - if ranking <= 50: + if item.ranking <= 50: top50 += 1 - total += 1 - return success( data=GetOnArticleRankSummaryResponse( top10=top10, @@ -318,26 +325,27 @@ async def get_on_article_rank_summary_handler( async def get_on_article_rank_summary_by_user_name_handler( user_name: Annotated[str, Parameter(description="用户昵称", max_length=50)], ) -> Response: - records = ARTICLE_FP_RANK_COLLECTION.find( - {"author.name": user_name}, - {"_id": False, "ranking": True}, - ) + user = await UserDocument.find_one({"name": user_name}) + if not user: # 没有找到对应昵称的用户 + return success( + data=GetOnArticleRankSummaryResponse(top10=0, top30=0, top50=0, total=0) + ) top10 = 0 top30 = 0 top50 = 0 total = 0 - async for item in records: - ranking = item["ranking"] - if ranking <= 10: + async for item in ArticleEarningRankingRecordDocument.find_many( + {"authorSlug": user.slug} + ): + total += 1 + if item.ranking <= 10: top10 += 1 - if ranking <= 30: + if item.ranking <= 30: top30 += 1 - if ranking <= 50: + if item.ranking <= 50: top50 += 1 - total += 1 - return success( data=GetOnArticleRankSummaryResponse( top10=top10, @@ -363,10 +371,10 @@ async def get_name_autocomplete_handler( name_part: Annotated[str, Parameter(description="用户昵称片段", max_length=50)], limit: Annotated[int, Parameter(description="结果数量", gt=0, le=100)] = 5, ) -> Response: - result = await ARTICLE_FP_RANK_COLLECTION.distinct( - "author.name", + result = await UserDocument.get_collection().distinct( + "name", { - "author.name": { + "name": { "$regex": f"^{name_part}", }, }, @@ -395,48 +403,21 @@ class GetHistoryNamesOnArticleRankSummaryResponse(Struct, **RESPONSE_STRUCT_CONF async def get_history_names_on_article_rank_summary_handler( user_name: Annotated[str, Parameter(description="用户昵称", max_length=50)], ) -> Response: - url_query = await ARTICLE_FP_RANK_COLLECTION.find_one({"author.name": user_name}) - if not url_query: + user = await UserDocument.find_one({"name": user_name}) + if not user: # 没有找到对应昵称的用户 return success( data=GetHistoryNamesOnArticleRankSummaryResponse( history_names_onrank_summary={}, ) ) - user_url = url_query["author"]["url"] - - result = ARTICLE_FP_RANK_COLLECTION.aggregate( - [ - { - "$match": { - "author.url": user_url, - }, - }, - { - "$group": { - "_id": "$author.name", - "count": {"$sum": 1}, - } - }, - # 排除当前昵称 - { - "$match": { - "_id": { - "$ne": user_name, - }, - }, - }, - ] - ) - - history_names_onrank_summary: Dict[str, int] = {} - async for item in result: - history_names_onrank_summary[item["_id"]] = item["count"] + history_names = user.history_names return success( data=GetHistoryNamesOnArticleRankSummaryResponse( - user_url=user_url, - history_names_onrank_summary=history_names_onrank_summary, + user_url=user_slug_to_url(user.slug), + # TODO: 全部曾上榜昵称均显示为 1 条记录 + history_names_onrank_summary={x: 1 for x in history_names}, ) ) diff --git a/backend/models/jianshu/article_earning_ranking_record.py b/backend/models/jianshu/article_earning_ranking_record.py new file mode 100644 index 0000000..99c448a --- /dev/null +++ b/backend/models/jianshu/article_earning_ranking_record.py @@ -0,0 +1,38 @@ +from datetime import datetime +from typing import Optional + +from bson import ObjectId +from jkit.msgspec_constraints import ( + ArticleSlug, + NonEmptyStr, + PositiveFloat, + PositiveInt, + UserSlug, +) +from sshared.mongo import MODEL_META, Document, Field, Index + +from utils.db import JIANSHU_DB + + +class ArticleField(Field, **MODEL_META): + slug: Optional[ArticleSlug] + title: Optional[NonEmptyStr] + + +class EarningField(Field, **MODEL_META): + to_author: PositiveFloat + to_voter: PositiveFloat + + +class ArticleEarningRankingRecordDocument(Document, **MODEL_META): + _id: ObjectId + date: datetime + ranking: PositiveInt + + article: ArticleField + author_slug: Optional[UserSlug] + earning: EarningField + + class Meta: # type: ignore + collection = JIANSHU_DB.article_earning_ranking_records + indexes = (Index(keys=("date", "ranking"), unique=True).validate(),) diff --git a/backend/models/jianshu/lottery_win_record.py b/backend/models/jianshu/lottery_win_record.py new file mode 100644 index 0000000..d1e24e0 --- /dev/null +++ b/backend/models/jianshu/lottery_win_record.py @@ -0,0 +1,22 @@ +from datetime import datetime + +from jkit.msgspec_constraints import ( + NonEmptyStr, + PositiveInt, + UserSlug, +) +from sshared.mongo import MODEL_META, Document, Index + +from utils.db import JIANSHU_DB + + +class LotteryWinRecordDocument(Document, **MODEL_META): + id: PositiveInt + time: datetime + award_name: NonEmptyStr + + user_slug: UserSlug + + class Meta: # type: ignore + collection = JIANSHU_DB.lottery_win_records + indexes = (Index(keys=("id",), unique=True),) diff --git a/backend/models/jianshu/user.py b/backend/models/jianshu/user.py new file mode 100644 index 0000000..aadaa44 --- /dev/null +++ b/backend/models/jianshu/user.py @@ -0,0 +1,30 @@ +from datetime import datetime +from enum import Enum +from typing import List, Optional + +from jkit.msgspec_constraints import PositiveInt, UserName, UserSlug, UserUploadedUrl +from sshared.mongo import MODEL_META, Document, Index + +from utils.db import JIANSHU_DB + + +class JianshuUserStatus(Enum): + NORMAL = "NORMAL" + INACCESSABLE = "INACCESSIBLE" + + +class UserDocument(Document, **MODEL_META): + slug: UserSlug + status: JianshuUserStatus + updated_at: datetime + id: Optional[PositiveInt] + name: Optional[UserName] + history_names: List[UserName] + avatar_url: Optional[UserUploadedUrl] + + class Meta: # type: ignore + collection = JIANSHU_DB.users + indexes = ( + Index(keys=("slug",), unique=True).validate(), + Index(keys=("updatedAt",)).validate(), + ) diff --git a/backend/models/jpep/ftn_trade_order.py b/backend/models/jpep/ftn_trade_order.py new file mode 100644 index 0000000..b0901b0 --- /dev/null +++ b/backend/models/jpep/ftn_trade_order.py @@ -0,0 +1,34 @@ +from datetime import datetime +from typing import Literal + +from jkit.msgspec_constraints import ( + NonNegativeInt, + PositiveFloat, + PositiveInt, +) +from sshared.mongo import MODEL_META, Document, Field, Index + +from utils.db import JPEP_DB + + +class AmountField(Field, **MODEL_META): + total: PositiveInt + traded: NonNegativeInt + tradable: NonNegativeInt + minimum_trade: PositiveInt + + +class FTNTradeOrderDocument(Document, **MODEL_META): + fetch_time: datetime + id: PositiveInt + published_at: datetime + type: Literal["buy", "sell"] + price: PositiveFloat + traded_count: NonNegativeInt + + amount: AmountField + publisher_id: PositiveInt + + class Meta: # type: ignore + collection = JPEP_DB.ftn_trade_orders + indexes = (Index(keys=("fetchTime", "id"), unique=True).validate(),) diff --git a/backend/poetry.lock b/backend/poetry.lock index 57e0d49..e527868 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -1,14 +1,14 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "anyio" -version = "4.3.0" +version = "4.4.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.8" files = [ - {file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"}, - {file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"}, + {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, + {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, ] [package.dependencies] @@ -24,13 +24,13 @@ trio = ["trio (>=0.23)"] [[package]] name = "certifi" -version = "2024.2.2" +version = "2024.6.2" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, + {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, + {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, ] [[package]] @@ -94,13 +94,13 @@ test = ["pytest (>=6)"] [[package]] name = "faker" -version = "25.0.0" +version = "25.8.0" description = "Faker is a Python package that generates fake data for you." optional = false python-versions = ">=3.8" files = [ - {file = "Faker-25.0.0-py3-none-any.whl", hash = "sha256:e23a2b74888885c3d23a9237bacb823041291c03d609a39acb9ebe6c123f3986"}, - {file = "Faker-25.0.0.tar.gz", hash = "sha256:87ef41e24b39a5be66ecd874af86f77eebd26782a2681200e86c5326340a95d3"}, + {file = "Faker-25.8.0-py3-none-any.whl", hash = "sha256:4c40b34a9c569018d4f9d6366d71a4da8a883d5ddf2b23197be5370f29b7e1b6"}, + {file = "Faker-25.8.0.tar.gz", hash = "sha256:bdec5f2fb057d244ebef6e0ed318fea4dcbdf32c3a1a010766fc45f5d68fc68d"}, ] [package.dependencies] @@ -314,13 +314,13 @@ typing-extensions = "*" [[package]] name = "litestar" -version = "2.8.2" +version = "2.9.0" description = "Litestar - A production-ready, highly performant, extensible ASGI API Framework" optional = false python-versions = "<4.0,>=3.8" files = [ - {file = "litestar-2.8.2-py3-none-any.whl", hash = "sha256:c891baf8a17d66cfed5c40bef7b5bf4c02c2831babf5fca0af404f441610557a"}, - {file = "litestar-2.8.2.tar.gz", hash = "sha256:18353cb7246ba2e7f8d4aac4fe2d8772b503c931cf5ee16efc759cbbc3a2344b"}, + {file = "litestar-2.9.0-py3-none-any.whl", hash = "sha256:25235ad99f08807e633347fa509dcf5989153bde9b6a82e521b1f056af33becc"}, + {file = "litestar-2.9.0.tar.gz", hash = "sha256:bea384c9ddae74bcb0d96ecb6dc1b51f8a13d50173cdfd56bfd2627ede505154"}, ] [package.dependencies] @@ -344,7 +344,7 @@ attrs = ["attrs"] brotli = ["brotli"] cli = ["jsbeautifier", "uvicorn[standard]", "uvloop (>=0.18.0)"] cryptography = ["cryptography"] -full = ["litestar[annotated-types,attrs,brotli,cli,cryptography,jinja,jwt,mako,minijinja,opentelemetry,piccolo,picologging,prometheus,pydantic,redis,sqlalchemy,standard,structlog]"] +full = ["advanced-alchemy (>=0.2.2)", "annotated-types", "attrs", "brotli", "cryptography", "email-validator", "fast-query-parsers (>=1.0.2)", "jinja2", "jinja2 (>=3.1.2)", "jsbeautifier", "mako (>=1.2.4)", "minijinja (>=1.0.0)", "opentelemetry-instrumentation-asgi", "piccolo", "picologging", "prometheus-client", "pydantic", "pydantic-extra-types", "python-jose", "redis[hiredis] (>=4.4.4)", "structlog", "uvicorn[standard]", "uvloop (>=0.18.0)"] jinja = ["jinja2 (>=3.1.2)"] jwt = ["cryptography", "python-jose"] mako = ["mako (>=1.2.4)"] @@ -355,7 +355,7 @@ picologging = ["picologging"] prometheus = ["prometheus-client"] pydantic = ["email-validator", "pydantic", "pydantic-extra-types"] redis = ["redis[hiredis] (>=4.4.4)"] -sqlalchemy = ["advanced-alchemy (>=0.2.2,<0.9.0)"] +sqlalchemy = ["advanced-alchemy (>=0.2.2)"] standard = ["fast-query-parsers (>=1.0.2)", "jinja2", "jsbeautifier", "uvicorn[standard]", "uvloop (>=0.18.0)"] structlog = ["structlog"] @@ -571,27 +571,24 @@ files = [ [[package]] name = "nodeenv" -version = "1.8.0" +version = "1.9.1" description = "Node.js virtual environment builder" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ - {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, - {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, + {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, + {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, ] -[package.dependencies] -setuptools = "*" - [[package]] name = "polyfactory" -version = "2.15.0" +version = "2.16.0" description = "Mock data generation factories" optional = false python-versions = "<4.0,>=3.8" files = [ - {file = "polyfactory-2.15.0-py3-none-any.whl", hash = "sha256:ff5b6a8742cbd6fbde9f81310b9732d5421fbec31916d6ede5a977753110fbe9"}, - {file = "polyfactory-2.15.0.tar.gz", hash = "sha256:a3ff5263756ad74acf4001f04c1b6aab7d1197cbaa070352df79573a8dcd85ec"}, + {file = "polyfactory-2.16.0-py3-none-any.whl", hash = "sha256:168d8e50b77e91e35e691e8b3eedac43d7e423a6857fa26d473def96d53f0ecf"}, + {file = "polyfactory-2.16.0.tar.gz", hash = "sha256:03d8c706b70c4782ac8e637d0f6ab52760a7d11b712da5936a95a8f7022b2688"}, ] [package.dependencies] @@ -609,86 +606,85 @@ sqlalchemy = ["sqlalchemy (>=1.4.29)"] [[package]] name = "pygments" -version = "2.17.2" +version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, - {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, ] [package.extras] -plugins = ["importlib-metadata"] windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pymongo" -version = "4.7.1" +version = "4.7.3" description = "Python driver for MongoDB " optional = false python-versions = ">=3.7" files = [ - {file = "pymongo-4.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8822614975038e0cece47d12e7634a79c2ee590a0ae78ae64c37b9c6610a14c"}, - {file = "pymongo-4.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:57b5b485ef89270ed2e603814f43f0fdd9b8ba5d4039124d90878cdc2327000c"}, - {file = "pymongo-4.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e99dac3c7c2cb498937cc1767361851099da38861e921113318c87d71e3d127"}, - {file = "pymongo-4.7.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:253ed8fd6e7f4b2a1caa89e6b287b9e04f42613319ee1e1240c2db2afe1637e7"}, - {file = "pymongo-4.7.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8cee62188127a126f59ea45d3981868a5e35343be4ef4ad8712eaf42be37a00b"}, - {file = "pymongo-4.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31ed8ba3da0366346264604b3a443f5a4232cab5ed45f520bead6184cf0851a1"}, - {file = "pymongo-4.7.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:887d043ecc0c7d5591925bbc7abb67caf21c94d6e6e5d442cb49eb5d9d8ee76b"}, - {file = "pymongo-4.7.1-cp310-cp310-win32.whl", hash = "sha256:bfd5c7e5bb87171a5296fa32205adb50b27704a612036ec4395c3cd316fc0e91"}, - {file = "pymongo-4.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:5ae1aeeb405c29885266666dc7115792d647ed68cfdb6ed02e2e211d12f2e1c8"}, - {file = "pymongo-4.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e4a63ba6813a2168ebd35ea5369f6c33f7787525986cd77668b7956acc3d2a38"}, - {file = "pymongo-4.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:811a07bba9d35f1e34159ede632ac71dbc429b372a20004e32d6578af872db1a"}, - {file = "pymongo-4.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d227555be35078b53f506f6b58bd0b0e8fd4513e89e6f29e83a97efab439250"}, - {file = "pymongo-4.7.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:daf35ab13b86aba7cc8c4b019882f1fa8d287a26f586ef5eaf60a5233d3eaa52"}, - {file = "pymongo-4.7.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa354933a158e57494c98b592f46d5d24d1b109e6ba05a05179cde719d9f7fd3"}, - {file = "pymongo-4.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad360630c221aee7c0841a51851496a3ca6fdea87007098a982c1aa26e34083a"}, - {file = "pymongo-4.7.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5119c66af8c4197c8757b4b7d98c443e5b127c224ac92fb657dbe2b512ae2713"}, - {file = "pymongo-4.7.1-cp311-cp311-win32.whl", hash = "sha256:11f74dafde63ad2dc30c01f40b4c69d9af157f8ba5224b0c9d4de7158537266f"}, - {file = "pymongo-4.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:ec94d29103317aa920dae59ed385de9604cb0ef840b5b7137b5eaa7a2042580a"}, - {file = "pymongo-4.7.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b8b95e2163b73d03a913efa89b0f7c5012be82efd4e9dbce8aa62010a75a277c"}, - {file = "pymongo-4.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fb1a884b1c6aeac5ffeb8ccb696fbc242a7ae1bba36f2328c01f76fab7221b94"}, - {file = "pymongo-4.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ccc8dd4fe9aac18dde27c33a53271c6c90159b74c43fbdab1d33d5efc36c2f5"}, - {file = "pymongo-4.7.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7247c1dc7d8eed4e24eb1dd92c4c58ebf1e5159500015652552acfdebdeed256"}, - {file = "pymongo-4.7.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:45ac46f0d6bdc2baac34ced60aae27b2083170d77397330eff0ac5689ea29d38"}, - {file = "pymongo-4.7.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a848249d5b4763497add62f7dd7bd0ce1538129bf42f4cb132a76d24c61bf98d"}, - {file = "pymongo-4.7.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ff6d56ca1f0cd3687a13ce90a32a8efb3cc3a53728e5ac160c4c30d10385a72"}, - {file = "pymongo-4.7.1-cp312-cp312-win32.whl", hash = "sha256:e175d74c52b6c8414a4b4504a2dd42b0202d101b2eb9508a34c137357683864e"}, - {file = "pymongo-4.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:263c169302df636f9086b584994a51d0adfc8738fe27d7b8e2aacf46fd68b6cb"}, - {file = "pymongo-4.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:337d99f88d32a5f8056d6d2bc365ccf09d09583f3942882c50cf11b459e8fbc0"}, - {file = "pymongo-4.7.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30a9d891631d7e847b24f551b1d89ff2033539e7cd8e9af29714b4d0db7abb06"}, - {file = "pymongo-4.7.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73bf96ece4999b0bbab7169cb2b9c60918b434487009e48be4bd47eeb2aa7b14"}, - {file = "pymongo-4.7.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ef32a7cfe748c0c72fdad9e51459de5e0c6b16c5288b39f863abfff23503847"}, - {file = "pymongo-4.7.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24c8f1dd545360ec1b79007a3ba6573af565df6fde49f6dfc53813f3f475a751"}, - {file = "pymongo-4.7.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b897b60b2d55c26f3efea0effc11b655db68125c3731274bc3953375e9ccab73"}, - {file = "pymongo-4.7.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5a58b6cd7c423ba49db10d8445756062c931ad2246ba0da1e705bf22962fd9e9"}, - {file = "pymongo-4.7.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ed6b3a0740efe98bb03ccf054578e9788ebcd06d021d548b8217ab2c82e45975"}, - {file = "pymongo-4.7.1-cp37-cp37m-win32.whl", hash = "sha256:85b8dd3756b73993b1e3ab6b1cba826b9e4987a094a5d5b6d37313776458cd94"}, - {file = "pymongo-4.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:297cdc87c4b4168782b571c8643540e9b0ad1d09266b43d2f5954f8632280835"}, - {file = "pymongo-4.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7b10603ba64af08f5af7eb9a69d6b24e3c69d91fdd48c54b95e284686c1c582d"}, - {file = "pymongo-4.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:64b69b9cd8a6d23881a80490d575e92918f9afca43096a7d6c1013d6b3e5c75c"}, - {file = "pymongo-4.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c7e05454cdc5aa4702e03cad0df4205daccd6fd631bbbf0a85bbe598129a6cc"}, - {file = "pymongo-4.7.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e0a30a022ac8a9164ee5a4b761e13dbb3d10a21845f7258011e3415151fb645"}, - {file = "pymongo-4.7.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13fc201e073644acd77860d9e91ccfc27addf510563e07381cadc9a55ac3a894"}, - {file = "pymongo-4.7.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dd998e9f0f7694032c1648c7f57fccaa78903df6329b8f8ae20cfa7c4ceca34"}, - {file = "pymongo-4.7.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:455f9d603ed0990a787773d5718e871300bddf585ce543baf129c9f5ca3adb02"}, - {file = "pymongo-4.7.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d804eaf19a65211cc2c8c5db75be685c3f31c64cdab639794f66f13f8e258ba6"}, - {file = "pymongo-4.7.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a46c08ef0b273c415b1e8933f6739596be264ae700a4927f84e0b84e70fdf0eb"}, - {file = "pymongo-4.7.1-cp38-cp38-win32.whl", hash = "sha256:58989bcb94233233a71645236b972835d4f87a6bb1b7e818d38a7e6e6d4630de"}, - {file = "pymongo-4.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:d63f38454a2e23c117d3ceab3b661568f2418536825787256ad24e5baaedfd27"}, - {file = "pymongo-4.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d50969de00d3522b2c394f7e59b843871e2be4b525af92066da7f3bd02799fdc"}, - {file = "pymongo-4.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f2a720e787c9b9b912db5bb4c3e7123ccff1352d6c3ac0cb2c7ee392cdc95c00"}, - {file = "pymongo-4.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c808098f2cdb87d4035144e536ba5fa7709d0420c17b68e6ace5da18c38ded5f"}, - {file = "pymongo-4.7.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1829a7db720ff586aaf59c806e89e0a388548063aa844d21a570a231ad8ca87"}, - {file = "pymongo-4.7.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:615c7573d7a9c4837332a673fdc5a5f214b474dd52d846bcf4cc3d011550bee1"}, - {file = "pymongo-4.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e935712b17e7a42831022353bac91a346a792658a54e12bec907ec11695cc899"}, - {file = "pymongo-4.7.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbc32217c81d87750401fa1c2bc9450e854b23e6e30243c82d3514b8e58f39e3"}, - {file = "pymongo-4.7.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5bc87db2e9563295c4e45602ab978a2fcbaba3ab89e745503b24f895cddeb755"}, - {file = "pymongo-4.7.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:65c45682d5ed8c6618bde22cd6716b47a197f4ef800a025213b28d13a59e5fca"}, - {file = "pymongo-4.7.1-cp39-cp39-win32.whl", hash = "sha256:67cbee427c263a4483e3249fef480788ccc16edb1a4fc330c4c6cb0cb9db94a8"}, - {file = "pymongo-4.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:1bd1eef70c1eda838b26397ef75c9580d7a97fd94b6324971d7f3d2ad3552e9a"}, - {file = "pymongo-4.7.1.tar.gz", hash = "sha256:811c41c6227b7548afcb53e1b996c25262d837b5e5f519e2ddc2c7e59d8728a5"}, + {file = "pymongo-4.7.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e9580b4537b3cc5d412070caabd1dabdf73fdce249793598792bac5782ecf2eb"}, + {file = "pymongo-4.7.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:517243b2b189c98004570dd8fc0e89b1a48363d5578b3b99212fa2098b2ea4b8"}, + {file = "pymongo-4.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23b1e9dabd61da1c7deb54d888f952f030e9e35046cebe89309b28223345b3d9"}, + {file = "pymongo-4.7.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03e0f9901ad66c6fb7da0d303461377524d61dab93a4e4e5af44164c5bb4db76"}, + {file = "pymongo-4.7.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9a870824aa54453aee030bac08c77ebcf2fe8999400f0c2a065bebcbcd46b7f8"}, + {file = "pymongo-4.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfd7b3d3f4261bddbb74a332d87581bc523353e62bb9da4027cc7340f6fcbebc"}, + {file = "pymongo-4.7.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4d719a643ea6da46d215a3ba51dac805a773b611c641319558d8576cbe31cef8"}, + {file = "pymongo-4.7.3-cp310-cp310-win32.whl", hash = "sha256:d8b1e06f361f3c66ee694cb44326e1a2e4f93bc9c3a4849ae8547889fca71154"}, + {file = "pymongo-4.7.3-cp310-cp310-win_amd64.whl", hash = "sha256:c450ab2f9397e2d5caa7fddeb4feb30bf719c47c13ae02c0bbb3b71bf4099c1c"}, + {file = "pymongo-4.7.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79cc6459209e885ba097779eaa0fe7f2fa049db39ab43b1731cf8d065a4650e8"}, + {file = "pymongo-4.7.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6e2287f1e2cc35e73cd74a4867e398a97962c5578a3991c730ef78d276ca8e46"}, + {file = "pymongo-4.7.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:413506bd48d8c31ee100645192171e4773550d7cb940b594d5175ac29e329ea1"}, + {file = "pymongo-4.7.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cc1febf17646d52b7561caa762f60bdfe2cbdf3f3e70772f62eb624269f9c05"}, + {file = "pymongo-4.7.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8dfcf18a49955d50a16c92b39230bd0668ffc9c164ccdfe9d28805182b48fa72"}, + {file = "pymongo-4.7.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89872041196c008caddf905eb59d3dc2d292ae6b0282f1138418e76f3abd3ad6"}, + {file = "pymongo-4.7.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3ed97b89de62ea927b672ad524de0d23f3a6b4a01c8d10e3d224abec973fbc3"}, + {file = "pymongo-4.7.3-cp311-cp311-win32.whl", hash = "sha256:d2f52b38151e946011d888a8441d3d75715c663fc5b41a7ade595e924e12a90a"}, + {file = "pymongo-4.7.3-cp311-cp311-win_amd64.whl", hash = "sha256:4a4cc91c28e81c0ce03d3c278e399311b0af44665668a91828aec16527082676"}, + {file = "pymongo-4.7.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cb30c8a78f5ebaca98640943447b6a0afcb146f40b415757c9047bf4a40d07b4"}, + {file = "pymongo-4.7.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9cf2069f5d37c398186453589486ea98bb0312214c439f7d320593b61880dc05"}, + {file = "pymongo-4.7.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3564f423958fced8a8c90940fd2f543c27adbcd6c7c6ed6715d847053f6200a0"}, + {file = "pymongo-4.7.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7a8af8a38fa6951fff73e6ff955a6188f829b29fed7c5a1b739a306b4aa56fe8"}, + {file = "pymongo-4.7.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a0e81c8dba6d825272867d487f18764cfed3c736d71d7d4ff5b79642acbed42"}, + {file = "pymongo-4.7.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88fc1d146feabac4385ea8ddb1323e584922922641303c8bf392fe1c36803463"}, + {file = "pymongo-4.7.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4225100b2c5d1f7393d7c5d256ceb8b20766830eecf869f8ae232776347625a6"}, + {file = "pymongo-4.7.3-cp312-cp312-win32.whl", hash = "sha256:5f3569ed119bf99c0f39ac9962fb5591eff02ca210fe80bb5178d7a1171c1b1e"}, + {file = "pymongo-4.7.3-cp312-cp312-win_amd64.whl", hash = "sha256:eb383c54c0c8ba27e7712b954fcf2a0905fee82a929d277e2e94ad3a5ba3c7db"}, + {file = "pymongo-4.7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a46cffe91912570151617d866a25d07b9539433a32231ca7e7cf809b6ba1745f"}, + {file = "pymongo-4.7.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c3cba427dac50944c050c96d958c5e643c33a457acee03bae27c8990c5b9c16"}, + {file = "pymongo-4.7.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7a5fd893edbeb7fa982f8d44b6dd0186b6cd86c89e23f6ef95049ff72bffe46"}, + {file = "pymongo-4.7.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c168a2fadc8b19071d0a9a4f85fe38f3029fe22163db04b4d5c046041c0b14bd"}, + {file = "pymongo-4.7.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c59c2c9e70f63a7f18a31e367898248c39c068c639b0579623776f637e8f482"}, + {file = "pymongo-4.7.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d08165fd82c89d372e82904c3268bd8fe5de44f92a00e97bb1db1785154397d9"}, + {file = "pymongo-4.7.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:397fed21afec4fdaecf72f9c4344b692e489756030a9c6d864393e00c7e80491"}, + {file = "pymongo-4.7.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:f903075f8625e2d228f1b9b9a0cf1385f1c41e93c03fd7536c91780a0fb2e98f"}, + {file = "pymongo-4.7.3-cp37-cp37m-win32.whl", hash = "sha256:8ed1132f58c38add6b6138b771d0477a3833023c015c455d9a6e26f367f9eb5c"}, + {file = "pymongo-4.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:8d00a5d8fc1043a4f641cbb321da766699393f1b6f87c70fae8089d61c9c9c54"}, + {file = "pymongo-4.7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9377b868c38700c7557aac1bc4baae29f47f1d279cc76b60436e547fd643318c"}, + {file = "pymongo-4.7.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:da4a6a7b4f45329bb135aa5096823637bd5f760b44d6224f98190ee367b6b5dd"}, + {file = "pymongo-4.7.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:487e2f9277f8a63ac89335ec4f1699ae0d96ebd06d239480d69ed25473a71b2c"}, + {file = "pymongo-4.7.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db3d608d541a444c84f0bfc7bad80b0b897e0f4afa580a53f9a944065d9b633"}, + {file = "pymongo-4.7.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e90af2ad3a8a7c295f4d09a2fbcb9a350c76d6865f787c07fe843b79c6e821d1"}, + {file = "pymongo-4.7.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e28feb18dc559d50ededba27f9054c79f80c4edd70a826cecfe68f3266807b3"}, + {file = "pymongo-4.7.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f21ecddcba2d9132d5aebd8e959de8d318c29892d0718420447baf2b9bccbb19"}, + {file = "pymongo-4.7.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:26140fbb3f6a9a74bd73ed46d0b1f43d5702e87a6e453a31b24fad9c19df9358"}, + {file = "pymongo-4.7.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:94baa5fc7f7d22c3ce2ac7bd92f7e03ba7a6875f2480e3b97a400163d6eaafc9"}, + {file = "pymongo-4.7.3-cp38-cp38-win32.whl", hash = "sha256:92dd247727dd83d1903e495acc743ebd757f030177df289e3ba4ef8a8c561fad"}, + {file = "pymongo-4.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:1c90c848a5e45475731c35097f43026b88ef14a771dfd08f20b67adc160a3f79"}, + {file = "pymongo-4.7.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f598be401b416319a535c386ac84f51df38663f7a9d1071922bda4d491564422"}, + {file = "pymongo-4.7.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:35ba90477fae61c65def6e7d09e8040edfdd3b7fd47c3c258b4edded60c4d625"}, + {file = "pymongo-4.7.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9aa8735955c70892634d7e61b0ede9b1eefffd3cd09ccabee0ffcf1bdfe62254"}, + {file = "pymongo-4.7.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:82a97d8f7f138586d9d0a0cff804a045cdbbfcfc1cd6bba542b151e284fbbec5"}, + {file = "pymongo-4.7.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de3b9db558930efab5eaef4db46dcad8bf61ac3ddfd5751b3e5ac6084a25e366"}, + {file = "pymongo-4.7.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0e149217ef62812d3c2401cf0e2852b0c57fd155297ecc4dcd67172c4eca402"}, + {file = "pymongo-4.7.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3a8a1ef4a824f5feb793b3231526d0045eadb5eb01080e38435dfc40a26c3e5"}, + {file = "pymongo-4.7.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d14e5e89a4be1f10efc3d9dcb13eb7a3b2334599cb6bb5d06c6a9281b79c8e22"}, + {file = "pymongo-4.7.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c6bfa29f032fd4fd7b129520f8cdb51ab71d88c2ba0567cccd05d325f963acb5"}, + {file = "pymongo-4.7.3-cp39-cp39-win32.whl", hash = "sha256:1421d0bd2ce629405f5157bd1aaa9b83f12d53a207cf68a43334f4e4ee312b66"}, + {file = "pymongo-4.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:f7ee974f8b9370a998919c55b1050889f43815ab588890212023fecbc0402a6d"}, + {file = "pymongo-4.7.3.tar.gz", hash = "sha256:6354a66b228f2cd399be7429685fb68e07f19110a3679782ecb4fdb68da03831"}, ] [package.dependencies] @@ -705,13 +701,13 @@ zstd = ["zstandard"] [[package]] name = "pyright" -version = "1.1.361" +version = "1.1.367" description = "Command line wrapper for pyright" optional = false python-versions = ">=3.7" files = [ - {file = "pyright-1.1.361-py3-none-any.whl", hash = "sha256:c50fc94ce92b5c958cfccbbe34142e7411d474da43d6c14a958667e35b9df7ea"}, - {file = "pyright-1.1.361.tar.gz", hash = "sha256:1d67933315666b05d230c85ea8fb97aaa2056e4092a13df87b7765bb9e8f1a8d"}, + {file = "pyright-1.1.367-py3-none-any.whl", hash = "sha256:89de6502ae02f1552d0c4df4b46867887a419849f379db617695ef9308cf01eb"}, + {file = "pyright-1.1.367.tar.gz", hash = "sha256:b1e5522ceb246ee6bc293a43d6d0162719d6467c1f1e9b81cee741aa11cdacbd"}, ] [package.dependencies] @@ -816,13 +812,13 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "rich-click" -version = "1.8.0" +version = "1.8.3" description = "Format click help output nicely with rich" optional = false python-versions = ">=3.7" files = [ - {file = "rich_click-1.8.0-py3-none-any.whl", hash = "sha256:846f504eb83a948d864888b2d73c71e52c310490c2babceac57e388aead086e2"}, - {file = "rich_click-1.8.0.tar.gz", hash = "sha256:f8cad0d67d286d6cd6fc9f69f2d6f25c6c4c2d99fb9d6cb3b8987b593dbe6fa8"}, + {file = "rich_click-1.8.3-py3-none-any.whl", hash = "sha256:636d9c040d31c5eee242201b5bf4f2d358bfae4db14bb22ec1cafa717cfd02cd"}, + {file = "rich_click-1.8.3.tar.gz", hash = "sha256:6d75bdfa7aa9ed2c467789a0688bc6da23fbe3a143e19aa6ad3f8bac113d2ab3"}, ] [package.dependencies] @@ -836,46 +832,30 @@ docs = ["markdown-include", "mkdocs", "mkdocs-glightbox", "mkdocs-material-exten [[package]] name = "ruff" -version = "0.4.2" +version = "0.4.8" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d14dc8953f8af7e003a485ef560bbefa5f8cc1ad994eebb5b12136049bbccc5"}, - {file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:24016ed18db3dc9786af103ff49c03bdf408ea253f3cb9e3638f39ac9cf2d483"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2e06459042ac841ed510196c350ba35a9b24a643e23db60d79b2db92af0c2b"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3afabaf7ba8e9c485a14ad8f4122feff6b2b93cc53cd4dad2fd24ae35112d5c5"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:799eb468ea6bc54b95527143a4ceaf970d5aa3613050c6cff54c85fda3fde480"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ec4ba9436a51527fb6931a8839af4c36a5481f8c19e8f5e42c2f7ad3a49f5069"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6a2243f8f434e487c2a010c7252150b1fdf019035130f41b77626f5655c9ca22"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8772130a063f3eebdf7095da00c0b9898bd1774c43b336272c3e98667d4fb8fa"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ab165ef5d72392b4ebb85a8b0fbd321f69832a632e07a74794c0e598e7a8376"}, - {file = "ruff-0.4.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1f32cadf44c2020e75e0c56c3408ed1d32c024766bd41aedef92aa3ca28eef68"}, - {file = "ruff-0.4.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:22e306bf15e09af45ca812bc42fa59b628646fa7c26072555f278994890bc7ac"}, - {file = "ruff-0.4.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:82986bb77ad83a1719c90b9528a9dd663c9206f7c0ab69282af8223566a0c34e"}, - {file = "ruff-0.4.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:652e4ba553e421a6dc2a6d4868bc3b3881311702633eb3672f9f244ded8908cd"}, - {file = "ruff-0.4.2-py3-none-win32.whl", hash = "sha256:7891ee376770ac094da3ad40c116258a381b86c7352552788377c6eb16d784fe"}, - {file = "ruff-0.4.2-py3-none-win_amd64.whl", hash = "sha256:5ec481661fb2fd88a5d6cf1f83403d388ec90f9daaa36e40e2c003de66751798"}, - {file = "ruff-0.4.2-py3-none-win_arm64.whl", hash = "sha256:cbd1e87c71bca14792948c4ccb51ee61c3296e164019d2d484f3eaa2d360dfaf"}, - {file = "ruff-0.4.2.tar.gz", hash = "sha256:33bcc160aee2520664bc0859cfeaebc84bb7323becff3f303b8f1f2d81cb4edc"}, -] - -[[package]] -name = "setuptools" -version = "69.5.1" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-69.5.1-py3-none-any.whl", hash = "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32"}, - {file = "setuptools-69.5.1.tar.gz", hash = "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987"}, + {file = "ruff-0.4.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7663a6d78f6adb0eab270fa9cf1ff2d28618ca3a652b60f2a234d92b9ec89066"}, + {file = "ruff-0.4.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eeceb78da8afb6de0ddada93112869852d04f1cd0f6b80fe464fd4e35c330913"}, + {file = "ruff-0.4.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aad360893e92486662ef3be0a339c5ca3c1b109e0134fcd37d534d4be9fb8de3"}, + {file = "ruff-0.4.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:284c2e3f3396fb05f5f803c9fffb53ebbe09a3ebe7dda2929ed8d73ded736deb"}, + {file = "ruff-0.4.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7354f921e3fbe04d2a62d46707e569f9315e1a613307f7311a935743c51a764"}, + {file = "ruff-0.4.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:72584676164e15a68a15778fd1b17c28a519e7a0622161eb2debdcdabdc71883"}, + {file = "ruff-0.4.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9678d5c9b43315f323af2233a04d747409d1e3aa6789620083a82d1066a35199"}, + {file = "ruff-0.4.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704977a658131651a22b5ebeb28b717ef42ac6ee3b11e91dc87b633b5d83142b"}, + {file = "ruff-0.4.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d05f8d6f0c3cce5026cecd83b7a143dcad503045857bc49662f736437380ad45"}, + {file = "ruff-0.4.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6ea874950daca5697309d976c9afba830d3bf0ed66887481d6bca1673fc5b66a"}, + {file = "ruff-0.4.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fc95aac2943ddf360376be9aa3107c8cf9640083940a8c5bd824be692d2216dc"}, + {file = "ruff-0.4.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:384154a1c3f4bf537bac69f33720957ee49ac8d484bfc91720cc94172026ceed"}, + {file = "ruff-0.4.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e9d5ce97cacc99878aa0d084c626a15cd21e6b3d53fd6f9112b7fc485918e1fa"}, + {file = "ruff-0.4.8-py3-none-win32.whl", hash = "sha256:6d795d7639212c2dfd01991259460101c22aabf420d9b943f153ab9d9706e6a9"}, + {file = "ruff-0.4.8-py3-none-win_amd64.whl", hash = "sha256:e14a3a095d07560a9d6769a72f781d73259655919d9b396c650fc98a8157555d"}, + {file = "ruff-0.4.8-py3-none-win_arm64.whl", hash = "sha256:14019a06dbe29b608f6b7cbcec300e3170a8d86efaddb7b23405cb7f7dcaf780"}, + {file = "ruff-0.4.8.tar.gz", hash = "sha256:16d717b1d57b2e2fd68bd0bf80fb43931b79d05a7131aa477d66fc40fbd86268"}, ] -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] - [[package]] name = "six" version = "1.16.0" @@ -898,6 +878,25 @@ files = [ {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] +[[package]] +name = "sshared" +version = "0.6.0" +description = "后端共享组件" +optional = false +python-versions = "<4.0,>=3.8" +files = [ + {file = "sshared-0.6.0-py3-none-any.whl", hash = "sha256:59ce6511c209583b272e29a8677737ad7dbe74d32b660c588f18bd6468cf3e57"}, + {file = "sshared-0.6.0.tar.gz", hash = "sha256:02056c995eb26b92da9e907291ca5c56bfe57374a340e87b9af01a7a187a2ad1"}, +] + +[package.dependencies] +msgspec = ">=0.18.0,<0.19.0" +typing-extensions = ">=4.12.0,<5.0.0" + +[package.extras] +api = ["litestar (>=2.9.0,<3.0.0)"] +mongo = ["motor (>=3.3.0,<4.0.0)"] + [[package]] name = "sspeedup" version = "0.25.1" @@ -928,24 +927,24 @@ word-split-jieba = ["jieba (>=0.42.0,<0.43.0)"] [[package]] name = "typing-extensions" -version = "4.11.0" +version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, - {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] name = "uvicorn" -version = "0.29.0" +version = "0.30.1" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.8" files = [ - {file = "uvicorn-0.29.0-py3-none-any.whl", hash = "sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de"}, - {file = "uvicorn-0.29.0.tar.gz", hash = "sha256:6a69214c0b6a087462412670b3ef21224fa48cae0e452b5883e8e8bdfdd11dd0"}, + {file = "uvicorn-0.30.1-py3-none-any.whl", hash = "sha256:cd17daa7f3b9d7a24de3617820e634d0933b69eed8e33a516071174427238c81"}, + {file = "uvicorn-0.30.1.tar.gz", hash = "sha256:d46cd8e0fd80240baffbcd9ec1012a712938754afcf81bce56c024c1656aece8"}, ] [package.dependencies] @@ -1002,86 +1001,86 @@ test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)" [[package]] name = "watchfiles" -version = "0.21.0" +version = "0.22.0" description = "Simple, modern and high performance file watching and code reload in python." optional = false python-versions = ">=3.8" files = [ - {file = "watchfiles-0.21.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:27b4035013f1ea49c6c0b42d983133b136637a527e48c132d368eb19bf1ac6aa"}, - {file = "watchfiles-0.21.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c81818595eff6e92535ff32825f31c116f867f64ff8cdf6562cd1d6b2e1e8f3e"}, - {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6c107ea3cf2bd07199d66f156e3ea756d1b84dfd43b542b2d870b77868c98c03"}, - {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d9ac347653ebd95839a7c607608703b20bc07e577e870d824fa4801bc1cb124"}, - {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5eb86c6acb498208e7663ca22dbe68ca2cf42ab5bf1c776670a50919a56e64ab"}, - {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f564bf68404144ea6b87a78a3f910cc8de216c6b12a4cf0b27718bf4ec38d303"}, - {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d0f32ebfaa9c6011f8454994f86108c2eb9c79b8b7de00b36d558cadcedaa3d"}, - {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d45d9b699ecbac6c7bd8e0a2609767491540403610962968d258fd6405c17c"}, - {file = "watchfiles-0.21.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:aff06b2cac3ef4616e26ba17a9c250c1fe9dd8a5d907d0193f84c499b1b6e6a9"}, - {file = "watchfiles-0.21.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d9792dff410f266051025ecfaa927078b94cc7478954b06796a9756ccc7e14a9"}, - {file = "watchfiles-0.21.0-cp310-none-win32.whl", hash = "sha256:214cee7f9e09150d4fb42e24919a1e74d8c9b8a9306ed1474ecaddcd5479c293"}, - {file = "watchfiles-0.21.0-cp310-none-win_amd64.whl", hash = "sha256:1ad7247d79f9f55bb25ab1778fd47f32d70cf36053941f07de0b7c4e96b5d235"}, - {file = "watchfiles-0.21.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:668c265d90de8ae914f860d3eeb164534ba2e836811f91fecc7050416ee70aa7"}, - {file = "watchfiles-0.21.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a23092a992e61c3a6a70f350a56db7197242f3490da9c87b500f389b2d01eef"}, - {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e7941bbcfdded9c26b0bf720cb7e6fd803d95a55d2c14b4bd1f6a2772230c586"}, - {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11cd0c3100e2233e9c53106265da31d574355c288e15259c0d40a4405cbae317"}, - {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78f30cbe8b2ce770160d3c08cff01b2ae9306fe66ce899b73f0409dc1846c1b"}, - {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6674b00b9756b0af620aa2a3346b01f8e2a3dc729d25617e1b89cf6af4a54eb1"}, - {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd7ac678b92b29ba630d8c842d8ad6c555abda1b9ef044d6cc092dacbfc9719d"}, - {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c873345680c1b87f1e09e0eaf8cf6c891b9851d8b4d3645e7efe2ec20a20cc7"}, - {file = "watchfiles-0.21.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49f56e6ecc2503e7dbe233fa328b2be1a7797d31548e7a193237dcdf1ad0eee0"}, - {file = "watchfiles-0.21.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:02d91cbac553a3ad141db016e3350b03184deaafeba09b9d6439826ee594b365"}, - {file = "watchfiles-0.21.0-cp311-none-win32.whl", hash = "sha256:ebe684d7d26239e23d102a2bad2a358dedf18e462e8808778703427d1f584400"}, - {file = "watchfiles-0.21.0-cp311-none-win_amd64.whl", hash = "sha256:4566006aa44cb0d21b8ab53baf4b9c667a0ed23efe4aaad8c227bfba0bf15cbe"}, - {file = "watchfiles-0.21.0-cp311-none-win_arm64.whl", hash = "sha256:c550a56bf209a3d987d5a975cdf2063b3389a5d16caf29db4bdddeae49f22078"}, - {file = "watchfiles-0.21.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:51ddac60b96a42c15d24fbdc7a4bfcd02b5a29c047b7f8bf63d3f6f5a860949a"}, - {file = "watchfiles-0.21.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:511f0b034120cd1989932bf1e9081aa9fb00f1f949fbd2d9cab6264916ae89b1"}, - {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cfb92d49dbb95ec7a07511bc9efb0faff8fe24ef3805662b8d6808ba8409a71a"}, - {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f92944efc564867bbf841c823c8b71bb0be75e06b8ce45c084b46411475a915"}, - {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:642d66b75eda909fd1112d35c53816d59789a4b38c141a96d62f50a3ef9b3360"}, - {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d23bcd6c8eaa6324fe109d8cac01b41fe9a54b8c498af9ce464c1aeeb99903d6"}, - {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18d5b4da8cf3e41895b34e8c37d13c9ed294954907929aacd95153508d5d89d7"}, - {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b8d1eae0f65441963d805f766c7e9cd092f91e0c600c820c764a4ff71a0764c"}, - {file = "watchfiles-0.21.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1fd9a5205139f3c6bb60d11f6072e0552f0a20b712c85f43d42342d162be1235"}, - {file = "watchfiles-0.21.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a1e3014a625bcf107fbf38eece0e47fa0190e52e45dc6eee5a8265ddc6dc5ea7"}, - {file = "watchfiles-0.21.0-cp312-none-win32.whl", hash = "sha256:9d09869f2c5a6f2d9df50ce3064b3391d3ecb6dced708ad64467b9e4f2c9bef3"}, - {file = "watchfiles-0.21.0-cp312-none-win_amd64.whl", hash = "sha256:18722b50783b5e30a18a8a5db3006bab146d2b705c92eb9a94f78c72beb94094"}, - {file = "watchfiles-0.21.0-cp312-none-win_arm64.whl", hash = "sha256:a3b9bec9579a15fb3ca2d9878deae789df72f2b0fdaf90ad49ee389cad5edab6"}, - {file = "watchfiles-0.21.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:4ea10a29aa5de67de02256a28d1bf53d21322295cb00bd2d57fcd19b850ebd99"}, - {file = "watchfiles-0.21.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:40bca549fdc929b470dd1dbfcb47b3295cb46a6d2c90e50588b0a1b3bd98f429"}, - {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9b37a7ba223b2f26122c148bb8d09a9ff312afca998c48c725ff5a0a632145f7"}, - {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec8c8900dc5c83650a63dd48c4d1d245343f904c4b64b48798c67a3767d7e165"}, - {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ad3fe0a3567c2f0f629d800409cd528cb6251da12e81a1f765e5c5345fd0137"}, - {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d353c4cfda586db2a176ce42c88f2fc31ec25e50212650c89fdd0f560ee507b"}, - {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:83a696da8922314ff2aec02987eefb03784f473281d740bf9170181829133765"}, - {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a03651352fc20975ee2a707cd2d74a386cd303cc688f407296064ad1e6d1562"}, - {file = "watchfiles-0.21.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3ad692bc7792be8c32918c699638b660c0de078a6cbe464c46e1340dadb94c19"}, - {file = "watchfiles-0.21.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06247538e8253975bdb328e7683f8515ff5ff041f43be6c40bff62d989b7d0b0"}, - {file = "watchfiles-0.21.0-cp38-none-win32.whl", hash = "sha256:9a0aa47f94ea9a0b39dd30850b0adf2e1cd32a8b4f9c7aa443d852aacf9ca214"}, - {file = "watchfiles-0.21.0-cp38-none-win_amd64.whl", hash = "sha256:8d5f400326840934e3507701f9f7269247f7c026d1b6cfd49477d2be0933cfca"}, - {file = "watchfiles-0.21.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:7f762a1a85a12cc3484f77eee7be87b10f8c50b0b787bb02f4e357403cad0c0e"}, - {file = "watchfiles-0.21.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6e9be3ef84e2bb9710f3f777accce25556f4a71e15d2b73223788d528fcc2052"}, - {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4c48a10d17571d1275701e14a601e36959ffada3add8cdbc9e5061a6e3579a5d"}, - {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c889025f59884423428c261f212e04d438de865beda0b1e1babab85ef4c0f01"}, - {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:66fac0c238ab9a2e72d026b5fb91cb902c146202bbd29a9a1a44e8db7b710b6f"}, - {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4a21f71885aa2744719459951819e7bf5a906a6448a6b2bbce8e9cc9f2c8128"}, - {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c9198c989f47898b2c22201756f73249de3748e0fc9de44adaf54a8b259cc0c"}, - {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f57c4461cd24fda22493109c45b3980863c58a25b8bec885ca8bea6b8d4b28"}, - {file = "watchfiles-0.21.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:853853cbf7bf9408b404754b92512ebe3e3a83587503d766d23e6bf83d092ee6"}, - {file = "watchfiles-0.21.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d5b1dc0e708fad9f92c296ab2f948af403bf201db8fb2eb4c8179db143732e49"}, - {file = "watchfiles-0.21.0-cp39-none-win32.whl", hash = "sha256:59137c0c6826bd56c710d1d2bda81553b5e6b7c84d5a676747d80caf0409ad94"}, - {file = "watchfiles-0.21.0-cp39-none-win_amd64.whl", hash = "sha256:6cb8fdc044909e2078c248986f2fc76f911f72b51ea4a4fbbf472e01d14faa58"}, - {file = "watchfiles-0.21.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab03a90b305d2588e8352168e8c5a1520b721d2d367f31e9332c4235b30b8994"}, - {file = "watchfiles-0.21.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:927c589500f9f41e370b0125c12ac9e7d3a2fd166b89e9ee2828b3dda20bfe6f"}, - {file = "watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd467213195e76f838caf2c28cd65e58302d0254e636e7c0fca81efa4a2e62c"}, - {file = "watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02b73130687bc3f6bb79d8a170959042eb56eb3a42df3671c79b428cd73f17cc"}, - {file = "watchfiles-0.21.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:08dca260e85ffae975448e344834d765983237ad6dc308231aa16e7933db763e"}, - {file = "watchfiles-0.21.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:3ccceb50c611c433145502735e0370877cced72a6c70fd2410238bcbc7fe51d8"}, - {file = "watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57d430f5fb63fea141ab71ca9c064e80de3a20b427ca2febcbfcef70ff0ce895"}, - {file = "watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dd5fad9b9c0dd89904bbdea978ce89a2b692a7ee8a0ce19b940e538c88a809c"}, - {file = "watchfiles-0.21.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:be6dd5d52b73018b21adc1c5d28ac0c68184a64769052dfeb0c5d9998e7f56a2"}, - {file = "watchfiles-0.21.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b3cab0e06143768499384a8a5efb9c4dc53e19382952859e4802f294214f36ec"}, - {file = "watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c6ed10c2497e5fedadf61e465b3ca12a19f96004c15dcffe4bd442ebadc2d85"}, - {file = "watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43babacef21c519bc6631c5fce2a61eccdfc011b4bcb9047255e9620732c8097"}, - {file = "watchfiles-0.21.0.tar.gz", hash = "sha256:c76c635fabf542bb78524905718c39f736a98e5ab25b23ec6d4abede1a85a6a3"}, + {file = "watchfiles-0.22.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:da1e0a8caebf17976e2ffd00fa15f258e14749db5e014660f53114b676e68538"}, + {file = "watchfiles-0.22.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:61af9efa0733dc4ca462347becb82e8ef4945aba5135b1638bfc20fad64d4f0e"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d9188979a58a096b6f8090e816ccc3f255f137a009dd4bbec628e27696d67c1"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2bdadf6b90c099ca079d468f976fd50062905d61fae183f769637cb0f68ba59a"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:067dea90c43bf837d41e72e546196e674f68c23702d3ef80e4e816937b0a3ffd"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbf8a20266136507abf88b0df2328e6a9a7c7309e8daff124dda3803306a9fdb"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1235c11510ea557fe21be5d0e354bae2c655a8ee6519c94617fe63e05bca4171"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2444dc7cb9d8cc5ab88ebe792a8d75709d96eeef47f4c8fccb6df7c7bc5be71"}, + {file = "watchfiles-0.22.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c5af2347d17ab0bd59366db8752d9e037982e259cacb2ba06f2c41c08af02c39"}, + {file = "watchfiles-0.22.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9624a68b96c878c10437199d9a8b7d7e542feddda8d5ecff58fdc8e67b460848"}, + {file = "watchfiles-0.22.0-cp310-none-win32.whl", hash = "sha256:4b9f2a128a32a2c273d63eb1fdbf49ad64852fc38d15b34eaa3f7ca2f0d2b797"}, + {file = "watchfiles-0.22.0-cp310-none-win_amd64.whl", hash = "sha256:2627a91e8110b8de2406d8b2474427c86f5a62bf7d9ab3654f541f319ef22bcb"}, + {file = "watchfiles-0.22.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8c39987a1397a877217be1ac0fb1d8b9f662c6077b90ff3de2c05f235e6a8f96"}, + {file = "watchfiles-0.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a927b3034d0672f62fb2ef7ea3c9fc76d063c4b15ea852d1db2dc75fe2c09696"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052d668a167e9fc345c24203b104c313c86654dd6c0feb4b8a6dfc2462239249"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e45fb0d70dda1623a7045bd00c9e036e6f1f6a85e4ef2c8ae602b1dfadf7550"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c49b76a78c156979759d759339fb62eb0549515acfe4fd18bb151cc07366629c"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4a65474fd2b4c63e2c18ac67a0c6c66b82f4e73e2e4d940f837ed3d2fd9d4da"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cc0cba54f47c660d9fa3218158b8963c517ed23bd9f45fe463f08262a4adae1"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94ebe84a035993bb7668f58a0ebf998174fb723a39e4ef9fce95baabb42b787f"}, + {file = "watchfiles-0.22.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e0f0a874231e2839abbf473256efffe577d6ee2e3bfa5b540479e892e47c172d"}, + {file = "watchfiles-0.22.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:213792c2cd3150b903e6e7884d40660e0bcec4465e00563a5fc03f30ea9c166c"}, + {file = "watchfiles-0.22.0-cp311-none-win32.whl", hash = "sha256:b44b70850f0073b5fcc0b31ede8b4e736860d70e2dbf55701e05d3227a154a67"}, + {file = "watchfiles-0.22.0-cp311-none-win_amd64.whl", hash = "sha256:00f39592cdd124b4ec5ed0b1edfae091567c72c7da1487ae645426d1b0ffcad1"}, + {file = "watchfiles-0.22.0-cp311-none-win_arm64.whl", hash = "sha256:3218a6f908f6a276941422b035b511b6d0d8328edd89a53ae8c65be139073f84"}, + {file = "watchfiles-0.22.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c7b978c384e29d6c7372209cbf421d82286a807bbcdeb315427687f8371c340a"}, + {file = "watchfiles-0.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bd4c06100bce70a20c4b81e599e5886cf504c9532951df65ad1133e508bf20be"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:425440e55cd735386ec7925f64d5dde392e69979d4c8459f6bb4e920210407f2"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68fe0c4d22332d7ce53ad094622b27e67440dacefbaedd29e0794d26e247280c"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a8a31bfd98f846c3c284ba694c6365620b637debdd36e46e1859c897123aa232"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc2e8fe41f3cac0660197d95216c42910c2b7e9c70d48e6d84e22f577d106fc1"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55b7cc10261c2786c41d9207193a85c1db1b725cf87936df40972aab466179b6"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28585744c931576e535860eaf3f2c0ec7deb68e3b9c5a85ca566d69d36d8dd27"}, + {file = "watchfiles-0.22.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:00095dd368f73f8f1c3a7982a9801190cc88a2f3582dd395b289294f8975172b"}, + {file = "watchfiles-0.22.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:52fc9b0dbf54d43301a19b236b4a4614e610605f95e8c3f0f65c3a456ffd7d35"}, + {file = "watchfiles-0.22.0-cp312-none-win32.whl", hash = "sha256:581f0a051ba7bafd03e17127735d92f4d286af941dacf94bcf823b101366249e"}, + {file = "watchfiles-0.22.0-cp312-none-win_amd64.whl", hash = "sha256:aec83c3ba24c723eac14225194b862af176d52292d271c98820199110e31141e"}, + {file = "watchfiles-0.22.0-cp312-none-win_arm64.whl", hash = "sha256:c668228833c5619f6618699a2c12be057711b0ea6396aeaece4ded94184304ea"}, + {file = "watchfiles-0.22.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d47e9ef1a94cc7a536039e46738e17cce058ac1593b2eccdede8bf72e45f372a"}, + {file = "watchfiles-0.22.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:28f393c1194b6eaadcdd8f941307fc9bbd7eb567995232c830f6aef38e8a6e88"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd64f3a4db121bc161644c9e10a9acdb836853155a108c2446db2f5ae1778c3d"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2abeb79209630da981f8ebca30a2c84b4c3516a214451bfc5f106723c5f45843"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cc382083afba7918e32d5ef12321421ef43d685b9a67cc452a6e6e18920890e"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d048ad5d25b363ba1d19f92dcf29023988524bee6f9d952130b316c5802069cb"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:103622865599f8082f03af4214eaff90e2426edff5e8522c8f9e93dc17caee13"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3e1f3cf81f1f823e7874ae563457828e940d75573c8fbf0ee66818c8b6a9099"}, + {file = "watchfiles-0.22.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8597b6f9dc410bdafc8bb362dac1cbc9b4684a8310e16b1ff5eee8725d13dcd6"}, + {file = "watchfiles-0.22.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0b04a2cbc30e110303baa6d3ddce8ca3664bc3403be0f0ad513d1843a41c97d1"}, + {file = "watchfiles-0.22.0-cp38-none-win32.whl", hash = "sha256:b610fb5e27825b570554d01cec427b6620ce9bd21ff8ab775fc3a32f28bba63e"}, + {file = "watchfiles-0.22.0-cp38-none-win_amd64.whl", hash = "sha256:fe82d13461418ca5e5a808a9e40f79c1879351fcaeddbede094028e74d836e86"}, + {file = "watchfiles-0.22.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3973145235a38f73c61474d56ad6199124e7488822f3a4fc97c72009751ae3b0"}, + {file = "watchfiles-0.22.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:280a4afbc607cdfc9571b9904b03a478fc9f08bbeec382d648181c695648202f"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a0d883351a34c01bd53cfa75cd0292e3f7e268bacf2f9e33af4ecede7e21d1d"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9165bcab15f2b6d90eedc5c20a7f8a03156b3773e5fb06a790b54ccecdb73385"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc1b9b56f051209be458b87edb6856a449ad3f803315d87b2da4c93b43a6fe72"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dc1fc25a1dedf2dd952909c8e5cb210791e5f2d9bc5e0e8ebc28dd42fed7562"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc92d2d2706d2b862ce0568b24987eba51e17e14b79a1abcd2edc39e48e743c8"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97b94e14b88409c58cdf4a8eaf0e67dfd3ece7e9ce7140ea6ff48b0407a593ec"}, + {file = "watchfiles-0.22.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:96eec15e5ea7c0b6eb5bfffe990fc7c6bd833acf7e26704eb18387fb2f5fd087"}, + {file = "watchfiles-0.22.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:28324d6b28bcb8d7c1041648d7b63be07a16db5510bea923fc80b91a2a6cbed6"}, + {file = "watchfiles-0.22.0-cp39-none-win32.whl", hash = "sha256:8c3e3675e6e39dc59b8fe5c914a19d30029e36e9f99468dddffd432d8a7b1c93"}, + {file = "watchfiles-0.22.0-cp39-none-win_amd64.whl", hash = "sha256:25c817ff2a86bc3de3ed2df1703e3d24ce03479b27bb4527c57e722f8554d971"}, + {file = "watchfiles-0.22.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b810a2c7878cbdecca12feae2c2ae8af59bea016a78bc353c184fa1e09f76b68"}, + {file = "watchfiles-0.22.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f7e1f9c5d1160d03b93fc4b68a0aeb82fe25563e12fbcdc8507f8434ab6f823c"}, + {file = "watchfiles-0.22.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:030bc4e68d14bcad2294ff68c1ed87215fbd9a10d9dea74e7cfe8a17869785ab"}, + {file = "watchfiles-0.22.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace7d060432acde5532e26863e897ee684780337afb775107c0a90ae8dbccfd2"}, + {file = "watchfiles-0.22.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5834e1f8b71476a26df97d121c0c0ed3549d869124ed2433e02491553cb468c2"}, + {file = "watchfiles-0.22.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:0bc3b2f93a140df6806c8467c7f51ed5e55a931b031b5c2d7ff6132292e803d6"}, + {file = "watchfiles-0.22.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8fdebb655bb1ba0122402352b0a4254812717a017d2dc49372a1d47e24073795"}, + {file = "watchfiles-0.22.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c8e0aa0e8cc2a43561e0184c0513e291ca891db13a269d8d47cb9841ced7c71"}, + {file = "watchfiles-0.22.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2f350cbaa4bb812314af5dab0eb8d538481e2e2279472890864547f3fe2281ed"}, + {file = "watchfiles-0.22.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7a74436c415843af2a769b36bf043b6ccbc0f8d784814ba3d42fc961cdb0a9dc"}, + {file = "watchfiles-0.22.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00ad0bcd399503a84cc688590cdffbe7a991691314dde5b57b3ed50a41319a31"}, + {file = "watchfiles-0.22.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72a44e9481afc7a5ee3291b09c419abab93b7e9c306c9ef9108cb76728ca58d2"}, + {file = "watchfiles-0.22.0.tar.gz", hash = "sha256:988e981aaab4f3955209e7e28c7794acdb690be1efa7f16f8ea5aba7ffdadacb"}, ] [package.dependencies] @@ -1089,20 +1088,20 @@ anyio = ">=3.0.0" [[package]] name = "zipp" -version = "3.18.1" +version = "3.19.2" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.18.1-py3-none-any.whl", hash = "sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b"}, - {file = "zipp-3.18.1.tar.gz", hash = "sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715"}, + {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"}, + {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "a235e030a5f5a1db51d17f8a8d18b9c645b00e75b19dc37e03deaad488c8f1c7" +content-hash = "41042a7edb029d8d732c9c3e1959902e47e3a680a00821ef28d8e8d70d923632" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 1e441ce..e488d29 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -5,15 +5,16 @@ package-mode = false python = "^3.8" motor = "^3.4.0" sspeedup = {version = "^0.25.0", extras = ["logging", "config", "api-litestar"]} -uvicorn = "^0.29.0" +uvicorn = "^0.30.0" httptools = "^0.6.0" uvloop = "^0.19.0" jkit = "^3.0.0a16" +sshared = "^0.6.0" [tool.poetry.group.dev.dependencies] ruff = "^0.4.0" pyright = "^1.1.0" -watchfiles = "^0.21.0" +watchfiles = "^0.22.0" [tool.ruff] @@ -27,4 +28,7 @@ lint.select = [ "S", "SIM", "SLOT", "TCH", "UP", "W" ] -lint.ignore = ["ANN101", "ANN102", "ISC001", "RUF001", "RUF002", "RUF003"] \ No newline at end of file +lint.ignore = [ + "ANN101", "ANN102", "ISC001", "PERF401", + "RUF001", "RUF002", "RUF003" +] \ No newline at end of file diff --git a/backend/requirements-dev.txt b/backend/requirements-dev.txt index 66beeb6..278be48 100644 --- a/backend/requirements-dev.txt +++ b/backend/requirements-dev.txt @@ -1,10 +1,10 @@ -anyio==4.3.0 ; python_version >= "3.8" and python_version < "4.0" -certifi==2024.2.2 ; python_version >= "3.8" and python_version < "4.0" +anyio==4.4.0 ; python_version >= "3.8" and python_version < "4.0" +certifi==2024.6.2 ; python_version >= "3.8" and python_version < "4.0" click==8.1.7 ; python_version >= "3.8" and python_version < "4.0" colorama==0.4.6 ; python_version >= "3.8" and python_version < "4.0" and platform_system == "Windows" dnspython==2.6.1 ; python_version >= "3.8" and python_version < "4.0" exceptiongroup==1.2.1 ; python_version >= "3.8" and python_version < "3.11" -faker==25.0.0 ; python_version >= "3.8" and python_version < "4.0" +faker==25.8.0 ; python_version >= "3.8" and python_version < "4.0" h11==0.14.0 ; python_version >= "3.8" and python_version < "4.0" h2==4.1.0 ; python_version >= "3.8" and python_version < "4.0" hpack==4.0.0 ; python_version >= "3.8" and python_version < "4.0" @@ -17,28 +17,28 @@ idna==3.7 ; python_version >= "3.8" and python_version < "4.0" importlib-metadata==7.1.0 ; python_version >= "3.8" and python_version < "3.10" importlib-resources==6.4.0 ; python_version >= "3.8" and python_version < "3.9" jkit==3.0.0a16 ; python_version >= "3.8" and python_version < "4.0" -litestar==2.8.2 ; python_version >= "3.8" and python_version < "4.0" +litestar==2.9.0 ; python_version >= "3.8" and python_version < "4.0" markdown-it-py==3.0.0 ; python_version >= "3.8" and python_version < "4.0" mdurl==0.1.2 ; python_version >= "3.8" and python_version < "4.0" motor==3.4.0 ; python_version >= "3.8" and python_version < "4.0" msgspec==0.18.6 ; python_version >= "3.8" and python_version < "4.0" multidict==6.0.5 ; python_version >= "3.8" and python_version < "4.0" -nodeenv==1.8.0 ; python_version >= "3.8" and python_version < "4.0" -polyfactory==2.15.0 ; python_version >= "3.8" and python_version < "4.0" -pygments==2.17.2 ; python_version >= "3.8" and python_version < "4.0" -pymongo==4.7.1 ; python_version >= "3.8" and python_version < "4.0" -pyright==1.1.361 ; python_version >= "3.8" and python_version < "4.0" +nodeenv==1.9.1 ; python_version >= "3.8" and python_version < "4.0" +polyfactory==2.16.0 ; python_version >= "3.8" and python_version < "4.0" +pygments==2.18.0 ; python_version >= "3.8" and python_version < "4.0" +pymongo==4.7.3 ; python_version >= "3.8" and python_version < "4.0" +pyright==1.1.367 ; python_version >= "3.8" and python_version < "4.0" python-dateutil==2.9.0.post0 ; python_version >= "3.8" and python_version < "4.0" pyyaml==6.0.1 ; python_version >= "3.8" and python_version < "4.0" -rich-click==1.8.0 ; python_version >= "3.8" and python_version < "4.0" +rich-click==1.8.3 ; python_version >= "3.8" and python_version < "4.0" rich==13.7.1 ; python_version >= "3.8" and python_version < "4.0" -ruff==0.4.2 ; python_version >= "3.8" and python_version < "4.0" -setuptools==69.5.1 ; python_version >= "3.8" and python_version < "4.0" +ruff==0.4.8 ; python_version >= "3.8" and python_version < "4.0" six==1.16.0 ; python_version >= "3.8" and python_version < "4.0" sniffio==1.3.1 ; python_version >= "3.8" and python_version < "4.0" +sshared==0.6.0 ; python_version >= "3.8" and python_version < "4.0" sspeedup[api-litestar,config,logging]==0.25.1 ; python_version >= "3.8" and python_version < "4.0" -typing-extensions==4.11.0 ; python_version >= "3.8" and python_version < "4.0" -uvicorn==0.29.0 ; python_version >= "3.8" and python_version < "4.0" +typing-extensions==4.12.2 ; python_version >= "3.8" and python_version < "4.0" +uvicorn==0.30.1 ; python_version >= "3.8" and python_version < "4.0" uvloop==0.19.0 ; python_version >= "3.8" and python_version < "4.0" -watchfiles==0.21.0 ; python_version >= "3.8" and python_version < "4.0" -zipp==3.18.1 ; python_version >= "3.8" and python_version < "3.10" +watchfiles==0.22.0 ; python_version >= "3.8" and python_version < "4.0" +zipp==3.19.2 ; python_version >= "3.8" and python_version < "3.10" diff --git a/backend/requirements.txt b/backend/requirements.txt index b8d35f9..f7d573d 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -1,10 +1,10 @@ -anyio==4.3.0 ; python_version >= "3.8" and python_version < "4.0" -certifi==2024.2.2 ; python_version >= "3.8" and python_version < "4.0" +anyio==4.4.0 ; python_version >= "3.8" and python_version < "4.0" +certifi==2024.6.2 ; python_version >= "3.8" and python_version < "4.0" click==8.1.7 ; python_version >= "3.8" and python_version < "4.0" colorama==0.4.6 ; python_version >= "3.8" and python_version < "4.0" and platform_system == "Windows" dnspython==2.6.1 ; python_version >= "3.8" and python_version < "4.0" exceptiongroup==1.2.1 ; python_version >= "3.8" and python_version < "3.11" -faker==25.0.0 ; python_version >= "3.8" and python_version < "4.0" +faker==25.8.0 ; python_version >= "3.8" and python_version < "4.0" h11==0.14.0 ; python_version >= "3.8" and python_version < "4.0" h2==4.1.0 ; python_version >= "3.8" and python_version < "4.0" hpack==4.0.0 ; python_version >= "3.8" and python_version < "4.0" @@ -17,23 +17,24 @@ idna==3.7 ; python_version >= "3.8" and python_version < "4.0" importlib-metadata==7.1.0 ; python_version >= "3.8" and python_version < "3.10" importlib-resources==6.4.0 ; python_version >= "3.8" and python_version < "3.9" jkit==3.0.0a16 ; python_version >= "3.8" and python_version < "4.0" -litestar==2.8.2 ; python_version >= "3.8" and python_version < "4.0" +litestar==2.9.0 ; python_version >= "3.8" and python_version < "4.0" markdown-it-py==3.0.0 ; python_version >= "3.8" and python_version < "4.0" mdurl==0.1.2 ; python_version >= "3.8" and python_version < "4.0" motor==3.4.0 ; python_version >= "3.8" and python_version < "4.0" msgspec==0.18.6 ; python_version >= "3.8" and python_version < "4.0" multidict==6.0.5 ; python_version >= "3.8" and python_version < "4.0" -polyfactory==2.15.0 ; python_version >= "3.8" and python_version < "4.0" -pygments==2.17.2 ; python_version >= "3.8" and python_version < "4.0" -pymongo==4.7.1 ; python_version >= "3.8" and python_version < "4.0" +polyfactory==2.16.0 ; python_version >= "3.8" and python_version < "4.0" +pygments==2.18.0 ; python_version >= "3.8" and python_version < "4.0" +pymongo==4.7.3 ; python_version >= "3.8" and python_version < "4.0" python-dateutil==2.9.0.post0 ; python_version >= "3.8" and python_version < "4.0" pyyaml==6.0.1 ; python_version >= "3.8" and python_version < "4.0" -rich-click==1.8.0 ; python_version >= "3.8" and python_version < "4.0" +rich-click==1.8.3 ; python_version >= "3.8" and python_version < "4.0" rich==13.7.1 ; python_version >= "3.8" and python_version < "4.0" six==1.16.0 ; python_version >= "3.8" and python_version < "4.0" sniffio==1.3.1 ; python_version >= "3.8" and python_version < "4.0" +sshared==0.6.0 ; python_version >= "3.8" and python_version < "4.0" sspeedup[api-litestar,config,logging]==0.25.1 ; python_version >= "3.8" and python_version < "4.0" -typing-extensions==4.11.0 ; python_version >= "3.8" and python_version < "4.0" -uvicorn==0.29.0 ; python_version >= "3.8" and python_version < "4.0" +typing-extensions==4.12.2 ; python_version >= "3.8" and python_version < "4.0" +uvicorn==0.30.1 ; python_version >= "3.8" and python_version < "4.0" uvloop==0.19.0 ; python_version >= "3.8" and python_version < "4.0" -zipp==3.18.1 ; python_version >= "3.8" and python_version < "3.10" +zipp==3.19.2 ; python_version >= "3.8" and python_version < "3.10" diff --git a/backend/tools_config.yaml b/backend/tools_config.yaml index 7cb8521..579512d 100644 --- a/backend/tools_config.yaml +++ b/backend/tools_config.yaml @@ -9,12 +9,12 @@ JPEP-FTN-market-analyzer: status: NORMAL reason: null last_update_time: - collection: JPEP_FTN_market - sort_key: fetch_time + collection: FTN_trade_orders + sort_key: fetchTime sort_direction: desc data_update_freq: 十分钟一次 data_count: - collection: JPEP_FTN_market + collection: FTN_trade_orders mode: estimated data_source: 简书积分兑换平台 - 贝市: https://www.jianshubei.com/bei @@ -22,12 +22,12 @@ lottery-analyzer: status: NORMAL reason: null last_update_time: - collection: lottery + collection: lottery_win_records sort_key: time sort_direction: desc data_update_freq: 每天 2:00、9:00、14:00、21:00 data_count: - collection: lottery + collection: lottery_win_records mode: estimated data_source: 简书 - 天天抽奖: https://www.jianshu.com/mobile/lottery @@ -35,12 +35,12 @@ lottery-reward-record-viewer: status: NORMAL reason: null last_update_time: - collection: lottery + collection: lottery_win_records sort_key: time sort_direction: desc data_update_freq: 每天 2:00、9:00、14:00、21:00 data_count: - collection: lottery + collection: lottery_win_records mode: estimated data_source: 简书 - 天天抽奖: https://www.jianshu.com/mobile/lottery @@ -56,12 +56,12 @@ on-rank-article-viewer: status: NORMAL reason: null last_update_time: - collection: article_FP_rank + collection: article_earning_ranking_records sort_key: date sort_direction: desc data_update_freq: 每天凌晨 1:00 data_count: - collection: article_FP_rank + collection: article_earning_ranking_records mode: estimated data_source: 简书 - 简书钻每日发放总榜: https://www.jianshu.com/fp/notice/now diff --git a/backend/utils/config.py b/backend/utils/config.py index ab8477f..ce4e6b4 100644 --- a/backend/utils/config.py +++ b/backend/utils/config.py @@ -31,7 +31,7 @@ def on_reload_success(new_config: _Config) -> None: def on_reload_failed(e: Exception) -> None: from utils.log import logger - logger.error(f"配置文件重载失败:{e}", exception=e) + logger.error(f"配置文件重载失败:{e}", exc=e) set_reload_on_sighup( diff --git a/backend/utils/db.py b/backend/utils/db.py index 8e27146..a78378a 100644 --- a/backend/utils/db.py +++ b/backend/utils/db.py @@ -4,12 +4,7 @@ from utils.config import config -_DB_CLIENT = AsyncIOMotorClient(config.db.host, config.db.port) -_MAIN_DB = _DB_CLIENT[config.db.database] -_JFETCHER_DB = _DB_CLIENT["JFetcherData"] - -RUN_LOG_COLLECTION = _MAIN_DB["run_log"] -ARTICLE_FP_RANK_COLLECTION = _JFETCHER_DB["article_FP_rank"] -LOTTERY_COLLECTION = _JFETCHER_DB["lottery_data"] -LP_COLLECTIONS_COLLECTION = _JFETCHER_DB["LP_collections"] -JPEP_FTN_MACKET_COLLECTION = _JFETCHER_DB["JPEP_FTN_macket"] +_CLIENT = AsyncIOMotorClient(config.db.host, config.db.port) +MAIN_DB = _CLIENT[config.db.database] +JIANSHU_DB = _CLIENT.jianshu +JPEP_DB = _CLIENT.jpep diff --git a/backend/utils/log.py b/backend/utils/log.py index a3d72f5..458cccf 100644 --- a/backend/utils/log.py +++ b/backend/utils/log.py @@ -1,10 +1,13 @@ -from sspeedup.logging.run_logger import RunLogger +from pymongo import MongoClient +from sshared.logging import Logger from utils.config import config -from utils.db import RUN_LOG_COLLECTION -logger = RunLogger( - save_level=config.log.save_level, - print_level=config.log.print_level, - mongo_collection=RUN_LOG_COLLECTION, +_client = MongoClient() + +logger = Logger( + # TODO + save_level=config.log.save_level.value, # type: ignore + display_level=config.log.print_level.value, # type: ignore + save_collection=_client[config.db.database].log, ) diff --git a/backend/utils/tools_config.py b/backend/utils/tools_config.py index 18b97ee..6b5c893 100644 --- a/backend/utils/tools_config.py +++ b/backend/utils/tools_config.py @@ -4,10 +4,11 @@ from msgspec import Struct from msgspec.yaml import decode -_TOOLS_CONFIG_STRUCT_CONFIG: Dict[str, Any] = { +_TOOLS_CONFIG_STRUCT_META: Dict[str, Any] = { "frozen": True, "kw_only": True, "forbid_unknown_fields": True, + "gc": False, } @@ -17,18 +18,18 @@ class ToolStatus(Enum): DOWNGRADED = "DOWNGRADED" -class _DataUpdateTimeItem(Struct, **_TOOLS_CONFIG_STRUCT_CONFIG): +class _DataUpdateTimeItem(Struct, **_TOOLS_CONFIG_STRUCT_META): collection: str sort_key: str sort_direction: Literal["asc", "desc"] -class _DataCountItem(Struct, **_TOOLS_CONFIG_STRUCT_CONFIG): +class _DataCountItem(Struct, **_TOOLS_CONFIG_STRUCT_META): collection: str mode: Literal["accurate", "estimated"] -class _ToolConfig(Struct, **_TOOLS_CONFIG_STRUCT_CONFIG): +class _ToolConfig(Struct, **_TOOLS_CONFIG_STRUCT_META): status: ToolStatus reason: Optional[str] last_update_time: Optional[_DataUpdateTimeItem] diff --git a/docker-compose.yml b/docker-compose.yml index 40556c6..017f1a1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,7 +7,7 @@ networks: services: frontend: - image: jtools-frontend:3.13.0 + image: jtools-frontend:3.14.0 container_name: jtools-frontend build: dockerfile: Dockerfile.frontend @@ -24,7 +24,7 @@ services: delay: 5s max_attempts: 3 backend: - image: jtools-backend:3.13.0 + image: jtools-backend:3.14.0 container_name: jtools-backend build: dockerfile: Dockerfile.backend diff --git a/frontend/bun.lockb b/frontend/bun.lockb index 6170897..7e487c9 100644 Binary files a/frontend/bun.lockb and b/frontend/bun.lockb differ diff --git a/frontend/package.json b/frontend/package.json index 775bf50..d6ed7f0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "jtools", "private": true, - "version": "3.13.0", + "version": "3.14.0", "type": "module", "scripts": { "dev": "vite", @@ -14,28 +14,28 @@ "biome-ci": "biome ci ." }, "dependencies": { - "@mantine/hooks": "^7.3.0", - "@preact/preset-vite": "^2.7.0", - "@preact/signals": "^1.2.0", + "@mantine/hooks": "^7.10.1", + "@preact/preset-vite": "^2.8.2", + "@preact/signals": "^1.2.3", "@sscreator/ui": "^0.27.0", - "@unocss/reset": "^0.58.0", - "clsx": "^2.1.0", - "dayjs": "^1.11.0", + "@unocss/reset": "^0.58.9", + "clsx": "^2.1.1", + "dayjs": "^1.11.11", "echarts": "^5.5.0", "echarts-wordcloud": "^2.1.0", - "preact": "^10.21.0", - "react-hot-toast": "^2.4.0", - "react-qr-code": "^2.0.0", - "resize-observer": "^1.0.0", - "swr": "^2.2.0", - "unocss": "^0.58.0", - "vite": "^5.0.0", - "vite-plugin-compression": "^0.5.0", + "preact": "^10.22.0", + "react-hot-toast": "^2.4.1", + "react-qr-code": "^2.0.14", + "resize-observer": "^1.0.4", + "swr": "^2.2.5", + "unocss": "^0.58.9", + "vite": "^5.2.13", + "vite-plugin-compression": "^0.5.1", "vite-plugin-pwa": "^0.20.0", - "wouter-preact": "^3.1.0" + "wouter-preact": "^3.2.0" }, "devDependencies": { - "@biomejs/biome": "^1.5.0", + "@biomejs/biome": "^1.8.1", "rollup-plugin-visualizer": "^5.12.0" } } diff --git a/frontend/src/thanks.json b/frontend/src/thanks.json index 00e6637..7e3a59d 100644 --- a/frontend/src/thanks.json +++ b/frontend/src/thanks.json @@ -161,6 +161,24 @@ "user_name": "平原雪", "user_url": "https://www.jianshu.com/u/754f9b7b7417", "reward": 50 + }, + { + "time": "2024-06-03", + "type": "数据异常", + "module": "上榜文章查询工具", + "desc": "部分上榜数据缺失", + "user_name": "睿希颖瑶", + "user_url": "https://www.jianshu.com/u/4b86da352f87", + "reward": 80 + }, + { + "time": "2024-06-08", + "type": "数据异常", + "module": "上榜文章查询工具", + "desc": "部分上榜数据缺失", + "user_name": "非村", + "user_url": "https://www.jianshu.com/u/df68a42402fc", + "reward": 80 } ], "opensourcePackages": {