Errors and Error handlers for REST API

Errors are an essential part of a REST API system. Error instances must follow a particular structure so the client developer can correctly handle them at the client side. We had set a proper error structure at the beginning of creating REST APIs. It’s as follows:

{
    "error": {
        "message": "Error description",
        "code": 400
    }
}

Any error occurring during client server communication would follow the above format. Code is the returned status code and message is a brief description of the error. To raise an error we used an _error_abort() function which was an abstraction over Flask-RESTplus abort(). We defined an error structure inside _error_abort() and passed it to abort().

def _error_abort(code, message):
    error = {
        'code': code,
        'message': message,
    }
    abort(code, error=error)

This method had its limitations. Since the error handlers were not being overidden, only errors raised through _error_abort() had the defined structure. So if an Internal Server error occurred, the returned error response wouldn’t follow the format.

To overcome this, we wrote our own exceptions for errors and created error handlers to handle them. We first made the response structure more detailed, so the client developer can understand what kind of error is being returned.

{
    "error": {
        "code": 400,
        "message": "'name' is a required parameter",
        "status": "INVALID_FIELD",
        "field": "name"
    }
}

The above is an example of a validation error.

The “status” key helps making the error more unique. For example we use 400 status code for both validation errors and invalid service errors (“Service not belonging to said event”). But both have different statuses: “INVALID_FIELD” and “INVALID_SERVICE”.

The “field” key is only useful in the case validation errors, where it names the field that did not pass the validation. For other errors it remains null.

I first documented what kind of errors we would need.

Code Status Field Description
401 NOT_AUTHORIZED null Invalid token or user not authenticated
400 INVALID_FIELD “field_name” Missing or invalid field
400 INVALID_SERVICE null Service ID mentioned in path does not belong to said Event
404 NOT_FOUND null Event or Service not found
403 PERMISSION_DENIED null User role not allowed to perform such action
500 SERVER_ERROR null Internal server error

Next part was creating exception classes for each one these. I created a base error class that extended the python Exception class.

class BaseError(Exception):
    """Base Error Class"""

    def __init__(self, code=400, message='', status='', field=None):
        Exception.__init__(self)
        self.code = code
        self.message = message
        self.status = status
        self.field = field

    def to_dict(self):
        return {'code': self.code,
                'message': self.message,
                'status': self.status,
                'field': self.field, }

The to_dict() method would help when returning the response in error handlers.

I then extended this base class to other error classes. Here are three of them:

class NotFoundError(BaseError):
    def __init__(self, message='Not found'):
        BaseError.__init__(self)
        self.code = 404
        self.message = message
        self.status = 'NOT_FOUND'


class NotAuthorizedError(BaseError):
    def __init__(self, message='Unauthorized'):
        BaseError.__init__(self)
        self.code = 401
        self.message = message
        self.status = 'NOT_AUTHORIZED'


class ValidationError(BaseError):
    def __init__(self, field, message='Invalid field'):
        BaseError.__init__(self)
        self.code = 400
        self.message = message
        self.status = 'INVALID_FIELD'
        self.field = field

I then defined the error handlers for the api:

@api.errorhandler(NotFoundError)
@api.errorhandler(NotAuthorizedError)
@api.errorhandler(ValidationError)
@api.errorhandler(InvalidServiceError)
def handle_error(error):
    return error.to_dict(), getattr(error, 'code')

For overriding the default error handler, Flask-RESTplus let’s you create one with the same decorator, but without passing and argument to it.

@api.errorhandler
def default_error_handler(error):
    """Returns Internal server error"""
    error = ServerError()
    return error.to_dict(), getattr(error, 'code', 500)

I had set the default error to be the internal server error.

class ServerError(BaseError):
    def __init__(self, message='Internal server error'):
        BaseError.__init__(self)
        self.code = 500
        self.message = message
        self.status = 'SERVER_ERROR'

Now raising any of these error classes would activate the error handlers and a proper response would be sent to the client.

Continue ReadingErrors and Error handlers for REST API

Open Event Apk generator

So we made this apk generator currently hosted on a server (http://192.241.232.231) which let’s you generate an android app for your event in 10 minutes out of which the server takes about 8 minutes to build 😛 . So, essentially you just have to spare 2 minutes and just enter 3 things(email, Desired app’s name and Api link). Isn’t this cool?

So how exactly do we do this?

At the backend, we are running a python scripts with some shell scripts where the python script is basically creating directories, interacting with our firebase database to get the data entered by a user. So we made these scripts to first of all to clone the open event android repo, then customise and change the code in the repo according to the parameters entered by the organiser earlier(shown in the image).

Screen Shot 2016-06-14 at 12.13.12 AM
Generator Website

After the code has been changed by the scripts to customise the app according to the event the app will be used for, we move on to the script to build the apk, where we build and sign the apk in release mode using signing configs and release keys from the server because we don’t the organiser to generate keys and store it on the server to avoid the hassle and also the privacy concerns involving the keys. So this is when the apk is generated on the server. Now you have questions like the apk is generated but how do I get it? Do I have to wait on the same page for 10 minutes while the apk is being sent? The answer is no and yes. What I mean by this is that you can wait to download the apk if you want but we’ll anyways send it to your email you specified on the apk generator website. This is the sample Email we got when we were testing the system

Screen Shot 2016-06-14 at 12.08.59 AM.png

So it’s an end to end complete solution from which you can easily get an android app for your event in just 2 minutes. Would love to hear feedback and reviews. Please feel free to contact me @ manan13056@iiitd.ac.in or on social media’s(Twitter, Facebook). Adios!

P.S. : Here is the link to the scripts we’re using.

Continue ReadingOpen Event Apk generator

Why should you use Heroku?

Last week I’ve dedicated most time to implement new heroku features to Open Event. Due to the fact that wasn’t easy tasks I can share my experience.

What is heroku?

Heroku is a cloud Platform-as-a-Service (PaaS) supporting several programming languages like Java, Node.js, Scala, Clojure, Python, PHP, and Go

Easy to deploy

what you need to do:

  1. Create account on heroku
  2. Download a heroku toolbelt to your enviroment.
  3. Go to your project directory(/open-event-orga-server)
  4. Sign in to heroku in your command line using your credentials
    $ heroku login
  5. Create app with name $
    heroku apps:create your_app_name

    after execution above command you will recive a link to your application

    http://your_app_name.herokuapp.com/
  6. Push latest changes to heroku
    $ git push heroku master
  7. If everythings is ok you can check results http://your_app_name.herokuapp.com/ (sometimes it does not work like we want 🙁 )

Easy to configure

To list/set/get config variables use:

$ heroku config
$ heroku config:set YOUR_VARIABLE=token123
$ heroku config:get YOUR_VARIABLE

or you can go to you application dashboard and make above operations

How you can get access to this variables using python langauges?

$ python

Python 2.7.10 (default, Oct 23 2015, 19:19:21) 

[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin

Type "help", "copyright", "credits" or "license" for more information.

>>> import os

>>> your_variable  = os.environ.get('YOUR_VARIABLE', None)

>>> print your_variable
token123

I’ve used this to display current release in my python application(You need to generate a special API token and add it to config variables)

os.popen('curl -n https://api.heroku.com/apps/open-event/releases -H 
"Authorization: Bearer ' + token + '" -H 
"Accept: application/vnd.heroku+json; version=3"').read()

Easy to monitor

If something is wrong with your APP you need to use this command

$ heroku logs

it shows all logs

To see 10 latest releases use:

$ heroku releases

How you can set up Open Event to deploy to heroku?

  1. Clone https://github.com/fossasia/open-event-orga-server
  2. Go to directory of open event orga server(/open-event-orga-server)
  3. Add git remote
     heroku git:remote -a open-event
  4. You can check if open event is added to git remote
    $ git remote -v
    heroku https://git.heroku.com/open-event.git (fetch)
    heroku https://git.heroku.com/open-event.git (push)
    origin https://github.com/fossasia/open-event-orga-server.git (fetch)
    origin https://github.com/fossasia/open-event-orga-server.git (push)
  5. Now you can deploy changes to open-event application(You need a permissions 🙂 )

Why should you use a Heroku?

It’s great to deploy apps because you are able to share content in short time what I’ve done. Besides it’s very well documented so you can find there answers for most of your questions. Finally most of things you can configure using Heroku dashboard so it’s the best advantages of this tool.

Continue ReadingWhy should you use Heroku?

Better fields and validation in Flask Restplus

We at Open Event Server project are using flask-restplus for API. Apart from auto-generating of Swagger specification, another great plus point of restplus is how easily we can set input and output models and the same is automatically shown in Swagger UI. We can also auto-validate the input in POST/PUT requests to make sure that we get what we want.

@api.expect(EVENT_POST, validate=True)
def put(self, id):
    """Modify object at id"""
    pass

As can be seen above, the validate param for namespace.expect decorator allows us to auto-validate the input payloads. This used to work well until one day I realized there were a few problems.

  1. When a field was defined as say for example field.Integer, then it will accept only Integer values, not even null.
  2. If there is a string field and it has required param set to True, then also it is possible to set empty string as its value and the in-built validator won’t catch it.
  3. Even if I somehow managed to hack my way to support null in field, it will also support null even if required=True.
  4. We had no control on what error message was returned.
EVENT = api.model('Event', {
    'id': fields.Integer,
    'name': fields.String(required=True)
})

Specially problem #1 was a huge one as it questioned the whole foundation of the API. So we realized it will be better if we don’t use namespace.expect and use a custom validator. For custom validator, we first had to create custom fields that this validator can benefit from. Luckily flask-restplus comes with a great API for creating custom fields. So we quickly created custom fields for all common fields (Integer, String) and more specific fields like Email, Uri and Color. Creating these specific fields were a huge advantage as now we can show proper example for each field types in the Swagger UI.

class Email(fields.String):
    """
    Email field
    """
    __schema_type__ = 'string'
    __schema_format__ = 'email'
    __schema_example__ = 'email@domain.com'

Consider the above code; now when we use Email as a field for a value, then the example shown for it in Swagger UI will be ‘email@domain.com’. Quite cool, right?

Now we needed a way to validate these fields. For that, what we did was to create a validate method in each of the field-classes. This validate method would get the value and check if it was valid. Consider the following code –

import re
EMAIL_REGEX = re.compile(r'S+@S+.S+')

class Email():
	def validate(self, value):
		if not value:
		    return False if self.required else True
		if not EMAIL_REGEX.match(value):
		    return False
		return True

Once each of the field had their validate methods, we created a validate_payload() function that uses the API model and compares it with the payload. It will first check if all required keys are present in the payload or not. When that is true, it finally validates each field’s value using their field’s classvalidate method.

from flask import abort
from flask_restplus import fields
from custom_fields import CustomField

def validate_payload(payload, api_model):
    # check if any reqd fields are missing in payload
    for key in api_model:
        if api_model[key].required and key not in payload:
            abort(400, 'Required field '%s' missing' % key)
    # check payload
    for key in payload:
        field = api_model[key]
        if isinstance(field, fields.List):
            field = field.container
            data = payload[key]
        else:
            data = [payload[key]]
        if isinstance(field, CustomField) and hasattr(field, 'validate'):
            for i in data:
                if not field.validate(i):
                    abort(400, 'Validation of '%s' field failed' % key)

The CustomField is the base class that each of the custom fields mentioned above inherit. So checking if field was an instance of CustomField is enough to know if it is a custom field or not. Other thing that may look weird in the above code is use of fields.List. If you look closely, I have added this to support custom fields inside lists. So if you have used a custom field in a list, it will also work too. But obviously, this only supports single level lists for now. The thing is we didn’t needed more than that so I let it go. :stuck_out_tongue_winking_eye:

This basically sums up how we are validating input payloads at Open Event. Of course this is very basic but we will keep on improving it as the project progresses. Stay tuned to opev blog if you want to be in touch with the progress of the project.

Links to full code at the time of writing this post are –

  1. Custom Fields
  2. Validate Payload

I hope you found this post useful. Thanks for reading.

 

{{ Repost from my personal blog http://aviaryan.in/blog/gsoc/restplus-validation-custom-fields.html }}

Continue ReadingBetter fields and validation in Flask Restplus

Export Timeline as iCal

iCal or iCalendar is the Internet standard for sharing event schedules or session timelines among each other. The filename extension for iCal is .ics . It is supported by a number of applications such as Google Calendar, Apple Calendar,] Yahoo! Calendar, Lightning extension for Mozilla Thunderbird and SeaMonkey, and partially by Microsoft Outlook . In Open Event Organizer’s Server we have added a feature to export the Schedule of a particular Event in iCal format.

Continue ReadingExport Timeline as iCal

Swagger

Swagger is a specification for describing REST APIs. The main aim of Swagger is to provide a REST API definition format that is readable by both machines and humans.

You can think of two entities in a REST API: One the provider of API, and another the client using the API. Swagger essentially covers the gap between them by providing a format that is easy to use by the client and easy for the provider to define.

If not using Swagger, one would most certainly be creating the API first, writing the documentation (human-readable) with it. The client developer would read the documentation and use APIs as required. With Swagger, the specification can be considered as the document itself, helping both the client developer and the provider.

Here’s an example spec I wrote for our GET APIs at Organizer Server: https://gist.github.com/shivamMg/dacada0b45585bcd9cd0fbe4a722eddf

The format, although readable doesn’t really look what a client developer would be asking for.

Remember that the format is machine readable? What does it mean exactly?

Since the Swagger spec is a defined format, the provider can document it and people can write programs that understand the Swagger specification. Swagger itself comes with a set of tools (http://swagger.io/tools/) that use Swagger definitions created by the API provider to create SDKs for the clients to use.

Swagger-UI

One of our most used tools at our server is the Swagger UI (http://swagger.io/swagger-ui/).

It reads an API spec written in Swagger to generate corresponding UI that people can use to explore the APIs. Every API endpoint can have responses and parameters associated with it. For instance our Event endpoint at Server (“/events/:event_id”).

You can see how the UI displays the Model Schema, required parameters and possible response message.

Screenshot from 2016-06-07 19:08:21

Apart from documentation, Swagger UI provides the “Try it out!” tool that lets you make requests to the server for the corresponding API. This feature is incredibly useful for POST requests. No need for long curl commands in the terminal.

Here’s the Swagger config from our demo application: https://open-event.herokuapp.com/api/v2/swagger.json

The Swagger UI for this config can be found at https://open-event.herokuapp.com/api/v2

The UI for the example spec (gist) I linked before can be browsed here.

Swagger-js

https://github.com/swagger-api/swagger-js

Swagger-js is JS library that reads an API spec written in Swagger and provides an interface to the client developer to interact with the API. We will be using Swagger-js for Open Event Webapp.

Here’s an example to show you how it works. Let’s say the following endpoint returns (json) a list of events.

/events

The client developer can create a GET request and render the list with HTML.

$.getJSON("http://example.com/api/v2/events", function(data) {

  var events = "";
  $.each(data, function(i, event) {
    events += "<li id='event_" + i + "'>" + event.name + "</li>";
  });

  $("ul#events").html(events);
});

What if the provider moves the endpoint to “/event/all”? The client developer would need to change every instance of the URL to http://example.com/event/all.

Let’s now take the case of Swagger-js. With Swagger-js the client developer would essentially be writing programs to interact with the API Swagger spec defined by the provider, instead of directly consuming the API.

window.client = new SwaggerClient({
    url: "http://example.com/api/v2/swagger.json",
    success: function() {
      client.event.getEvents({
        responseContentType: 'application/json'
      }, function(data) {

        /* Create `events` string same as before */

        $("ul#events").html(events);
      });
    }
  });

 

The APIs at the Organizer server are getting more complex. Swagger helps in keeping the spec well defined.

That’s all for now. Hope you enjoyed the read.

Continue ReadingSwagger

Bower Dependency & Configure .bowerrc to use Proxy

2 weeks into GSOC 2016, the project has really started to grow at a rapid pace. There have been a lot of issues related to UI as well as other different bugs. As we use more and more libraries for the user interface of the dashboard, we added bower dependencies to install the libraries.

Why Use Bower?

Some of the benefits of using bower dependencies are:

  • Simplify what might be called declarative dependency management; i.e. you declare your dependencies in bower.json so that other things can determine them easily
  • No need to commit dependencies to version control
  • Semantic versioning is used to help define a range of acceptable versions for a dependency, which makes it easy to update to newer versions within the defined range
  • No need to locate various builds (debug, minified, etc)
  • Simple to use different builds of a dependency for dev vs. prod
  • Bower lets you easily search and install libraries even locking to a specific version. Bower makes it easy to list and update dependencies.
  • You can distribute the bower.json file and everyone can get up to speed with a simple “bower install”

Prerequisites

There are some things you’ll need before you can start working with Bower:

  • The command line.
  • Node and NPM.
  • Git.
  • Global Installation. .

To install Bower globally:

$ npm install -g bower

bower.json

The `bower.json` file looks a lot like Node’s `package.json`. It is a manifest file that allows you to specify the various packages you want to download along with their version number and various features. This is how the `bower.json` looks for the open-event-orga-server project.Screenshot from 2016-06-04 05:25:08.png

.bowerrc

The `.bowerrc` file can be seen as a configure file for bower which dictates various rules to it. Though mostly this file is ignored and is used mainly to specify the directory where the libraries are to be installed instead of the default `bower_components`, however it can be used to do a lot more than that.

Screenshot from 2016-06-04 05:29:50.png

For example, one of the biggest problem you might face while installing using bower is if your organization/institute has a proxy network through all network connections pass. In that case bower install might not be able to install the libraries. However we can configure the .bowerrc to work via proxy.

Configure .bowerrc to use Proxy

To use http proxy, we can add 2 properties to .bowerrc which will make bower search and install libraries using the proxy. The properties are “proxy” and “https-proxy”. This 2 properties dictate that both http:// and https:// links are to be searched via the proxy. So, to make this settings, we can configure the .bowerrc something like this:
Screenshot from 2016-06-04 05:35:13.png

This should then fix your problem of proxy and will install your libraries as desired.

Continue ReadingBower Dependency & Configure .bowerrc to use Proxy

Better project definitions with User Stories and Themes

The Open Event project of FOSSASIA’s consists of a group of applications which involve making an application for managing events including the Open-Event Webapp, the Open-Event Android, Open-Event ios, and Open-Event Server of which I am working on.

The Open-Event Server is responsible for handling all the backend or the database aspect of the Open Event application. All the data for the application – the user details, the sessions details, the event details etc… is being managed by the server. But up till now we only had a basic working server with an prototype UI. In short not ready for people to use for their events . Thus my project was developed – Improving the Open-Event Organization project.

What is my project about?

The first versions of Open Event Server and the other subprojects – the Webapp and Android were not based on a user experience. So what we did this time was to create a user story for each of the projects. For the server, we created a user story wherein we decided what all functionalities will a user encounter when he /she uses our server. Thus step by step our project is being developed based on the user story created.

I have already solved a lot of issues which involve both – adding code to the backend as well as the frontend aspect. We have now a pretty good and properly functioning server with a login system involving Google and Facebook supported login. We also have a very awesome UI all thanks to gentelella. Presently we are working on the sessions part of the event creation wizard which is broken in various stages – Draft, Call for Papers, Schedule, Completed. The Draft part is almost finished and the Call for Papers part is going on.

Continue ReadingBetter project definitions with User Stories and Themes

Transmitting response from a Web page to a server.

{ Re-post from my Medium Post }

My project has pivoted from a standalone android app to a Web page that will generate a custom app for an event organizer’s use.

Read up here on what my project actually is.

So obviously some changes at the server are to be made to make this possible.

How are you planning to do it?

First of we started by providing a Web page that the organizers can use to submit information about the app they need to be built like the App’s name, the link to the API (for fetching the json files) and their email address (for mailing them the apk once it’s generated).

The HTML file for the same can be found here.

Some changes to the Travis build should also be made so that it can use this data for building.

From there on, the details submitted by them will be converted by a json object (using javascript) and further send to the open event server via a POST request where it will be written to a database.

We will be able to fetch this file from the database by the following link

openevent.com/api/v2/customapps/id.

Simultaneously one Travis build will also be trigger using the API that will auto build the latest commit, taking the modified json file data provided by the orga-server.

This configuration will be provided to Travis while the build time.

Cool, any difficulties yet!

One of the main challenges that we are facing is manually triggering the Travis build.

We can do this via the Travis API but that’s still in beta and also we are getting our head around on how to implement it.

I also had a tough time learning javascript and HTML for making the Web page and then I also have to read up on sending a POST request to the server via Ajax.

It’s a bit tough, but should be fun.

So, that was all for now, see you next week and all the best for your projects.✌

Continue ReadingTransmitting response from a Web page to a server.

Open Event: Planning the Scheduler UI

{ Repost from my personal bloghttps://blog.codezero.xyz/planning-the-scheduler-ui/ }

In the first phase of the GSoC coding period, Saptak Sengupta and myself have been working on the Scheduler UI.

The Scheduler UI would allow the organizers to graphically schedule/manage the sessions in their conference/event.

Event-Organizer by Josh Greco has been a major inspiration for the timeline design. The css styles have been borrowed from that project.

After some research, we have decided to use the interact.js javascript library for implementing drag-drop and resizing functionality to the project and lodash for array/collection manipulations and for some useful utility functions.

The following tasks have been formulated:

  • Drag-and-drop interface to add session blocks into a timeline
  • Resize sessions to change time
  • load live data from the server using the API
  • Handle session clashes within a track properly
  • Add Track button that opens up a modal to add a track.
  • Search option for unscheduled sessions
  • Save each session change/update using the API
  • Option to Export timeline as pdf
  • Option to export timeline/calendar as iCal

An umbrella issue (#349) has been created in the open-event-orga-serverrespository to track the progress. There will be a separate issue created for each task when that task is being worked upon and the same would be referred to in the umbrella issue.

We are targeting GSOC 2016: Milestone 4 (Due by June 12, 2016) to finish the Scheduler UI and we are confident that we’ll be able to reach our target. *fingers-crossed* :sweat_smile:

To know more about the Scheduler UI, read Enhancing the Open Event Server: Scheduler UI.

Continue ReadingOpen Event: Planning the Scheduler UI