默认开启网页控制台

This commit is contained in:
Wuyi无疑 2023-03-21 23:17:01 +08:00
parent f7c2ac1732
commit 8ec712cdd0
13 changed files with 998 additions and 288 deletions

1
.gitignore vendored
View File

@ -666,3 +666,4 @@ config.json
res_data res_data
GsData.db GsData.db
GenshinUID GenshinUID
data

View File

@ -1,13 +1,17 @@
import sys import sys
import asyncio import asyncio
from typing import Dict
from pathlib import Path from pathlib import Path
import uvicorn import uvicorn
from msgspec import json as msgjson from msgspec import json as msgjson
from starlette.requests import Request
from fastapi import FastAPI, WebSocket, WebSocketDisconnect from fastapi import FastAPI, WebSocket, WebSocketDisconnect
sys.path.append(str(Path(__file__).parents[1])) sys.path.append(str(Path(__file__).parents[1]))
from gsuid_core.sv import SL # noqa: E402
from gsuid_core.gss import gss # noqa: E402 from gsuid_core.gss import gss # noqa: E402
from gsuid_core.logger import logger # noqa: E402
from gsuid_core.config import core_config # noqa: E402 from gsuid_core.config import core_config # noqa: E402
from gsuid_core.handler import handle_event # noqa: E402 from gsuid_core.handler import handle_event # noqa: E402
from gsuid_core.models import MessageReceive # noqa: E402 from gsuid_core.models import MessageReceive # noqa: E402
@ -18,7 +22,7 @@ HOST = core_config.get_config('HOST')
PORT = int(core_config.get_config('PORT')) PORT = int(core_config.get_config('PORT'))
@app.websocket("/ws/{bot_id}") @app.websocket('/ws/{bot_id}')
async def websocket_endpoint(websocket: WebSocket, bot_id: str): async def websocket_endpoint(websocket: WebSocket, bot_id: str):
bot = await gss.connect(websocket, bot_id) bot = await gss.connect(websocket, bot_id)
@ -39,6 +43,12 @@ async def websocket_endpoint(websocket: WebSocket, bot_id: str):
@app.on_event('startup') @app.on_event('startup')
async def startup_event(): async def startup_event():
try:
from gsuid_core.webconsole.__init__ import start_check
await start_check()
except ImportError:
logger.warning('未加载GenshinUID...网页控制台启动失败...')
await start_scheduler() await start_scheduler()
@ -48,4 +58,20 @@ async def shutdown_event():
if __name__ == "__main__": if __name__ == "__main__":
try:
from gsuid_core.webconsole.mount_app import site
@app.post('/setSV/{name}')
@site.auth.requires('admin')
async def _set_SV(request: Request, data: Dict, name: str):
if name in SL.lst:
sv = SL.lst[name]
data['pm'] = int(data['pm'])
data['black_list'] = data['black_list'].split(';')
sv.set(**data)
site.mount_app(app)
except ImportError:
logger.warning('未加载GenshinUID...网页控制台启动失败...')
uvicorn.run(app, host=HOST, port=PORT) uvicorn.run(app, host=HOST, port=PORT)

View File

@ -61,7 +61,10 @@ async def handle_event(ws: _Bot, msg: MessageReceive):
if ( if (
SL.lst[sv].enabled SL.lst[sv].enabled
and user_pm <= SL.lst[sv].pm and user_pm <= SL.lst[sv].pm
and msg.group_id not in SL.lst[sv].black_list and (
msg.group_id not in SL.lst[sv].black_list
or msg.user_id not in SL.lst[sv].black_list
)
and True and True
if SL.lst[sv].area == 'ALL' if SL.lst[sv].area == 'ALL'
or (msg.group_id and SL.lst[sv].area == 'GROUP') or (msg.group_id and SL.lst[sv].area == 'GROUP')

View File

@ -0,0 +1,29 @@
from sqlmodel import SQLModel
from gsuid_core.logger import logger
from gsuid_core.config import core_config
from gsuid_core.webconsole.mount_app import site
async def start_check():
# 语言本地化
from fastapi_user_auth import i18n as user_auth_i18n
from fastapi_amis_admin import i18n as admin_auth_i18n
HOST = core_config.get_config('HOST')
PORT = core_config.get_config('PORT')
admin_auth_i18n.set_language('zh_CN')
user_auth_i18n.set_language('zh_CN')
logger.info('尝试挂载WebConsole')
await site.auth.db.async_run_sync(
SQLModel.metadata.create_all, is_session=False # type:ignore
)
await site.db.async_run_sync(
SQLModel.metadata.create_all, is_session=False # type:ignore
) # type:ignore
# 创建默认测试用户, 请及时修改密码!!!
await site.auth.create_role_user('admin')
logger.info(('WebConsole挂载成功:' f'http://{HOST}:{PORT}/genshinuid'))

View File

@ -0,0 +1,284 @@
from typing import List, Literal
from gsuid_core.sv import SL
def get_sv_panel(
name: str = '',
pm: int = 3,
priority: int = 5,
enabled: bool = True,
area: Literal['GROUP', 'DIRECT', 'ALL'] = 'ALL',
black_list: List = [],
):
api = f'/setSV/{name}'
card = {
"type": "service",
"body": {
'type': 'card',
'header': {'title': '', 'subTitle': ''},
'body': [
{
'type': 'flex',
'className': 'p-1',
'items': [
{
'type': 'container',
'size': 'xs',
'style': {
'position': 'static',
'display': 'block',
'flex': '1 1 auto',
'flexGrow': 1,
'flexBasis': 'auto',
},
'wrapperBody': False,
'isFixedHeight': False,
'isFixedWidth': False,
'id': 'u:bafbdfce89c2',
'body': [
{
'type': 'tpl',
'tpl': name,
'inline': True,
'wrapperComponent': '',
'id': 'u:cd523cbd8f0c',
'style': {
'fontFamily': '',
'fontSize': 25,
},
},
{
'type': 'switch',
'label': '总开关',
'option': '开启/关闭功能',
'name': 'enabled',
'falseValue': False,
'trueValue': True,
'id': 'u:d739bc85f307',
'value': enabled,
},
],
},
{
'type': 'container',
'size': 'xs',
'style': {
'position': 'static',
'display': 'block',
'flex': '1 1 auto',
'flexGrow': 1,
'flexBasis': 'auto',
},
'wrapperBody': False,
'isFixedHeight': False,
'isFixedWidth': False,
'id': 'u:80670a4807f2',
},
{
'type': 'container',
'body': [],
'size': 'xs',
'style': {
'position': 'static',
'display': 'block',
'flex': '1 1 auto',
'flexGrow': 1,
'flexBasis': 'auto',
},
'wrapperBody': False,
'isFixedHeight': False,
'isFixedWidth': False,
'id': 'u:f24811f21e93',
},
],
'style': {'position': 'static'},
'direction': 'row',
'justify': 'flex-start',
'alignItems': 'stretch',
'id': 'u:2a2b198f141b',
'label': '',
},
{
'type': 'flex',
'className': 'p-1',
'items': [
{
'type': 'container',
'body': [
{
'type': 'select',
'label': '权限控制',
'name': 'pm',
'options': [
{'label': '超级管理员', 'value': '1'},
{'label': '管理员', 'value': '2'},
{'label': '正常', 'value': '3'},
{'label': '几乎所有人', 'value': '4'},
{'label': '所有人', 'value': '5'},
],
'id': 'u:c71f20b605d4',
'multiple': False,
'value': str(pm),
}
],
'size': 'xs',
'style': {
'position': 'static',
'display': 'block',
'flex': '1 1 auto',
'flexGrow': 1,
'flexBasis': 'auto',
},
'wrapperBody': False,
'isFixedHeight': False,
'isFixedWidth': False,
'id': 'u:bafbdfce89c2',
},
{
'type': 'container',
'body': [
{
'type': 'input-number',
'label': '命令优先级',
'name': 'priority',
'keyboard': True,
'id': 'u:0b72c9b8086d',
'step': 1,
'value': priority,
}
],
'size': 'xs',
'style': {
'position': 'static',
'display': 'block',
'flex': '1 1 auto',
'flexGrow': 1,
'flexBasis': 'auto',
},
'wrapperBody': False,
'isFixedHeight': False,
'isFixedWidth': False,
'id': 'u:80670a4807f2',
},
{
'type': 'container',
'body': [
{
'type': 'select',
'label': '作用范围',
'name': 'area',
'options': [
{'label': '全局', 'value': 'ALL'},
{'label': '仅限私聊', 'value': 'DIRECT'},
{'label': '仅限群聊', 'value': 'GROUP'},
],
'id': 'u:88e66f806556',
'multiple': False,
'value': area,
}
],
'size': 'xs',
'style': {
'position': 'static',
'display': 'block',
'flex': '1 1 auto',
'flexGrow': 1,
'flexBasis': 'auto',
},
'wrapperBody': False,
'isFixedHeight': False,
'isFixedWidth': False,
'id': 'u:f24811f21e93',
},
],
'style': {'position': 'static'},
'direction': 'row',
'justify': 'flex-start',
'alignItems': 'stretch',
'id': 'u:2a2b198f141b',
'label': '',
},
{
'type': 'flex',
'className': 'p-1',
'items': [
{
'type': 'container',
'size': 'xs',
'body': [
{
'type': 'input-text',
'label': '黑名单(以;为分割)',
'name': 'black_list',
'id': 'u:ab168d425936',
'value': ';'.join(black_list),
}
],
'wrapperBody': False,
'style': {'flex': '0 0 auto', 'display': 'block'},
'id': 'u:48c938f71548',
}
],
'direction': 'column',
'justify': 'center',
'alignItems': 'stretch',
'id': 'u:a7b2f1bbc0a8',
'label': '',
},
],
'actions': [
{
'type': 'button',
'label': '确认修改',
'id': 'u:5784cfaa5c0a',
'actionType': 'ajax',
'api': api,
'onEvent': {
'click': {
'weight': 0,
'actions': [
{
'args': {
'msgType': 'success',
'position': 'top-center',
'closeButton': True,
'showIcon': True,
'msg': '成功设置!',
'timeout': 100,
},
'actionType': 'toast',
}
],
}
},
}
],
'id': 'u:69b06813bfbe',
},
"id": "u:4c2981f6a055",
}
return card
def get_sv_page():
page = {
'type': 'page',
'title': '功能管理',
'body': [],
'id': 'u:a9be7e0dc676',
}
for sv_name in SL.lst:
sv = SL.lst[sv_name]
panel = get_sv_panel(
sv.name,
sv.pm,
sv.priority,
sv.enabled,
sv.area, # type:ignore
sv.black_list,
)
page['body'].append(panel)
return page

View File

@ -0,0 +1,114 @@
import fastapi_amis_admin
from gsuid_core.plugins.GenshinUID.GenshinUID.version import GenshinUID_version
login_html = '''
<p align='center'>
<a href='https://github.com/KimigaiiWuyi/GenshinUID/'>
<img src='https://s2.loli.net/2022/01/31/kwCIl3cF1Z2GxnR.png'
width='256' height='256' alt='GenshinUID'>
</a>
</p>
<h1 align='center'>GsCore WebConsole</h1>
<h4 align='center'>
基于
<a href='https://github.com/Ice-Cirno/HoshinoBot' target='_blank'>
HoshinoBot
</a>
/
<a href='https://github.com/nonebot/nonebot2' target='_blank'>NoneBot2</a>
/
<a href='https://bot.q.qq.com/wiki/#' target='_blank'>QQ官方频道Bot</a>
的原神多功能插件
</h4>
<div align='center'>
<a href='https://github.com/KimigaiiWuyi/GenshinUID/wiki' target='_blank'>
安装文档</a> &nbsp; · &nbsp;
<a href='https://github.com/KimigaiiWuyi/GenshinUID/wiki/File5-「指令列表」'
target='_blank'>指令列表</a> &nbsp; · &nbsp;
<a href='https://github.com/KimigaiiWuyi/GenshinUID/issues/226'>常见问题</a>
</div>
'''
footer_html = f'''
<p align='right'>
<div class='p-2 text-center bg-light'>Copyright © 2021 - 2022
<a href='https://github.com/KimigaiiWuyi/GenshinUID' target='_blank'
class='link-secondary'>GenshinUID {GenshinUID_version}
</a>
X
<a target='_blank'
href='https://github.com/amisadmin/fastapi_amis_admin/'
class='link-secondary' rel='noopener'>
fastapi_amis_admin {fastapi_amis_admin.__version__}
</a>
</div>
</p>
'''
gsuid_webconsole_help = '''
## 初次使用
欢迎进入网页控制台!
Admin账户可以通过左侧的选项进入不同的数据库直接修改,**首次登陆的Admin账户别忘了修改你的密码!**
普通账户可以通过左侧的选项进行绑定CK或者SK
未来还会加入更多功能!
## 丨我该如何获取Cookies[#92](https://github.com/KimigaiiWuyi/GenshinUID/issues/92)
[@RemKeeper](https://github.com/RemKeeper)
```js
var cookie = document.cookie;
var Str_Num = cookie.indexOf('_MHYUUID=');
cookie = cookie.substring(Str_Num);
var ask = confirm('Cookie:' + cookie + '按确认然后粘贴至Cookies或者Login_ticket选框内');
if (ask == true) {
copy(cookie);
msg = cookie
} else {
msg = 'Cancel'
}
```
1. 复制上面全部代码然后打开[米游社BBS](https://bbs.mihoyo.com/ys/)
2. 在页面上右键检查或者Ctrl+Shift+i
3. 选择控制台Console粘贴回车在弹出的窗口点确认点完自动复制
4. 然后在和机器人的私聊窗口粘贴发送即可
**警告Cookies属于个人隐私其效用相当于账号密码请勿随意公开**
## 丨获取米游社Stoken([AutoMihoyoBBS](https://github.com/Womsxd/AutoMihoyoBBS))
```js
var cookie = document.cookie;
var ask = confirm('Cookie:' + cookie + '按确认然后粘贴至Cookies或者Login_ticket选框内');
if (ask == true) {
copy(cookie);
msg = cookie
} else {
msg = 'Cancel'
}
```
1. 复制上面全部代码然后打开[米游社账户登录界面](http://user.mihoyo.com/)
2. 在页面上右键检查或者Ctrl+Shift+i
3. 选择控制台Console粘贴回车在弹出的窗口点确认点完自动复制
4. 然后在和机器人的私聊窗口粘贴发送即可
**警告Cookies属于个人隐私其效用相当于账号密码请勿随意公开**
## 获取CK通则
**如果获取到的Cookies字段不全无法通过校验**
**推荐重新登陆米游社再进行获取**
## 网页端 #92 [@RemKeeper](https://github.com/RemKeeper)
[通过网页控制台简易获取Cookies](https://github.com/KimigaiiWuyi/GenshinUID/issues/92)
## 安卓 [@shirokurakana](https://github.com/shirokurakana)
[通过额外APP获取Cookies](https://github.com/KimigaiiWuyi/GenshinUID/issues/203)
## IOS [@741807012](https://github.com/741807012)
[通过快捷指令获取Cookies](https://github.com/KimigaiiWuyi/GenshinUID/issues/201)
'''

View File

@ -0,0 +1,71 @@
import contextlib
from fastapi import Request
from fastapi_user_auth.auth import AuthRouter
from starlette.responses import RedirectResponse
from fastapi_user_auth import admin as user_auth_admin
from fastapi_amis_admin.admin import admin as amis_admin
from fastapi_amis_admin.amis.components import App, Tpl, Grid, Html, Page
from gsuid_core.webconsole.utils import overrides
from gsuid_core.webconsole.html import login_html, footer_html
@overrides(user_auth_admin)
def attach_page_head(page: Page) -> Page:
page.body = [
Html(html=login_html),
Grid(
columns=[
{'body': [page.body], 'lg': 3, 'md': 4, 'valign': 'middle'}
],
align='center',
valign='middle',
),
]
return page
@overrides(amis_admin.AdminApp)
async def _get_page_as_app(self, request: Request) -> App:
app = App()
app.brandName = self.site.settings.site_title
app.header = Tpl(
className='w-full',
tpl='''
<div class='flex justify-between'>
<div>
<a href='https://github.com/KimigaiiWuyi/GenshinUID'
target='_blank' title='Copyright'>
<i class='fa fa-github fa-2x'></i>
</a>
</div>
</div>
''',
) # type: ignore
app.footer = footer_html
children = await self.get_page_schema_children(request)
app.pages = [{'children': children}] if children else [] # type: ignore
return app
@property
@overrides(AuthRouter)
def route_logout(self):
@self.auth.requires()
async def user_logout(request: Request):
token_value = request.auth.backend.get_user_token(request=request)
with contextlib.suppress(Exception):
await self.auth.backend.token_store.destroy_token(
token=token_value
)
response = RedirectResponse(url="/genshinuid")
response.delete_cookie("Authorization")
return response
return user_logout
amis_admin.AdminApp._get_page_as_app = _get_page_as_app
user_auth_admin.attach_page_head = attach_page_head
AuthRouter.route_logout = route_logout # type:ignore

View File

@ -0,0 +1,10 @@
from fastapi_user_auth.auth.models import User
from fastapi_amis_admin.models.fields import Field
class WebUser(User, table=True):
bot_id: str = Field(None, title='用户平台') # type:ignore
user_id: str = Field(None, title='用户ID') # type:ignore
parent_id: int = Field(
None, title='Superior', foreign_key='auth_user.id'
) # type:ignore

View File

@ -0,0 +1,399 @@
# flake8: noqa
import platform
from typing import Any, Callable, Optional
from starlette import status
from pydantic import BaseModel
from fastapi_user_auth.auth import Auth
from fastapi_amis_admin import amis, admin
from fastapi_user_auth.app import UserAuthApp
from sqlalchemy_database import AsyncDatabase
from fastapi_amis_admin.crud import BaseApiOut
from fastapi_user_auth.site import AuthAdminSite
from fastapi_amis_admin.models.fields import Field
from fastapi_amis_admin.admin.site import APIDocsApp
from fastapi_amis_admin.admin.settings import Settings
from fastapi_user_auth.auth.models import UserRoleLink
from fastapi_amis_admin.utils.translation import i18n as _
from fastapi import Depends, FastAPI, Request, HTTPException
from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine
from fastapi_amis_admin.amis.constants import LevelEnum, DisplayModeEnum
from fastapi_user_auth.admin import (
FormAdmin,
UserRegFormAdmin,
UserLoginFormAdmin,
)
from fastapi_amis_admin.amis.components import (
App,
Form,
Grid,
Page,
Alert,
Action,
Property,
ActionType,
Horizontal,
PageSchema,
ButtonToolbar,
)
from gsuid_core.data_store import get_res_path
from gsuid_core.webconsole.models import WebUser
from gsuid_core.webconsole.html import gsuid_webconsole_help
from gsuid_core.webconsole.create_sv_panel import get_sv_page
from gsuid_core.plugins.GenshinUID.GenshinUID.utils.database import db_url
from gsuid_core.plugins.GenshinUID.GenshinUID.version import GenshinUID_version
from gsuid_core.plugins.GenshinUID.GenshinUID.genshinuid_user.add_ck import (
_deal_ck,
)
from gsuid_core.webconsole.login_page import ( # noqa # 不要删
AuthRouter,
amis_admin,
user_auth_admin,
)
from gsuid_core.plugins.GenshinUID.GenshinUID.gsuid_utils.database.models import (
GsBind,
GsPush,
GsUser,
GsCache,
)
class GsLoginFormAdmin(UserLoginFormAdmin):
@property
def route_page(self) -> Callable:
async def route(
request: Request, result=Depends(super(FormAdmin, self).route_page)
):
if request.user:
raise HTTPException(
status_code=status.HTTP_307_TEMPORARY_REDIRECT,
detail='已经登陆过啦~',
headers={
'location': request.query_params.get('redirect')
or '/genshinuid'
},
)
return result
return route
async def get_form(self, request: Request) -> Form:
form = await super(user_auth_admin.UserLoginFormAdmin, self).get_form(
request
)
form.body.sort(
key=lambda form_item: form_item.type, reverse=True # type: ignore
)
form.update_from_kwargs(
title='',
mode=DisplayModeEnum.horizontal,
submitText=_('登陆'),
actionsClassName='no-border m-none p-none',
panelClassName='',
wrapWithPanel=True,
horizontal=Horizontal(left=3, right=9),
actions=[
ButtonToolbar(
buttons=[
ActionType.Link(
actionType='link',
link=f'{self.router_path}/reg',
label=_('Sign up'),
),
Action(
actionType='submit',
label=_('Sign in'),
level=LevelEnum.primary,
),
]
)
],
)
form.redirect = request.query_params.get('redirect') or '/genshinuid'
return form
class GsUserRegFormAdmin(UserRegFormAdmin):
async def get_form(self, request: Request) -> Form:
form = await super().get_form(request)
form.redirect = request.query_params.get('redirect') or '/genshinuid'
form.update_from_kwargs(
title='',
mode=DisplayModeEnum.horizontal,
submitText=_('注册'),
actionsClassName='no-border m-none p-none',
panelClassName='',
wrapWithPanel=True,
horizontal=Horizontal(left=3, right=9),
actions=[
ButtonToolbar(
buttons=[
ActionType.Link(
actionType='link',
link=f'{self.router_path}/login',
label=_('登陆'),
),
Action(
actionType='submit',
label=_('注册'),
level=LevelEnum.primary,
),
]
)
],
)
return form
class GsUserAuthApp(UserAuthApp):
UserLoginFormAdmin = GsLoginFormAdmin
UserRegFormAdmin = GsUserRegFormAdmin
class GsAuthAdminSite(AuthAdminSite):
UserAuthApp = GsUserAuthApp
# 自定义后台管理站点
class GsAdminSite(GsAuthAdminSite):
def __init__(
self,
settings: Settings,
fastapi: FastAPI = None, # type: ignore
engine: AsyncEngine = None, # type: ignore
auth: Auth = None, # type: ignore
):
super().__init__(settings, fastapi, engine, auth)
async def get_page(self, request: Request) -> App:
app = await super().get_page(request)
app.brandName = 'GsCore网页控制台'
app.logo = 'https://s2.loli.net/2022/01/31/kwCIl3cF1Z2GxnR.png'
return app
settings = Settings(
database_url_async=f'sqlite+aiosqlite:///{db_url}',
database_url='',
site_path='/genshinuid',
site_icon='https://s2.loli.net/2022/01/31/kwCIl3cF1Z2GxnR.png',
site_title='GsCore - 网页控制台',
language='zh_CN',
amis_theme='ang',
)
site = GsAdminSite(settings)
site.auth.user_model = WebUser
@site.register_admin
class AmisPageAdmin(admin.PageAdmin):
page_schema = '入门使用'
page = Page.parse_obj(
{
'type': 'page',
'body': {
'type': 'markdown',
'value': f'{gsuid_webconsole_help}',
},
}
)
@site.register_admin
class UserBindFormAdmin(admin.FormAdmin):
page_schema = PageSchema(label='绑定CK或SK', icon='fa fa-link') # type: ignore
async def get_form(self, request: Request) -> Form:
form = await super().get_form(request)
form.body.sort(key=lambda form_item: form_item.type, reverse=True) # type: ignore
form.update_from_kwargs(
title='',
mode=DisplayModeEnum.horizontal,
submitText='绑定',
actionsClassName='no-border m-none p-none',
panelClassName='',
wrapWithPanel=True,
horizontal=Horizontal(left=3, right=9),
actions=[
ButtonToolbar(
buttons=[
Action(
actionType='submit',
label='绑定',
level=LevelEnum.primary,
)
]
)
],
)
return form
async def get_page(self, request: Request) -> Page:
page = await super().get_page(request)
page.body = [
Alert(
level='warning',
body='CK获取可查看左侧栏 [入门使用] 相关细则!',
),
amis.Divider(),
Grid(
columns=[
{
'body': [page.body],
'lg': 10,
'md': 10,
'valign': 'middle',
}
],
align='center',
valign='middle',
),
]
return page
# 创建表单数据模型
class schema(BaseModel):
bot_id: str = Field(..., title='平台ID') # type: ignore
user_id: str = Field(..., title='用户ID', min_length=3, max_length=30) # type: ignore
cookie: str = Field(..., title='Cookie或者Login_ticket') # type: ignore
# 处理表单提交数据
async def handle(
self, request: Request, data: schema, **kwargs
) -> BaseApiOut[Any]:
try:
im = await _deal_ck(data.bot_id, data.cookie, data.user_id)
except Exception:
return BaseApiOut(status=-1, msg='你输入的CK可能已经失效,请按照[入门使用]进行操作!')
ok_num = im.count('成功')
if ok_num < 1:
return BaseApiOut(status=-1, msg=im)
else:
return BaseApiOut(msg=im)
class GsAdminModel(admin.ModelAdmin):
async def has_page_permission(
self,
request: Request,
obj: Optional[admin.ModelAdmin] = None,
action: Optional[str] = None,
) -> bool:
return await super().has_page_permission(
request
) and await request.auth.requires(roles='admin', response=False)(
request
)
@site.register_admin
class UserAuth(GsAdminModel):
pk_name = 'user_id'
page_schema = PageSchema(label='用户授权', icon='fa fa-user-o')
# 配置管理模型
model = UserRoleLink
@site.register_admin
class CKadmin(GsAdminModel):
pk_name = 'id'
page_schema = PageSchema(label='CK管理', icon='fa fa-database')
# 配置管理模型
model = GsUser
@site.register_admin
class pushadmin(GsAdminModel):
pk_name = 'id'
page_schema = PageSchema(label='推送管理', icon='fa fa-bullhorn')
# 配置管理模型
model = GsPush
@site.register_admin
class cacheadmin(GsAdminModel):
pk_name = 'id'
page_schema = PageSchema(label='缓存管理', icon='fa fa-recycle')
# 配置管理模型
model = GsCache
@site.register_admin
class bindadmin(GsAdminModel):
pk_name = 'id'
page_schema = PageSchema(label='绑定管理', icon='fa fa-users')
# 配置管理模型
model = GsBind
# 注册自定义首页
@site.register_admin
class MyHomeAdmin(admin.HomeAdmin):
group_schema = None
page_schema = PageSchema(
label=('主页'),
icon='fa fa-home',
url='/home',
isDefaultPage=True,
sort=100,
)
page_path = '/home'
async def get_page(self, request: Request) -> Page:
page = await super().get_page(request)
page.body = [
Alert(
level='warning',
body=' 警告: 初始admin账号请务必前往「用户授权」➡「用户管理」处修改密码!',
),
amis.Divider(),
Property(
title='GenshinUID Info',
column=4,
items=[
Property.Item(label='system', content=platform.system()),
Property.Item(
label='python', content=platform.python_version()
),
Property.Item(label='version', content=GenshinUID_version),
Property.Item(label='license', content='GPLv3'),
],
),
]
return page
@site.register_admin
class SVManagePage(admin.PageAdmin):
page_schema = PageSchema(
label=('修改配置'),
icon='fa fa-sliders',
url='/SVmanage',
isDefaultPage=True,
sort=100,
)
page = Page.parse_obj(get_sv_page())
async def has_page_permission(
self,
request: Request,
obj: Optional[admin.ModelAdmin] = None,
action: Optional[str] = None,
) -> bool:
return await super().has_page_permission(
request
) and await request.auth.requires(roles='admin', response=False)(
request
)
# 取消注册默认管理类
site.unregister_admin(admin.HomeAdmin, APIDocsApp)

View File

@ -0,0 +1,15 @@
from typing import TypeVar, Callable
T_Wrapped = TypeVar("T_Wrapped", bound=Callable)
def overrides(InterfaceClass: object) -> Callable[[T_Wrapped], T_Wrapped]:
"""标记一个方法为父类 interface 的 implement"""
def overrider(func: T_Wrapped) -> T_Wrapped:
assert func.__name__ in dir(
InterfaceClass
), f"Error method: {func.__name__}"
return func
return overrider

290
poetry.lock generated
View File

@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry and should not be changed by hand. # This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand.
[[package]] [[package]]
name = "aiofiles" name = "aiofiles"
@ -169,36 +169,6 @@ doc = ["packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
test = ["contextlib2", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (<0.15)", "uvloop (>=0.15)"] test = ["contextlib2", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (<0.15)", "uvloop (>=0.15)"]
trio = ["trio (>=0.16,<0.22)"] trio = ["trio (>=0.16,<0.22)"]
[[package]]
name = "apscheduler"
version = "3.10.1"
description = "In-process task scheduler with Cron-like capabilities"
category = "main"
optional = false
python-versions = ">=3.6"
files = [
{file = "APScheduler-3.10.1-py3-none-any.whl", hash = "sha256:e813ad5ada7aff36fb08cdda746b520531eaac7757832abc204868ba78e0c8f6"},
{file = "APScheduler-3.10.1.tar.gz", hash = "sha256:0293937d8f6051a0f493359440c1a1b93e882c57daf0197afeff0e727777b96e"},
]
[package.dependencies]
pytz = "*"
setuptools = ">=0.7"
six = ">=1.4.0"
tzlocal = ">=2.0,<3.0.0 || >=4.0.0"
[package.extras]
doc = ["sphinx", "sphinx-rtd-theme"]
gevent = ["gevent"]
mongodb = ["pymongo (>=3.0)"]
redis = ["redis (>=3.0)"]
rethinkdb = ["rethinkdb (>=2.4.0)"]
sqlalchemy = ["sqlalchemy (>=1.4)"]
testing = ["pytest", "pytest-asyncio", "pytest-cov", "pytest-tornado5"]
tornado = ["tornado (>=4.3)"]
twisted = ["twisted"]
zookeeper = ["kazoo"]
[[package]] [[package]]
name = "async-timeout" name = "async-timeout"
version = "4.0.2" version = "4.0.2"
@ -230,35 +200,6 @@ docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-
tests = ["attrs[tests-no-zope]", "zope.interface"] tests = ["attrs[tests-no-zope]", "zope.interface"]
tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"]
[[package]]
name = "backports-zoneinfo"
version = "0.2.1"
description = "Backport of the standard library zoneinfo module"
category = "main"
optional = false
python-versions = ">=3.6"
files = [
{file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"},
{file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"},
{file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"},
{file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"},
{file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"},
{file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"},
{file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"},
{file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"},
{file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"},
{file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"},
{file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"},
{file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"},
{file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"},
{file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"},
{file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"},
{file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"},
]
[package.extras]
tzdata = ["tzdata"]
[[package]] [[package]]
name = "bcrypt" name = "bcrypt"
version = "4.0.1" version = "4.0.1"
@ -296,14 +237,14 @@ typecheck = ["mypy"]
[[package]] [[package]]
name = "beautifulsoup4" name = "beautifulsoup4"
version = "4.11.2" version = "4.12.0"
description = "Screen-scraping library" description = "Screen-scraping library"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.6.0" python-versions = ">=3.6.0"
files = [ files = [
{file = "beautifulsoup4-4.11.2-py3-none-any.whl", hash = "sha256:0e79446b10b3ecb499c1556f7e228a53e64a2bfcebd455f370d8927cb5b59e39"}, {file = "beautifulsoup4-4.12.0-py3-none-any.whl", hash = "sha256:2130a5ad7f513200fae61a17abb5e338ca980fa28c439c0571014bc0217e9591"},
{file = "beautifulsoup4-4.11.2.tar.gz", hash = "sha256:bc4bdda6717de5a2987436fb8d72f45dc90dd856bdfd512a1314ce90349a0106"}, {file = "beautifulsoup4-4.12.0.tar.gz", hash = "sha256:c5fceeaec29d09c84970e47c65f2f0efe57872f7cff494c9691a26ec0ff13234"},
] ]
[package.dependencies] [package.dependencies]
@ -548,19 +489,19 @@ files = [
[[package]] [[package]]
name = "fastapi" name = "fastapi"
version = "0.94.0" version = "0.95.0"
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "fastapi-0.94.0-py3-none-any.whl", hash = "sha256:898d7f6616dea49e78fa00e34401f9ace238fc670aafe4e30a16a384e3a671e1"}, {file = "fastapi-0.95.0-py3-none-any.whl", hash = "sha256:daf73bbe844180200be7966f68e8ec9fd8be57079dff1bacb366db32729e6eb5"},
{file = "fastapi-0.94.0.tar.gz", hash = "sha256:08ce0bc6f381ef1b6431e84a31d26eca0b60d6e1ac575adba4af95cc5a36cb62"}, {file = "fastapi-0.95.0.tar.gz", hash = "sha256:99d4fdb10e9dd9a24027ac1d0bd4b56702652056ca17a6c8721eec4ad2f14e18"},
] ]
[package.dependencies] [package.dependencies]
pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0" pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0"
starlette = ">=0.26.0,<0.27.0" starlette = ">=0.26.1,<0.27.0"
[package.extras] [package.extras]
all = ["email-validator (>=1.1.1)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] all = ["email-validator (>=1.1.1)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
@ -570,14 +511,14 @@ test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==23.1.0)", "coverage[toml] (>=6
[[package]] [[package]]
name = "fastapi-amis-admin" name = "fastapi-amis-admin"
version = "0.5.0" version = "0.5.1"
description = "FastAPI-Amis-Admin is a high-performance, efficient and easily extensible FastAPI admin framework. Inspired by Django-admin, and has as many powerful functions as Django-admin. " description = "FastAPI-Amis-Admin is a high-performance, efficient and easily extensible FastAPI admin framework. Inspired by Django-admin, and has as many powerful functions as Django-admin. "
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "fastapi_amis_admin-0.5.0-py3-none-any.whl", hash = "sha256:82f232c27b277d83f8829c1be07ec64ebbc94acf6bfd6fadf30c1f9fc9ed2704"}, {file = "fastapi_amis_admin-0.5.1-py3-none-any.whl", hash = "sha256:7cb65e6389c8f132152fd185cb8832d63a2401689db92b2e0fc2cb9d8d22969c"},
{file = "fastapi_amis_admin-0.5.0.tar.gz", hash = "sha256:f17d9cba8e2b32374d5a6f6576b98867d5777668a92885663a01b7a0faf206ff"}, {file = "fastapi_amis_admin-0.5.1.tar.gz", hash = "sha256:da4d11fc1f68bb48c817e02b477b5673e4d8e42dfec28e29eabd3937f2b35a36"},
] ]
[package.dependencies] [package.dependencies]
@ -623,19 +564,19 @@ test = ["aiosqlite (>=0.15.0)", "jinja2 (>=2.11.2,<4.0.0)", "pytest (>=6.2.4)",
[[package]] [[package]]
name = "filelock" name = "filelock"
version = "3.9.0" version = "3.10.0"
description = "A platform independent file lock." description = "A platform independent file lock."
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "filelock-3.9.0-py3-none-any.whl", hash = "sha256:f58d535af89bb9ad5cd4df046f741f8553a418c01a7856bf0d173bbc9f6bd16d"}, {file = "filelock-3.10.0-py3-none-any.whl", hash = "sha256:e90b34656470756edf8b19656785c5fea73afa1953f3e1b0d645cef11cab3182"},
{file = "filelock-3.9.0.tar.gz", hash = "sha256:7b319f24340b51f55a2bf7a12ac0755a9b03e718311dac567a0f4f7fabd2f5de"}, {file = "filelock-3.10.0.tar.gz", hash = "sha256:3199fd0d3faea8b911be52b663dfccceb84c95949dd13179aa21436d1a79c4ce"},
] ]
[package.extras] [package.extras]
docs = ["furo (>=2022.12.7)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] docs = ["furo (>=2022.12.7)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"]
testing = ["covdefaults (>=2.2.2)", "coverage (>=7.0.1)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-timeout (>=2.1)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.2.1)", "pytest (>=7.2.2)", "pytest-cov (>=4)", "pytest-timeout (>=2.1)"]
[[package]] [[package]]
name = "flake8" name = "flake8"
@ -902,14 +843,14 @@ socks = ["socksio (>=1.0.0,<2.0.0)"]
[[package]] [[package]]
name = "identify" name = "identify"
version = "2.5.20" version = "2.5.21"
description = "File identification library for Python" description = "File identification library for Python"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "identify-2.5.20-py2.py3-none-any.whl", hash = "sha256:5dfef8a745ca4f2c95f27e9db74cb4c8b6d9916383988e8791f3595868f78a33"}, {file = "identify-2.5.21-py2.py3-none-any.whl", hash = "sha256:69edcaffa8e91ae0f77d397af60f148b6b45a8044b2cc6d99cafa5b04793ff00"},
{file = "identify-2.5.20.tar.gz", hash = "sha256:c8b288552bc5f05a08aff09af2f58e6976bf8ac87beb38498a0e3d98ba64eb18"}, {file = "identify-2.5.21.tar.gz", hash = "sha256:7671a05ef9cfaf8ff63b15d45a91a1147a03aaccb2976d4e9bd047cbbc508471"},
] ]
[package.extras] [package.extras]
@ -993,25 +934,6 @@ typing-inspect = ">=0.4.0"
[package.extras] [package.extras]
dev = ["Sphinx (>=5.1.1)", "black (==22.10.0)", "coverage (>=4.5.4)", "fixit (==0.1.1)", "flake8 (>=3.7.8,<5)", "hypothesis (>=4.36.0)", "hypothesmith (>=0.0.4)", "jinja2 (==3.1.2)", "jupyter (>=1.0.0)", "maturin (>=0.8.3,<0.14)", "nbsphinx (>=0.4.2)", "prompt-toolkit (>=2.0.9)", "pyre-check (==0.9.9)", "setuptools-rust (>=1.5.2)", "setuptools-scm (>=6.0.1)", "slotscheck (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "ufmt (==2.0.1)", "usort (==1.0.5)"] dev = ["Sphinx (>=5.1.1)", "black (==22.10.0)", "coverage (>=4.5.4)", "fixit (==0.1.1)", "flake8 (>=3.7.8,<5)", "hypothesis (>=4.36.0)", "hypothesmith (>=0.0.4)", "jinja2 (==3.1.2)", "jupyter (>=1.0.0)", "maturin (>=0.8.3,<0.14)", "nbsphinx (>=0.4.2)", "prompt-toolkit (>=2.0.9)", "pyre-check (==0.9.9)", "setuptools-rust (>=1.5.2)", "setuptools-scm (>=6.0.1)", "slotscheck (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "ufmt (==2.0.1)", "usort (==1.0.5)"]
[[package]]
name = "loguru"
version = "0.6.0"
description = "Python logging made (stupidly) simple"
category = "main"
optional = false
python-versions = ">=3.5"
files = [
{file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"},
{file = "loguru-0.6.0.tar.gz", hash = "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c"},
]
[package.dependencies]
colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""}
win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""}
[package.extras]
dev = ["Sphinx (>=4.1.1)", "black (>=19.10b0)", "colorama (>=0.3.4)", "docutils (==0.16)", "flake8 (>=3.7.7)", "isort (>=5.1.1)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "tox (>=3.9.0)"]
[[package]] [[package]]
name = "lxml" name = "lxml"
version = "4.9.2" version = "4.9.2"
@ -1274,50 +1196,6 @@ files = [
[package.dependencies] [package.dependencies]
setuptools = "*" setuptools = "*"
[[package]]
name = "nonebot-plugin-apscheduler"
version = "0.2.0"
description = "APScheduler Support for NoneBot2"
category = "main"
optional = false
python-versions = ">=3.8,<4.0"
files = [
{file = "nonebot-plugin-apscheduler-0.2.0.tar.gz", hash = "sha256:7b63e99a611b657533b48fcf1f8c6627c18c2eb3fa820a906cd4ec4666c0ceb0"},
{file = "nonebot_plugin_apscheduler-0.2.0-py3-none-any.whl", hash = "sha256:9285ee84ca1cfa4db73c86cedb5911bbbd25a21ec0cd5f22447cd12f89e48fb4"},
]
[package.dependencies]
apscheduler = ">=3.7.0,<4.0.0"
nonebot2 = ">=2.0.0-rc.1,<3.0.0"
[[package]]
name = "nonebot2"
version = "2.0.0rc3"
description = "An asynchronous python bot framework."
category = "main"
optional = false
python-versions = ">=3.8,<4.0"
files = [
{file = "nonebot2-2.0.0rc3-py3-none-any.whl", hash = "sha256:6596e9837e95e99a6cfa7c4e21d75a54a5f3529d34f30454136ebfef6aa374f4"},
{file = "nonebot2-2.0.0rc3.tar.gz", hash = "sha256:a16da07b7c764d536cbdf9bcb86eb7cc21b1d254c966552ec5d20e0cb303cec2"},
]
[package.dependencies]
loguru = ">=0.6.0,<0.7.0"
pydantic = {version = ">=1.10.0,<2.0.0", extras = ["dotenv"]}
pygtrie = ">=2.4.1,<3.0.0"
tomlkit = ">=0.10.0,<1.0.0"
typing-extensions = ">=3.10.0,<5.0.0"
yarl = ">=1.7.2,<2.0.0"
[package.extras]
aiohttp = ["aiohttp[speedups] (>=3.7.4,<4.0.0)"]
all = ["Quart (>=0.18.0,<1.0.0)", "aiohttp[speedups] (>=3.7.4,<4.0.0)", "fastapi (>=0.87.0,!=0.89.0,<1.0.0)", "httpx[http2] (>=0.20.0,<1.0.0)", "uvicorn[standard] (>=0.20.0,<1.0.0)", "websockets (>=10.0,<11.0)"]
fastapi = ["fastapi (>=0.87.0,!=0.89.0,<1.0.0)", "uvicorn[standard] (>=0.20.0,<1.0.0)"]
httpx = ["httpx[http2] (>=0.20.0,<1.0.0)"]
quart = ["Quart (>=0.18.0,<1.0.0)", "uvicorn[standard] (>=0.20.0,<1.0.0)"]
websockets = ["websockets (>=10.0,<11.0)"]
[[package]] [[package]]
name = "openpyxl" name = "openpyxl"
version = "3.1.2" version = "3.1.2"
@ -1567,7 +1445,6 @@ files = [
] ]
[package.dependencies] [package.dependencies]
python-dotenv = {version = ">=0.10.4", optional = true, markers = "extra == \"dotenv\""}
typing-extensions = ">=4.2.0" typing-extensions = ">=4.2.0"
[package.extras] [package.extras]
@ -1586,18 +1463,6 @@ files = [
{file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"}, {file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"},
] ]
[[package]]
name = "pygtrie"
version = "2.5.0"
description = "A pure Python trie data structure implementation."
category = "main"
optional = false
python-versions = "*"
files = [
{file = "pygtrie-2.5.0-py3-none-any.whl", hash = "sha256:8795cda8105493d5ae159a5bef313ff13156c5d4d72feddefacaad59f8c8ce16"},
{file = "pygtrie-2.5.0.tar.gz", hash = "sha256:203514ad826eb403dab1d2e2ddd034e0d1534bbe4dbe0213bb0593f66beba4e2"},
]
[[package]] [[package]]
name = "pypng" name = "pypng"
version = "0.20220715.0" version = "0.20220715.0"
@ -1610,21 +1475,6 @@ files = [
{file = "pypng-0.20220715.0.tar.gz", hash = "sha256:739c433ba96f078315de54c0db975aee537cbc3e1d0ae4ed9aab0ca1e427e2c1"}, {file = "pypng-0.20220715.0.tar.gz", hash = "sha256:739c433ba96f078315de54c0db975aee537cbc3e1d0ae4ed9aab0ca1e427e2c1"},
] ]
[[package]]
name = "python-dotenv"
version = "1.0.0"
description = "Read key-value pairs from a .env file and set them as environment variables"
category = "main"
optional = false
python-versions = ">=3.8"
files = [
{file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"},
{file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"},
]
[package.extras]
cli = ["click (>=5.0)"]
[[package]] [[package]]
name = "python-multipart" name = "python-multipart"
version = "0.0.6" version = "0.0.6"
@ -1640,34 +1490,6 @@ files = [
[package.extras] [package.extras]
dev = ["atomicwrites (==1.2.1)", "attrs (==19.2.0)", "coverage (==6.5.0)", "hatch", "invoke (==1.7.3)", "more-itertools (==4.3.0)", "pbr (==4.3.0)", "pluggy (==1.0.0)", "py (==1.11.0)", "pytest (==7.2.0)", "pytest-cov (==4.0.0)", "pytest-timeout (==2.1.0)", "pyyaml (==5.1)"] dev = ["atomicwrites (==1.2.1)", "attrs (==19.2.0)", "coverage (==6.5.0)", "hatch", "invoke (==1.7.3)", "more-itertools (==4.3.0)", "pbr (==4.3.0)", "pluggy (==1.0.0)", "py (==1.11.0)", "pytest (==7.2.0)", "pytest-cov (==4.0.0)", "pytest-timeout (==2.1.0)", "pyyaml (==5.1)"]
[[package]]
name = "pytz"
version = "2022.7.1"
description = "World timezone definitions, modern and historical"
category = "main"
optional = false
python-versions = "*"
files = [
{file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"},
{file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"},
]
[[package]]
name = "pytz-deprecation-shim"
version = "0.1.0.post0"
description = "Shims to make deprecation of pytz easier"
category = "main"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
files = [
{file = "pytz_deprecation_shim-0.1.0.post0-py2.py3-none-any.whl", hash = "sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6"},
{file = "pytz_deprecation_shim-0.1.0.post0.tar.gz", hash = "sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d"},
]
[package.dependencies]
"backports.zoneinfo" = {version = "*", markers = "python_version >= \"3.6\" and python_version < \"3.9\""}
tzdata = {version = "*", markers = "python_version >= \"3.6\""}
[[package]] [[package]]
name = "pyyaml" name = "pyyaml"
version = "6.0" version = "6.0"
@ -1803,7 +1625,7 @@ six = ">=1.9.0"
name = "setuptools" name = "setuptools"
version = "67.6.0" version = "67.6.0"
description = "Easily download, build, install, upgrade, and uninstall Python packages" description = "Easily download, build, install, upgrade, and uninstall Python packages"
category = "main" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
@ -1916,7 +1738,7 @@ files = [
] ]
[package.dependencies] [package.dependencies]
greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and platform_machine == \"aarch64\" or python_version >= \"3\" and platform_machine == \"ppc64le\" or python_version >= \"3\" and platform_machine == \"x86_64\" or python_version >= \"3\" and platform_machine == \"amd64\" or python_version >= \"3\" and platform_machine == \"AMD64\" or python_version >= \"3\" and platform_machine == \"win32\" or python_version >= \"3\" and platform_machine == \"WIN32\""}
[package.extras] [package.extras]
aiomysql = ["aiomysql", "greenlet (!=0.4.17)"] aiomysql = ["aiomysql", "greenlet (!=0.4.17)"]
@ -2011,14 +1833,14 @@ test = ["pytest (>=7.1.3)"]
[[package]] [[package]]
name = "starlette" name = "starlette"
version = "0.26.0.post1" version = "0.26.1"
description = "The little ASGI library that shines." description = "The little ASGI library that shines."
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "starlette-0.26.0.post1-py3-none-any.whl", hash = "sha256:5b80b546ed60d43da45f80113c05ff9f4c44fae95ee884945958eba685c56253"}, {file = "starlette-0.26.1-py3-none-any.whl", hash = "sha256:e87fce5d7cbdde34b76f0ac69013fd9d190d581d80681493016666e6f96c6d5e"},
{file = "starlette-0.26.0.post1.tar.gz", hash = "sha256:af0e54d08afed70fcbc53ae01e71c9c62c8ab038ff8cfd3f7477bf0f086b5ab4"}, {file = "starlette-0.26.1.tar.gz", hash = "sha256:41da799057ea8620e4667a3e69a5b1923ebd32b1819c8fa75634bbe8d8bea9bd"},
] ]
[package.dependencies] [package.dependencies]
@ -2044,7 +1866,7 @@ files = [
name = "tomlkit" name = "tomlkit"
version = "0.11.6" version = "0.11.6"
description = "Style preserving TOML library" description = "Style preserving TOML library"
category = "main" category = "dev"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
files = [ files = [
@ -2101,39 +1923,6 @@ files = [
mypy-extensions = ">=0.3.0" mypy-extensions = ">=0.3.0"
typing-extensions = ">=3.7.4" typing-extensions = ">=3.7.4"
[[package]]
name = "tzdata"
version = "2022.7"
description = "Provider of IANA time zone data"
category = "main"
optional = false
python-versions = ">=2"
files = [
{file = "tzdata-2022.7-py2.py3-none-any.whl", hash = "sha256:2b88858b0e3120792a3c0635c23daf36a7d7eeeca657c323da299d2094402a0d"},
{file = "tzdata-2022.7.tar.gz", hash = "sha256:fe5f866eddd8b96e9fcba978f8e503c909b19ea7efda11e52e39494bad3a7bfa"},
]
[[package]]
name = "tzlocal"
version = "4.2"
description = "tzinfo object for the local timezone"
category = "main"
optional = false
python-versions = ">=3.6"
files = [
{file = "tzlocal-4.2-py3-none-any.whl", hash = "sha256:89885494684c929d9191c57aa27502afc87a579be5cdd3225c77c463ea043745"},
{file = "tzlocal-4.2.tar.gz", hash = "sha256:ee5842fa3a795f023514ac2d801c4a81d1743bbe642e3940143326b3a00addd7"},
]
[package.dependencies]
"backports.zoneinfo" = {version = "*", markers = "python_version < \"3.9\""}
pytz-deprecation-shim = "*"
tzdata = {version = "*", markers = "platform_system == \"Windows\""}
[package.extras]
devenv = ["black", "pyroma", "pytest-cov", "zest.releaser"]
test = ["pytest (>=4.3)", "pytest-mock (>=3.3)"]
[[package]] [[package]]
name = "urllib3" name = "urllib3"
version = "1.26.15" version = "1.26.15"
@ -2153,14 +1942,14 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
[[package]] [[package]]
name = "uvicorn" name = "uvicorn"
version = "0.21.0" version = "0.21.1"
description = "The lightning-fast ASGI server." description = "The lightning-fast ASGI server."
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "uvicorn-0.21.0-py3-none-any.whl", hash = "sha256:e69e955cb621ae7b75f5590a814a4fcbfb14cb8f44a36dfe3c5c75ab8aee3ad5"}, {file = "uvicorn-0.21.1-py3-none-any.whl", hash = "sha256:e47cac98a6da10cd41e6fd036d472c6f58ede6c5dbee3dbee3ef7a100ed97742"},
{file = "uvicorn-0.21.0.tar.gz", hash = "sha256:8635a388062222082f4b06225b867b74a7e4ef942124453d4d1d1a5cb3750932"}, {file = "uvicorn-0.21.1.tar.gz", hash = "sha256:0fac9cb342ba099e0d582966005f3fdba5b0290579fed4a6266dc702ca7bb032"},
] ]
[package.dependencies] [package.dependencies]
@ -2172,14 +1961,14 @@ standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)",
[[package]] [[package]]
name = "virtualenv" name = "virtualenv"
version = "20.20.0" version = "20.21.0"
description = "Virtual Python Environment builder" description = "Virtual Python Environment builder"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "virtualenv-20.20.0-py3-none-any.whl", hash = "sha256:3c22fa5a7c7aa106ced59934d2c20a2ecb7f49b4130b8bf444178a16b880fa45"}, {file = "virtualenv-20.21.0-py3-none-any.whl", hash = "sha256:31712f8f2a17bd06234fa97fdf19609e789dd4e3e4bf108c3da71d710651adbc"},
{file = "virtualenv-20.20.0.tar.gz", hash = "sha256:a8a4b8ca1e28f864b7514a253f98c1d62b64e31e77325ba279248c65fb4fcef4"}, {file = "virtualenv-20.21.0.tar.gz", hash = "sha256:f50e3e60f990a0757c9b68333c9fdaa72d7188caa417f96af9e52407831a3b68"},
] ]
[package.dependencies] [package.dependencies]
@ -2270,21 +2059,6 @@ files = [
{file = "websockets-10.4.tar.gz", hash = "sha256:eef610b23933c54d5d921c92578ae5f89813438fded840c2e9809d378dc765d3"}, {file = "websockets-10.4.tar.gz", hash = "sha256:eef610b23933c54d5d921c92578ae5f89813438fded840c2e9809d378dc765d3"},
] ]
[[package]]
name = "win32-setctime"
version = "1.1.0"
description = "A small Python utility to set file creation time on Windows"
category = "main"
optional = false
python-versions = ">=3.5"
files = [
{file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"},
{file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"},
]
[package.extras]
dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"]
[[package]] [[package]]
name = "yarl" name = "yarl"
version = "1.8.2" version = "1.8.2"
@ -2376,4 +2150,4 @@ multidict = ">=4.0"
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.8.1" python-versions = "^3.8.1"
content-hash = "ba81e4086af98ac3117b3ac99a19d8d7915cc893a5a08cc52a27300c92c4395b" content-hash = "cc565e9b9975fa6d8e1e0117da4cc877a9f62502708b3b507857b744f48c63f6"

View File

@ -22,12 +22,11 @@ aiohttp = ">=3.8.1"
sqlalchemy = ">=1.4.39,<2.0.0" sqlalchemy = ">=1.4.39,<2.0.0"
pillow = ">=9.2.0" pillow = ">=9.2.0"
aiosqlite = ">=0.17.0" aiosqlite = ">=0.17.0"
nonebot-plugin-apscheduler = ">=0.1.4"
aiofiles = ">=0.8.0" aiofiles = ">=0.8.0"
sqlmodel = ">=0.0.8" sqlmodel = ">=0.0.8"
gitpython = ">=3.1.27" gitpython = ">=3.1.27"
fastapi-amis-admin = ">=0.2.1" fastapi-amis-admin = ">=0.5.0"
fastapi-user-auth = ">=0.2.1" fastapi-user-auth = ">=0.5.0"
qrcode = {extras = ["pil"], version = "^7.3.1"} qrcode = {extras = ["pil"], version = "^7.3.1"}
msgspec = ">= 0.13.1" msgspec = ">= 0.13.1"
uvicorn = ">=0.20.0" uvicorn = ">=0.20.0"

View File

@ -3,22 +3,20 @@ aiohttp==3.8.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0
aiosignal==1.3.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" aiosignal==1.3.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
aiosqlite==0.18.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" aiosqlite==0.18.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
anyio==3.6.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" anyio==3.6.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
apscheduler==3.10.1 ; python_full_version >= "3.8.1" and python_version < "4.0"
async-timeout==4.0.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" async-timeout==4.0.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
attrs==22.2.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" attrs==22.2.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
backports-zoneinfo==0.2.1 ; python_full_version >= "3.8.1" and python_version < "3.9"
bcrypt==4.0.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" bcrypt==4.0.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
beautifulsoup4==4.11.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" beautifulsoup4==4.12.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
certifi==2022.12.7 ; python_full_version >= "3.8.1" and python_version < "4" certifi==2022.12.7 ; python_full_version >= "3.8.1" and python_version < "4"
charset-normalizer==3.1.0 ; python_full_version >= "3.8.1" and python_version < "4" charset-normalizer==3.1.0 ; python_full_version >= "3.8.1" and python_version < "4"
click==8.1.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" click==8.1.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
colorama==0.4.6 ; python_full_version >= "3.8.1" and python_version < "4.0" and platform_system == "Windows" or python_full_version >= "3.8.1" and python_version < "4.0" and sys_platform == "win32" colorama==0.4.6 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" and platform_system == "Windows"
dnspython==2.3.0 ; python_full_version >= "3.8.1" and python_version < "4.0" dnspython==2.3.0 ; python_full_version >= "3.8.1" and python_version < "4.0"
email-validator==1.3.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" email-validator==1.3.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
et-xmlfile==1.1.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" et-xmlfile==1.1.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
fastapi-amis-admin==0.5.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" fastapi-amis-admin==0.5.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
fastapi-user-auth==0.5.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" fastapi-user-auth==0.5.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
fastapi==0.94.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" fastapi==0.95.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
frozenlist==1.3.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" frozenlist==1.3.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
gitdb==4.0.10 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" gitdb==4.0.10 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
gitpython==3.1.31 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" gitpython==3.1.31 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
@ -27,29 +25,20 @@ h11==0.14.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
httpcore==0.16.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" httpcore==0.16.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
httpx==0.23.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" httpx==0.23.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
idna==3.4 ; python_full_version >= "3.8.1" and python_version < "4" idna==3.4 ; python_full_version >= "3.8.1" and python_version < "4"
loguru==0.6.0 ; python_full_version >= "3.8.1" and python_version < "4.0"
lxml==4.9.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" lxml==4.9.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
msgspec==0.13.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" msgspec==0.13.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
multidict==6.0.4 ; python_full_version >= "3.8.1" and python_version < "4.0" multidict==6.0.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
nonebot-plugin-apscheduler==0.2.0 ; python_full_version >= "3.8.1" and python_version < "4.0"
nonebot2==2.0.0rc3 ; python_full_version >= "3.8.1" and python_version < "4.0"
openpyxl==3.1.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" openpyxl==3.1.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
passlib==1.7.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" passlib==1.7.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
pillow==9.4.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" pillow==9.4.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
pydantic==1.10.6 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" pydantic==1.10.6 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
pydantic[dotenv]==1.10.6 ; python_full_version >= "3.8.1" and python_version < "4.0"
pygtrie==2.5.0 ; python_full_version >= "3.8.1" and python_version < "4.0"
pypng==0.20220715.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" pypng==0.20220715.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
python-dotenv==1.0.0 ; python_full_version >= "3.8.1" and python_version < "4.0"
python-multipart==0.0.6 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" python-multipart==0.0.6 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
pytz-deprecation-shim==0.1.0.post0 ; python_full_version >= "3.8.1" and python_version < "4.0"
pytz==2022.7.1 ; python_full_version >= "3.8.1" and python_version < "4.0"
qrcode[pil]==7.4.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" qrcode[pil]==7.4.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
requests==2.28.2 ; python_full_version >= "3.8.1" and python_version < "4" requests==2.28.2 ; python_full_version >= "3.8.1" and python_version < "4"
rfc3986[idna2008]==1.5.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" rfc3986[idna2008]==1.5.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
rollbar==0.16.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" rollbar==0.16.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
setuptools==67.6.0 ; python_full_version >= "3.8.1" and python_version < "4.0" six==1.16.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
six==1.16.0 ; python_full_version >= "3.8.1" and python_version < "4.0"
smmap==5.0.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" smmap==5.0.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
sniffio==1.3.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" sniffio==1.3.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
soupsieve==2.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" soupsieve==2.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
@ -58,13 +47,9 @@ sqlalchemy2-stubs==0.0.2a32 ; python_full_version >= "3.8.1" and python_full_ver
sqlalchemy==1.4.41 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" sqlalchemy==1.4.41 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
sqlmodel==0.0.8 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" sqlmodel==0.0.8 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
sqlmodelx==0.0.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" sqlmodelx==0.0.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
starlette==0.26.0.post1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" starlette==0.26.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
tomlkit==0.11.6 ; python_full_version >= "3.8.1" and python_version < "4.0" typing-extensions==4.5.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
typing-extensions==4.5.0 ; python_full_version >= "3.8.1" and python_version < "4.0"
tzdata==2022.7 ; python_full_version >= "3.8.1" and python_version < "4.0"
tzlocal==4.2 ; python_full_version >= "3.8.1" and python_version < "4.0"
urllib3==1.26.15 ; python_full_version >= "3.8.1" and python_version < "4" urllib3==1.26.15 ; python_full_version >= "3.8.1" and python_version < "4"
uvicorn==0.21.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" uvicorn==0.21.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
websockets==10.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" websockets==10.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
win32-setctime==1.1.0 ; python_full_version >= "3.8.1" and python_version < "4.0" and sys_platform == "win32" yarl==1.8.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
yarl==1.8.2 ; python_full_version >= "3.8.1" and python_version < "4.0"