add Makefile

update cli
This commit is contained in:
long2ice
2020-05-22 21:28:32 +08:00
parent ae4eb02145
commit afabc6cd27
26 changed files with 782 additions and 384 deletions

View File

@@ -1,9 +1,9 @@
from fastapi import Depends
from . import login, site, rest
from ..depends import jwt_required
from ..factory import app
from . import login, rest, site
app.include_router(login.router)
app.include_router(site.router)
app.include_router(rest.router, dependencies=[Depends(jwt_required)], prefix='/rest')
app.include_router(rest.router, dependencies=[Depends(jwt_required)], prefix="/rest")

View File

@@ -10,25 +10,20 @@ from ..shortcuts import get_object_or_404
router = APIRouter()
@router.post(
'/login',
)
async def login(
login_in: LoginIn
):
@router.post("/login",)
async def login(login_in: LoginIn):
user_model = app.user_model
user = await get_object_or_404(user_model, username=login_in.username)
if not user.is_active:
raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail='User is not Active!')
raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail="User is not Active!")
if not pwd_context.verify(login_in.password, user.password):
raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail='Incorrect Password!')
raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail="Incorrect Password!")
ret = {
'user': {
'username': user.username,
'is_superuser': user.is_superuser,
'avatar': user.avatar if hasattr(user, 'avatar') else None
"user": {
"username": user.username,
"is_superuser": user.is_superuser,
"avatar": user.avatar if hasattr(user, "avatar") else None,
},
'token': jwt.encode({'user_id': user.pk}, app.admin_secret, algorithm='HS256')
"token": jwt.encode({"user_id": user.pk}, app.admin_secret, algorithm="HS256"),
}
return ret

View File

@@ -1,7 +1,7 @@
import io
import xlsxwriter
from fastapi import Depends, APIRouter
from fastapi import APIRouter, Depends
from fastapi.responses import UJSONResponse
from starlette.responses import StreamingResponse
from starlette.status import HTTP_409_CONFLICT
@@ -11,8 +11,16 @@ from tortoise.exceptions import IntegrityError
from tortoise.fields import ManyToManyRelation
from ..common import handle_m2m_fields_create_or_update
from ..depends import QueryItem, get_query, parse_body, get_model, read_checker, delete_checker, update_checker, \
create_checker
from ..depends import (
QueryItem,
create_checker,
delete_checker,
get_model,
get_query,
parse_body,
read_checker,
update_checker,
)
from ..factory import app
from ..responses import GetManyOut
from ..schemas import BulkIn
@@ -21,20 +29,16 @@ from ..shortcuts import get_object_or_404
router = APIRouter()
@router.get(
'/{resource}/export'
)
async def export(
resource: str,
query: QueryItem = Depends(get_query),
model=Depends(get_model)
):
@router.get("/{resource}/export")
async def export(resource: str, query: QueryItem = Depends(get_query), model=Depends(get_model)):
qs = model.all()
if query.where:
qs = qs.filter(**query.where)
resource = await app.get_resource(resource)
result = await qs
creator = pydantic_model_creator(model, include=resource.resource_fields.keys(), exclude=model._meta.m2m_fields)
creator = pydantic_model_creator(
model, include=resource.resource_fields.keys(), exclude=model._meta.m2m_fields
)
data = map(lambda x: creator.from_orm(x).dict(), result)
output = io.BytesIO()
@@ -54,14 +58,9 @@ async def export(
return StreamingResponse(output)
@router.get(
'/{resource}',
dependencies=[Depends(read_checker)]
)
@router.get("/{resource}", dependencies=[Depends(read_checker)])
async def get_resource(
resource: str,
query: QueryItem = Depends(get_query),
model=Depends(get_model)
resource: str, query: QueryItem = Depends(get_query), model=Depends(get_model)
):
menu = app.model_menu_mapping[resource]
qs = model.all()
@@ -71,125 +70,81 @@ async def get_resource(
for k, v in sort.items():
if k in menu.sort_fields:
if v == -1:
qs = qs.order_by(f'-{k}')
qs = qs.order_by(f"-{k}")
elif v == 1:
qs = qs.order_by(k)
resource = await app.get_resource(resource)
result = await qs.limit(query.size).offset((query.page - 1) * query.size)
creator = pydantic_model_creator(model, include=resource.resource_fields.keys(), exclude=model._meta.m2m_fields)
creator = pydantic_model_creator(
model, include=resource.resource_fields.keys(), exclude=model._meta.m2m_fields
)
return GetManyOut(
total=await qs.count(),
data=list(map(lambda x: creator.from_orm(x).dict(), result))
total=await qs.count(), data=list(map(lambda x: creator.from_orm(x).dict(), result))
)
@router.get(
'/{resource}/form',
dependencies=[Depends(read_checker)]
)
async def form(
resource: str,
):
resource = await app.get_resource(resource, exclude_pk=True, exclude_m2m_field=False, exclude_actions=True)
@router.get("/{resource}/form", dependencies=[Depends(read_checker)])
async def form(resource: str,):
resource = await app.get_resource(
resource, exclude_pk=True, exclude_m2m_field=False, exclude_actions=True
)
return resource.dict(by_alias=True, exclude_unset=True)
@router.get(
'/{resource}/grid',
dependencies=[Depends(read_checker)]
)
async def grid(
resource: str,
):
@router.get("/{resource}/grid", dependencies=[Depends(read_checker)])
async def grid(resource: str,):
resource = await app.get_resource(resource)
return resource.dict(by_alias=True, exclude_unset=True)
@router.get(
'/{resource}/view',
dependencies=[Depends(read_checker)]
)
async def view(
resource: str,
):
@router.get("/{resource}/view", dependencies=[Depends(read_checker)])
async def view(resource: str,):
resource = await app.get_resource(resource)
return resource.dict(by_alias=True, exclude_unset=True)
@router.post(
'/{resource}/bulk/delete',
dependencies=[Depends(delete_checker)]
)
async def bulk_delete(
bulk_in: BulkIn,
model=Depends(get_model)
):
@router.post("/{resource}/bulk/delete", dependencies=[Depends(delete_checker)])
async def bulk_delete(bulk_in: BulkIn, model=Depends(get_model)):
await model.filter(pk__in=bulk_in.pk_list).delete()
return {'success': True}
return {"success": True}
@router.delete(
'/{resource}/{id}',
dependencies=[Depends(delete_checker)]
)
async def delete_one(
id: int,
model=Depends(get_model)
):
@router.delete("/{resource}/{id}", dependencies=[Depends(delete_checker)])
async def delete_one(id: int, model=Depends(get_model)):
await model.filter(pk=id).delete()
return {'success': True}
return {"success": True}
@router.put(
'/{resource}/{id}',
dependencies=[Depends(update_checker)]
)
async def update_one(
id: int,
parsed=Depends(parse_body),
model=Depends(get_model)
):
@router.put("/{resource}/{id}", dependencies=[Depends(update_checker)])
async def update_one(id: int, parsed=Depends(parse_body), model=Depends(get_model)):
body, resource_fields = parsed
m2m_fields = model._meta.m2m_fields
try:
obj = await handle_m2m_fields_create_or_update(body, m2m_fields, model, False, id)
except IntegrityError as e:
return UJSONResponse(status_code=HTTP_409_CONFLICT, content=dict(
message=f'Update Error,{e}'
))
return UJSONResponse(
status_code=HTTP_409_CONFLICT, content=dict(message=f"Update Error,{e}")
)
creator = pydantic_model_creator(model, include=resource_fields, exclude=m2m_fields)
return creator.from_orm(obj).dict()
@router.post(
'/{resource}',
dependencies=[Depends(create_checker)]
)
async def create_one(
parsed=Depends(parse_body),
model=Depends(get_model)
):
@router.post("/{resource}", dependencies=[Depends(create_checker)])
async def create_one(parsed=Depends(parse_body), model=Depends(get_model)):
body, resource_fields = parsed
m2m_fields = model._meta.m2m_fields
creator = pydantic_model_creator(model, include=resource_fields, exclude=m2m_fields)
try:
obj = await handle_m2m_fields_create_or_update(body, m2m_fields, model)
except IntegrityError as e:
return UJSONResponse(status_code=HTTP_409_CONFLICT, content=dict(
message=f'Create Error,{e}'
))
return UJSONResponse(
status_code=HTTP_409_CONFLICT, content=dict(message=f"Create Error,{e}")
)
return creator.from_orm(obj).dict()
@router.get(
'/{resource}/{id}',
dependencies=[Depends(read_checker)]
)
async def get_one(
id: int,
resource: str,
model=Depends(get_model)
):
@router.get("/{resource}/{id}", dependencies=[Depends(read_checker)])
async def get_one(id: int, resource: str, model=Depends(get_model)):
obj = await get_object_or_404(model, pk=id) # type:Model
m2m_fields = model._meta.m2m_fields
resource = await app.get_resource(resource, exclude_m2m_field=False)
@@ -201,5 +156,5 @@ async def get_one(
relate_model = getattr(obj, m2m_field) # type:ManyToManyRelation
ids = await relate_model.all().values_list(relate_model.remote_model._meta.pk_attr)
ret[m2m_field] = list(map(lambda x: x[0], ids))
ret['__str__'] = str(obj)
ret["__str__"] = str(obj)
return ret

View File

@@ -9,26 +9,22 @@ from ..shortcuts import get_object_or_404
router = APIRouter()
@router.get(
'/site',
)
async def site(
user_id=Depends(jwt_optional)
):
@router.get("/site",)
async def site(user_id=Depends(jwt_optional)):
site_ = app.site
user = None
if user_id:
user = await get_object_or_404(app.user_model, pk=user_id)
if user and app.permission and not user.is_superuser:
site_ = deepcopy(site_)
await user.fetch_related('roles')
filter_menus = filter(lambda x: (x.url and 'rest' in x.url) or x.children, site_.menus)
await user.fetch_related("roles")
filter_menus = filter(lambda x: (x.url and "rest" in x.url) or x.children, site_.menus)
hide_menus = []
for menu in filter_menus:
has_permission = False
for role in user.roles:
if not has_permission:
model = menu.url.split('/')[-1]
model = menu.url.split("/")[-1]
permission = await role.permissions.filter(model=model)
if permission:
has_permission = True