from flask import Blueprint from flask_apispec import use_kwargs, marshal_with, doc from flask_jwt_extended import jwt_required from marshmallow import fields from sqlalchemy import or_ from api.exceptions import NotFoundException, BadRequestException from api.target.models import Target from api.target_exchange.models import TargetExchange from .models import Registration from .serializers import registration_schema, registrations_schema blueprint = Blueprint('Registration', __name__) @doc(tags=['Registration']) @blueprint.route('', methods=['GET']) @jwt_required() @use_kwargs({'exchange': fields.Str(), 'target': fields.Str()}) @marshal_with(registrations_schema) def get_list(exchange=None, target=None): res = Registration.query if exchange is not None: res = res.join(Registration.targets).join(Target.exchange).filter( or_(TargetExchange.name == exchange, Target.name == target, Target.routing_key == target)) return res.all() @doc(tags=['Registration']) @blueprint.route('', methods=['POST']) @jwt_required() @use_kwargs(registration_schema) @marshal_with(registration_schema) def create(name, routing_key, targets): target_ids = [t.id for t in targets] xchanges = Target.query.filter(Target.target_exchange_id.in_(target_ids)) if len(xchanges) != len(target_ids): xchange_ids = [t.id for t in xchanges] not_found = ','.join([f'{t.name}({t.id})' for t in targets if t.id not in xchange_ids]) raise BadRequestException(f"the target {not_found} could not be found") registration = Registration(name=name, routing_key=routing_key, registration_exchange_id=xchanges.id) registration.save() return registration @doc(tags=['Registration']) @blueprint.route('/', methods=['GET']) @jwt_required() @marshal_with(registration_schema) def get_by_id(registration_id: int): registration = Registration.get_by_id(registration_id) if registration is not None: return registration else: return NotFoundException(Registration.__name__) @doc(tags=['Registration']) @blueprint.route('/', methods=['PUT']) @jwt_required() @use_kwargs(registration_schema) @marshal_with(registration_schema) def update(registration_id, **kwargs): registration = Registration.get_by_id(registration_id) if registration is not None: return registration.update(**kwargs) else: return NotFoundException(Registration.__name__)