81 lines
No EOL
3.1 KiB
Python
81 lines
No EOL
3.1 KiB
Python
from flask import Blueprint, request, jsonify, abort
|
|
from sqlalchemy.orm import scoped_session
|
|
from .dsl import QuerySpec
|
|
from .service import CrudService
|
|
from .eager import default_eager_policy
|
|
from .serialize import serialize
|
|
|
|
def make_blueprint(db_session_factory, registry):
|
|
bp = Blueprint("crud", __name__)
|
|
def session(): return scoped_session(db_session_factory)()
|
|
|
|
@bp.get("/<model>/list")
|
|
def list_items(model):
|
|
Model = registry.get(model) or abort(404)
|
|
spec = QuerySpec(
|
|
filters=_parse_filters(request.args),
|
|
order_by=request.args.getlist("sort"),
|
|
page=request.args.get("page", type=int),
|
|
per_page=request.args.get("per_page", type=int),
|
|
expand=request.args.getlist("expand"),
|
|
fields=request.args.get("fields", type=lambda s: [x.strip() for x in s.split(",")] if s else None),
|
|
)
|
|
s = session(); svc = CrudService(s, default_eager_policy)
|
|
rows, total = svc.list(Model, spec)
|
|
data = [serialize(r, fields=spec.fields, expand=spec.expand) for r in rows]
|
|
return jsonify({"data": data, "total": total})
|
|
|
|
@bp.post("/<model>")
|
|
def create_item(model):
|
|
Model = registry.get(model) or abort(404)
|
|
payload = request.get_json() or {}
|
|
s = session(); svc = CrudService(s, default_eager_policy)
|
|
obj = svc.create(Model, payload)
|
|
s.commit()
|
|
return jsonify(serialize(obj)), 201
|
|
|
|
@bp.get("/<model>/<int:id>")
|
|
def read_item(model, id):
|
|
Model = registry.get(model) or abort(404)
|
|
spec = QuerySpec(expand=request.args.getlist("expand"),
|
|
fields=request.args.get("fields", type=lambda s: s.split(",")))
|
|
s = session(); svc = CrudService(s, default_eager_policy)
|
|
obj = svc.get(Model, id, spec) or abort(404)
|
|
return jsonify(serialize(obj, fields=spec.fields, expand=spec.expand))
|
|
|
|
@bp.patch("/<model>/<int:id>")
|
|
def update_item(model, id):
|
|
Model = registry.get(model) or abort(404)
|
|
s = session(); svc = CrudService(s, default_eager_policy)
|
|
obj = svc.get(Model, id, QuerySpec()) or abort(404)
|
|
payload = request.get_json() or {}
|
|
svc.update(obj, payload)
|
|
s.commit()
|
|
return jsonify(serialize(obj))
|
|
|
|
@bp.delete("/<model>/<int:id>")
|
|
def delete_item(model, id):
|
|
Model = registry.get(model) or abort(404)
|
|
s = session(); svc = CrudService(s, default_eager_policy)
|
|
obj = svc.get(Model, id, QuerySpec()) or abort(404)
|
|
svc.soft_delete(obj)
|
|
s.commit()
|
|
return jsonify({"status": "deleted"})
|
|
|
|
@bp.post("/<model>/<int:id>/undelete")
|
|
def undelete_item(model, id):
|
|
Model = registry.get(model) or abort(404)
|
|
s = session(); svc = CrudService(s, default_eager_policy)
|
|
obj = svc.get(Model, id, QuerySpec()) or abort(404)
|
|
svc.undelete(obj)
|
|
s.commit()
|
|
return jsonify({"status": "restored"})
|
|
return bp
|
|
|
|
def _parse_filters(args):
|
|
out = {}
|
|
for k, v in args.items():
|
|
if k in {"page", "per_page", "sort", "expand", "fields"}:
|
|
continue
|
|
out[k] = v
|
|
return out |