DEV Community

asaf g
asaf g

Posted on • Originally published at turtle-techies.com on

Instant Rest Api Written in Python

Why would you need an Instant Rest API?

  • You are developing a client side application that doesn't have a server yet
  • You are trying out a new library and you want to see if it plays nice
  • You are preparing a demo that needs a simple server and don't want to trouble yourself with actually building one
  • You are doing testing on some system and need a stub

If you need it you can get it here.

Is It Really Instant?

Basically, you just define the objects you want to have in your rest api and start the server.

It can take you under a minute if you are really fast.

How To Use

First, clone the repository:

$ git clone https://github.com/asafg6/instant-rest-api.git
Enter fullscreen mode Exit fullscreen mode

I usually use virtualenvwrapper, but this is optional.

If you don't have it and want to install it go here.
If you have it:

$  mkvirtualenv -p python3 instant-api
Enter fullscreen mode Exit fullscreen mode

Instant Rest Api is built with falcon so it has to be installed.

Install the dependencies:

$ cd instant-api
$ pip install -r dependencies.txt
Enter fullscreen mode Exit fullscreen mode

Let's say we want our model to be "Dog". so - the properties that it will have are: name, breed, color, age.

Let's add our new model to user_models.py.

user_models.py


"""
your models go here

example:

from model import InstantModel

class User(InstantModel):

    name = ''
    phone_number = ''
    address = ''
    age = 0

"""

from model import InstantModel


class Dog(InstantModel):

    name = ''
    breed = ''
    color = ''
    age = 0


Enter fullscreen mode Exit fullscreen mode

Run the server:

$ python
Enter fullscreen mode Exit fullscreen mode

Great! It's running!

Let's test the server (in another terminal window):

$ curl http://localhost:8000
{"routes": ["/dog"]}
Enter fullscreen mode Exit fullscreen mode

The root url gives us the possible routes.

Let's list our dogs:

$ curl http://localhost:8000/dog
{"message": null, "body": [], "status": "OK"}
Enter fullscreen mode Exit fullscreen mode

We don't have any dogs yet, let's create some:

$ curl -X POST ht​tp://localhost:8000/dog -H "Content-Type: application/json" -d '{"name": "lucky", "age": 4, "breed": "collie", "color": "brown"}'
{"message": "object created", "body": {"id": "0"}, "status": "OK"}
$ curl -X POST http://localhost:8000/dog -H "Content-Type: application/json" -d '{"name": "rocky", "age": 2, "breed": "jack russel", "color": "white"}'
{"message": "object created", "body": {"id": "1"}, "status": "OK"}
$ curl -X POST http://localhost:8000/dog -H "Content-Type: application/json" -d '{"name": "rex", "age": 7, "breed": "collie", "color": "white"}'
{"message": "object created", "body": {"id": "2"}, "status": "OK"}
$ curl -X POST http://localhost:8000/dog -H "Content-Type: application/json" -d '{"name": "rover", "age": 1, "breed": "rottweiler", "color": "black"}'
{"message": "object created", "body": {"id": "3"}, "status": "OK"}
Enter fullscreen mode Exit fullscreen mode

So now our server has some dogs. let's list again and look at the results (indented for convenience):

$ curl http://localhost:8000/dog
{
  "message": null,
  "body": [
    {
      "age": 1,
      "breed": "rottweiler",
      "id": "3",
      "name": "rover",
      "color": "black"
    },
    {
      "age": 7,
      "breed": "collie",
      "id": "2",
      "name": "rex",
      "color": "white"
    },
    {
      "age": 2,
      "breed": "jack russel",
      "id": "1",
      "name": "rocky",
      "color": "white"
    },
    {
      "age": 4,
      "breed": "collie",
      "id": "0",
      "name": "lucky",
      "color": "brown"
    }
  ],
  "status": "OK"
}
Enter fullscreen mode Exit fullscreen mode

Looking good.

We can also filter our results:

$ curl http://localhost:8000/dog?color=white
{
  "message": null,
  "body": [
    {
      "age": 7,
      "breed": "collie",
      "id": "2",
      "name": "rex",
      "color": "white"
    },
    {
      "age": 2,
      "breed": "jack russel",
      "id": "1",
      "name": "rocky",
      "color": "white"
    }
  ],
  "status": "OK"
}
Enter fullscreen mode Exit fullscreen mode

Or get an object by id:

$ curl http://localhost:8000/dog?id=1
{
  "message": null,
  "body": {
    "age": 2,
    "breed": "jack russel",
    "id": "1",
    "name": "rocky",
    "color": "white"
  },
  "status": "OK"
}
Enter fullscreen mode Exit fullscreen mode

You can also use sort, desc, limit and offset.

If an object doesn't exist we'll get an error

$ curl http://localhost:8000/dog?id=999
{"message": "Object 999 not found", "body": {}, "status": "ERROR"}
Enter fullscreen mode Exit fullscreen mode

Of course we can also update an object:

$ curl -X PUT http://localhost:8000/dog?id=3 -H "Content-Type: application/json" -d '{"age": 2}'
{
  "message": "Updated",
  "body": {
    "age": 2,
    "breed": "rottweiler",
    "id": "3",
    "name": "rover",
    "color": "black"
  },
  "status": "OK"
}
Enter fullscreen mode Exit fullscreen mode

And finally delete an object:

$ curl -X DELETE http://127.0.0.1:8000/dog?id=3
{"message": "Deleted", "body": {}, "status": "OK"}
Enter fullscreen mode Exit fullscreen mode

How Does It Work?

You might have noticed that the Dog class inherits from InstantModel. The main function lists all InstanModel's subclasses and create instances like this:

    import user_models
    for name, klass in inspect.getmembers(user_models,
                                          lambda x: inspect.isclass(x) and issubclass(x, InstantModel)):
        if klass == InstantModel:
            continue
        resource_model = klass()
Enter fullscreen mode Exit fullscreen mode

The InstantModel class uses the model's properties to create a generic CRUD. Objects are saved to a dictionary and are also written to disk. when the class initiates, it reads the content written by the server in the past and loads it into memory to be ready for reading.

The ViewResource is built generically to work with the InstantModel interface.

The main function sets a resource and a route for each model like this:

        view = ViewResource(resource_model)
        route = '/%s' % name.lower()
        app.add_route(route, view)
        routes.append(route)
Enter fullscreen mode Exit fullscreen mode

The code is pretty simple and straight forward, it is also quite short.
If you want to know more read it.

Summary

This utility is really simple, it's a nice stub.

Comments and pull requests are most welcome.

Thank you for reading.

Top comments (0)