diff --git a/app/api/__init__.py b/app/api/__init__.py index 96d3ce7..5700bf7 100644 --- a/app/api/__init__.py +++ b/app/api/__init__.py @@ -42,7 +42,9 @@ def add_resources(): from .resources.token import TokenResource, ValidateTokenResource from .resources.device import (DeviceResource, DeviceRecordingResource, - DeviceListResource) + DeviceListResource, + DeviceTypeResource, + DeviceTypeListResource) api.add_resource(AccountResource, '/v1/accounts/') api.add_resource(AccountListResource, '/v1/accounts') @@ -52,6 +54,9 @@ def add_resources(): api.add_resource(DeviceRecordingResource, '/v1/devices//recordings') api.add_resource(DeviceListResource, '/v1/devices') + api.add_resource(DeviceTypeResource, + '/v1/devices/types/') + api.add_resource(DeviceTypeListResource, '/v1/devices/types') add_resources() diff --git a/app/api/resources/device.py b/app/api/resources/device.py index c15b299..67fe3cb 100644 --- a/app/api/resources/device.py +++ b/app/api/resources/device.py @@ -6,9 +6,15 @@ import app.devices as devices from app.api import ProtectedResource +class DeviceTypeSchema(Schema): + id = fields.Integer(dump_only=True) + name = fields.Str(required=True) + + class DeviceSchema(Schema): id = fields.Integer(dump_only=True) name = fields.Str(required=True) + device_type = fields.Nested(DeviceTypeSchema, dump_only=True) class DeviceWrapperSchema(Schema): @@ -20,6 +26,16 @@ class DevicesWrapperSchema(Schema): location='json', many=True) +class DeviceTypeWrapperSchema(Schema): + device_type = fields.Nested(DeviceTypeSchema, required=True, + location='json') + + +class DeviceTypesWrapperSchema(Schema): + device_types = fields.Nested(DeviceTypeSchema, required=True, + location='json', many=True) + + class RecordingsSchema(Schema): recorded_at = fields.DateTime() record_type = fields.Integer() @@ -43,6 +59,29 @@ class DeviceResource(ProtectedResource): return '', 204 +class DeviceTypeResource(ProtectedResource): + @swag_from('swagger/get_device_type_spec.yaml') + def get(self, device_type_id): + return DeviceTypeWrapperSchema().dump( + {'device_type': devices.get_device_type(device_type_id)}), 200 + + +class DeviceTypeListResource(ProtectedResource): + @use_args(DeviceTypeWrapperSchema()) + @swag_from('swagger/create_device_type_spec.yaml') + def post(self, args): + args = args['device_type'] + success = devices.create_device_type( + args['name']) + if success: + return '', 201 + + @swag_from('swagger/get_device_types_spec.yaml') + def get(self): + return DeviceTypesWrapperSchema().dump( + {'device_types': devices.get_device_types()}), 200 + + class DeviceRecordingResource(ProtectedResource): @swag_from('swagger/get_device_recordings_spec.yaml') def get(self, device_id): diff --git a/app/api/resources/swagger/create_device_type_spec.yaml b/app/api/resources/swagger/create_device_type_spec.yaml new file mode 100644 index 0000000..7433cf7 --- /dev/null +++ b/app/api/resources/swagger/create_device_type_spec.yaml @@ -0,0 +1,19 @@ +Creates new device type +Requires DeviceType object and creates device type +--- +tags: + - DeviceType +parameters: + - in: body + name: body + required: true + schema: + type: object + required: + - device_type + properties: + device_type: + $ref: '#/definitions/DeviceType' +responses: + 201: + description: Successful creation diff --git a/app/api/resources/swagger/get_device_type_spec.yaml b/app/api/resources/swagger/get_device_type_spec.yaml new file mode 100644 index 0000000..26bf588 --- /dev/null +++ b/app/api/resources/swagger/get_device_type_spec.yaml @@ -0,0 +1,21 @@ +Gets a device type +--- +tags: + - DeviceType +parameters: + - in: path + name: device_type_id + required: true + type: integer + description: Id of the device type +responses: + 200: + description: Success + schema: + type: object + required: + - device_type + properties: + device_type: + $ref: '#/definitions/DeviceType' + diff --git a/app/api/resources/swagger/get_device_types_spec.yaml b/app/api/resources/swagger/get_device_types_spec.yaml new file mode 100644 index 0000000..47dfbe1 --- /dev/null +++ b/app/api/resources/swagger/get_device_types_spec.yaml @@ -0,0 +1,17 @@ +Gets all device types +--- +tags: + - DeviceType +responses: + 200: + description: Success + schema: + type: object + required: + - device_types + properties: + device_types: + type: array + items: + $ref: '#/definitions/DeviceType' + diff --git a/app/devices/__init__.py b/app/devices/__init__.py index c7fedfb..ece082e 100644 --- a/app/devices/__init__.py +++ b/app/devices/__init__.py @@ -1,6 +1,6 @@ import sys from flask import Blueprint -from .models import Device, Recording, DeviceAssociation +from .models import Device, Recording, DeviceAssociation, DeviceType from app import app devices_bp = Blueprint('devices', __name__) @@ -25,6 +25,19 @@ def create_device(name, account_id, device_type=1): device_association.save() +def create_device_type(name): + """ + Tries to create device type with given parameters + + :param name: Desired device type name + :type name: string + :returns: True if device type is successfully created + :rtype: Boolean + """ + device_type = DeviceType(name) + device_type.save() + + def get_device_recordings(device_id): """ Tries to get device recording for device with given parameters. Raises @@ -58,6 +71,23 @@ def get_device(device_id): return Device.get(id=device_id) +def get_device_type(device_type_id): + """ + Tries to get device type with given parameters. Raises error on failure + + :param device_type_id: Id of device type + :type device_type_id: int + :returns: Requested device type + :rtype: DeviceType + :raises: ValueError if device type does not exist + """ + if not DeviceType.exists(id=device_type_id): + raise ValueError("Device type with id %s does not exist" % + device_type_id) + + return DeviceType.get(id=device_type_id) + + def delete_device(device_id): """ Tries to delete device with given parameters. Does not raise errors @@ -80,6 +110,16 @@ def get_devices(account_id): return Device.get_many_for_user(account_id) +def get_device_types(): + """ + Tries to get all device types. Raises error on failure + + :returns: List of device types + :rtype: List of DeviceTypes + """ + return DeviceType.get_many() + + def create_recording(device_id, raw_json): """ Tries to create recording with given parameters. Raises error on failure diff --git a/app/devices/models.py b/app/devices/models.py index af59940..07b4bbf 100644 --- a/app/devices/models.py +++ b/app/devices/models.py @@ -243,6 +243,45 @@ class DeviceType(db.Model): def __init__(self, name): self.name = name + def save(self): + """ + Stores this device type to database + This may raise errors + """ + db.session.add(self) + db.session.commit() + + @staticmethod + def get_many(**kwargs): + """ + Get many devices types with given filters as a list + + Available filters: + * id + * name + """ + return DeviceType.query.filter_by(**kwargs).all() + + @staticmethod + def get(**kwargs): + """ + Get device type with given filters + + Available filters: + * id + * name + """ + return DeviceType.query.filter_by(**kwargs).first() + + @staticmethod + def exists(**kwargs): + """ + Checks if device type with all of the given arguments exists + """ + if DeviceType.query.filter_by(**kwargs).first(): + return True + return False + def __repr__(self): return '' % self.name diff --git a/app/swagger/template.yaml b/app/swagger/template.yaml index 291372e..cb0dd17 100644 --- a/app/swagger/template.yaml +++ b/app/swagger/template.yaml @@ -21,6 +21,11 @@ definitions: type: string description: Time + devicetypename: + type: string + description: Name of device type + default: STANDARD + devicename: type: string description: Name of device @@ -92,16 +97,30 @@ definitions: description: Value of the recording default: '25 degrees' - Device: + DeviceType: type: object required: - id - name + properties: + id: + $ref: '#/definitions/id' + name: + $ref: '#/definitions/devicetypename' + + Device: + type: object + required: + - id + - name + - device_type properties: id: $ref: '#/definitions/id' name: $ref: '#/definitions/devicename' + device_type: + $ref: '#/definitions/DeviceType' UnauthorizedError: type: object