From aeb8916744e777c189f4f4b6afbee569c1c8ac98 Mon Sep 17 00:00:00 2001 From: Gardient Date: Tue, 21 Sep 2021 21:23:14 +0300 Subject: [PATCH] added target entity --- .gitignore | 1 + api/__init__.py | 7 ++- api/target/__init__.py | 3 + api/target/models.py | 12 ++++ api/target/serializers.py | 11 ++++ api/target/views.py | 60 +++++++++++++++++++ .../versions/294a2085f840_added_targets.py | 36 +++++++++++ 7 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 api/target/__init__.py create mode 100644 api/target/models.py create mode 100644 api/target/serializers.py create mode 100644 api/target/views.py create mode 100644 migrations/versions/294a2085f840_added_targets.py diff --git a/.gitignore b/.gitignore index c026f95..341a602 100644 --- a/.gitignore +++ b/.gitignore @@ -145,3 +145,4 @@ cython_debug/ # End of https://www.toptal.com/developers/gitignore/api/python *.db +!api/target diff --git a/api/__init__.py b/api/__init__.py index e7eb19b..b8f272f 100644 --- a/api/__init__.py +++ b/api/__init__.py @@ -1,5 +1,5 @@ from flask import Flask, Blueprint -from . import commands, login, target_exchange +from . import commands, login, target_exchange, target from .settings import ProdConfig, Config from .extensions import db, migrate, jwt, apispec from .exceptions import ApiException @@ -40,6 +40,8 @@ def register_blueprints(app: Flask): login.views.blueprint, url_prefix='/login') api_blueprint.register_blueprint( target_exchange.views.blueprint, url_prefix='/target-exchange') + api_blueprint.register_blueprint( + target.views.blueprint, url_prefix='/target') app.register_blueprint(api_blueprint) @@ -80,7 +82,8 @@ def register_shellcontext(app: Flask): """Shell context objects.""" return { 'db': db, - 'TargetExchange': target_exchange.models.TargetExchange + 'TargetExchange': target_exchange.models.TargetExchange, + 'Target': target.models.Target } app.shell_context_processor(shell_context) diff --git a/api/target/__init__.py b/api/target/__init__.py new file mode 100644 index 0000000..a1ab2c1 --- /dev/null +++ b/api/target/__init__.py @@ -0,0 +1,3 @@ +"""Target view""" + +from . import views, models diff --git a/api/target/models.py b/api/target/models.py new file mode 100644 index 0000000..9845493 --- /dev/null +++ b/api/target/models.py @@ -0,0 +1,12 @@ +from api.database import (Model, SurrogatePK, db, + Column, reference_col, relationship) +from sqlalchemy import String + +from api.target_exchange.models import TargetExchange + +class Target(SurrogatePK, Model): + __tablename__ = "target" + name = Column(String(255), unique=True, nullable=False) + routing_key = Column(String(255), nullable=False) + target_exchange_id = reference_col(TargetExchange.__tablename__, nullable=False) + exchange = relationship(TargetExchange.__name__, backref=db.backref('targets')) diff --git a/api/target/serializers.py b/api/target/serializers.py new file mode 100644 index 0000000..4591954 --- /dev/null +++ b/api/target/serializers.py @@ -0,0 +1,11 @@ +from marshmallow import Schema, fields +from api.target_exchange.serializers import TargetExchangeSchema + +class TargetSchema(Schema): + id = fields.Int() + name = fields.Str() + routing_key = fields.Str(required=True) + exchange = fields.Nested(TargetExchangeSchema) + +target_schema = TargetSchema() +targets_schema = TargetSchema(many=True) diff --git a/api/target/views.py b/api/target/views.py new file mode 100644 index 0000000..e04d840 --- /dev/null +++ b/api/target/views.py @@ -0,0 +1,60 @@ +from flask import Blueprint +from flask_jwt_extended import jwt_required +from flask_apispec import use_kwargs, marshal_with, doc +from marshmallow import fields + +from api.exceptions import NotFoundException +from api.target_exchange.models import TargetExchange + +from .models import Target +from .serializers import target_schema, targets_schema + +blueprint = Blueprint('target', __name__) + + +@doc(tags=['Target']) +@blueprint.route('', methods=['GET']) +@jwt_required() +@use_kwargs({'exchange': fields.Str()}) +@marshal_with(targets_schema) +def get_list(exchange=None): + res = Target.query + if exchange is not None: + res = res.join(Target.exchange).filter(TargetExchange.name == exchange) + return res.all() + + +@doc(tags=['Target']) +@blueprint.route('', methods=['POST']) +@jwt_required() +@use_kwargs(target_schema) +@marshal_with(target_schema) +def create(name): + target = Target(name=name) + target.save() + return target + + +@doc(tags=['Target']) +@blueprint.route('/', methods=['GET']) +@jwt_required() +@marshal_with(target_schema) +def get_by_id(id): + target_exchange = Target.get_by_id(id) + if target_exchange is not None: + return target_exchange + else: + return NotFoundException(Target.__name__) + + +@doc(tags=['Target']) +@blueprint.route('/', methods=['PUT']) +@jwt_required() +@use_kwargs(target_schema) +@marshal_with(target_schema) +def update(id, **kwargs): + target_exchange = Target.get_by_id(id) + if target_exchange is not None: + return target_exchange.update(**kwargs) + else: + return NotFoundException(Target.__name__) diff --git a/migrations/versions/294a2085f840_added_targets.py b/migrations/versions/294a2085f840_added_targets.py new file mode 100644 index 0000000..2b6cda2 --- /dev/null +++ b/migrations/versions/294a2085f840_added_targets.py @@ -0,0 +1,36 @@ +"""added targets + +Revision ID: 294a2085f840 +Revises: 14ceaaaa6e85 +Create Date: 2021-09-21 21:20:27.226540 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '294a2085f840' +down_revision = '14ceaaaa6e85' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('target', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', sa.String(length=255), nullable=False), + sa.Column('routing_key', sa.String(length=255), nullable=False), + sa.Column('target_exchange_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['target_exchange_id'], ['target-exchange.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('name') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('target') + # ### end Alembic commands ###