Endpoint for recording events in api.

An event has an id, a type and a blob of json attached.
This commit is contained in:
Adam Shimali
2016-04-27 10:27:05 +01:00
parent bca61454f3
commit dacbbfbf2f
10 changed files with 130 additions and 2 deletions

View File

@@ -60,6 +60,7 @@ def create_app(app_name=None):
from app.accept_invite.rest import accept_invite
from app.notifications_statistics.rest import notifications_statistics as notifications_statistics_blueprint
from app.template_statistics.rest import template_statistics as template_statistics_blueprint
from app.events.rest import events as events_blueprint
application.register_blueprint(service_blueprint, url_prefix='/service')
application.register_blueprint(user_blueprint, url_prefix='/user')
@@ -72,6 +73,7 @@ def create_app(app_name=None):
application.register_blueprint(accept_invite, url_prefix='/invite')
application.register_blueprint(notifications_statistics_blueprint)
application.register_blueprint(template_statistics_blueprint)
application.register_blueprint(events_blueprint)
return application

6
app/dao/events_dao.py Normal file
View File

@@ -0,0 +1,6 @@
from app import db
def dao_create_event(event):
db.session.add(event)
db.session.commit()

0
app/events/__init__.py Normal file
View File

22
app/events/rest.py Normal file
View File

@@ -0,0 +1,22 @@
from flask import (
Blueprint,
jsonify,
request
)
from app.errors import register_errors
from app.schemas import event_schema
from app.dao.events_dao import dao_create_event
events = Blueprint('events', __name__, url_prefix='/events')
register_errors(events)
@events.route('', methods=['POST'])
def create_event():
data = request.get_json()
event, errors = event_schema.load(data)
if errors:
return jsonify(result="error", message=errors), 400
dao_create_event(event)
return jsonify(data=event_schema.dump(event).data), 201

View File

@@ -35,13 +35,13 @@ class User(db.Model):
index=False,
unique=False,
nullable=False,
default=datetime.datetime.now)
default=datetime.datetime.utcnow)
updated_at = db.Column(
db.DateTime,
index=False,
unique=False,
nullable=True,
onupdate=datetime.datetime.now)
onupdate=datetime.datetime.utcnow)
_password = db.Column(db.String, index=False, unique=False, nullable=False)
mobile_number = db.Column(db.String, index=False, unique=False, nullable=False)
password_changed_at = db.Column(db.DateTime, index=False, unique=False, nullable=True)
@@ -414,3 +414,18 @@ class TemplateStatistics(db.Model):
unique=False,
nullable=False,
default=datetime.datetime.utcnow)
class Event(db.Model):
__tablename__ = 'events'
id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
event_type = db.Column(db.String(255), nullable=False)
created_at = db.Column(
db.DateTime,
index=False,
unique=False,
nullable=False,
default=datetime.datetime.utcnow)
data = db.Column(JSON, nullable=False)

View File

@@ -325,6 +325,11 @@ class TemplateHistorySchema(ma.Schema):
created_by_id = fields.UUID()
class EventSchema(BaseSchema):
class Meta:
model = models.Event
user_schema = UserSchema()
user_schema_load_json = UserSchema(load_json=True)
service_schema = ServiceSchema()
@@ -352,3 +357,4 @@ template_statistics_schema = TemplateStatisticsSchema()
service_history_schema = ServiceHistorySchema()
api_key_history_schema = ApiKeyHistorySchema()
template_history_schema = TemplateHistorySchema()
event_schema = EventSchema()

View File

@@ -0,0 +1,32 @@
"""empty message
Revision ID: 0009_events_table
Revises: 0008_archive_template
Create Date: 2016-04-26 13:08:42.892813
"""
# revision identifiers, used by Alembic.
revision = '0009_events_table'
down_revision = '0008_archive_template'
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.create_table('events',
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('event_type', sa.String(length=255), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('data', postgresql.JSON(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
### end Alembic commands ###
def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.drop_table('events')
### end Alembic commands ###

View File

@@ -0,0 +1,19 @@
from app.dao.events_dao import dao_create_event
from app.models import Event
def test_create_event(notify_db, notify_db_session):
assert Event.query.count() == 0
data = {
'event_type': 'sucessful_login',
'data': {'something': 'random', 'in_fact': 'could be anything'}
}
event = Event(**data)
dao_create_event(event)
assert Event.query.count() == 1
event_from_db = Event.query.first()
assert event == event_from_db

View File

View File

@@ -0,0 +1,26 @@
import json
from tests import create_authorization_header
def test_create_event(notify_api):
with notify_api.test_request_context():
with notify_api.test_client() as client:
data = {
'event_type': 'sucessful_login',
'data': {'something': 'random', 'in_fact': 'could be anything'}
}
path = '/events'
auth_header = create_authorization_header(
path=path,
method='POST',
request_body=json.dumps(data))
headers = [('Content-Type', 'application/json'), auth_header]
response = client.post(
path,
data=json.dumps(data),
headers=headers)
assert response.status_code == 201
resp_json = json.loads(response.get_data(as_text=True))['data']
assert resp_json['event_type'] == data['event_type']
assert resp_json['data']['something'] == data['data']['something']
assert resp_json['data']['in_fact'] == data['data']['in_fact']