From d24d2ad221168e6760eb821e3857cb786b068651 Mon Sep 17 00:00:00 2001 From: Gardient Date: Wed, 22 Sep 2021 19:26:07 +0300 Subject: [PATCH] registration --- api/registration/__init__.py | 3 ++ api/registration/models.py | 21 ++++++++++ api/registration/serializers.py | 14 +++++++ api/registration/views.py | 68 +++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 api/registration/__init__.py create mode 100644 api/registration/models.py create mode 100644 api/registration/serializers.py create mode 100644 api/registration/views.py diff --git a/api/registration/__init__.py b/api/registration/__init__.py new file mode 100644 index 0000000..193a878 --- /dev/null +++ b/api/registration/__init__.py @@ -0,0 +1,3 @@ +"""Registrations""" + +from . import views, models diff --git a/api/registration/models.py b/api/registration/models.py new file mode 100644 index 0000000..495432f --- /dev/null +++ b/api/registration/models.py @@ -0,0 +1,21 @@ +from sqlalchemy import String + +from api.database import (Model, SurrogatePK, db, + Column, relationship) + +registration_target_assoc = db.Table( + "registration_target", + db.Column("registration", db.Integer(), db.ForeignKey("target.id")), + db.Column("target", db.Integer(), db.ForeignKey("registration.id")) +) + + +class Registration(SurrogatePK, Model): + __tablename__ = "registration" + name = Column(String(255), unique=True, nullable=False) + routing_key = Column(String(255), nullable=False) + targets = relationship( + "Target", secondary=registration_target_assoc, backref=db.backref("registrations")) + + def __init__(self, **kwargs): + super(Registration, self).__init__(**kwargs) diff --git a/api/registration/serializers.py b/api/registration/serializers.py new file mode 100644 index 0000000..d04da8d --- /dev/null +++ b/api/registration/serializers.py @@ -0,0 +1,14 @@ +from marshmallow import Schema, fields + +from api.target.serializers import TargetSchema + + +class Registration(Schema): + id = fields.Int() + name = fields.Str() + Token = fields.Str(dump_only=True) + exchange = fields.Nested(TargetSchema, required=True) + + +registration_schema = Registration() +registrations_schema = Registration(many=True) diff --git a/api/registration/views.py b/api/registration/views.py new file mode 100644 index 0000000..a5007cb --- /dev/null +++ b/api/registration/views.py @@ -0,0 +1,68 @@ +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__)