Instant Rest Api Written in Python
Tags: python, rest
Published: 2020-08-26 11:52:35

---
title: Instant Rest Api Written in Python
published: true
date: 2017-12-09 21:38:15 UTC
tags:  ["python", "rest"]
canonical_url: https://www.turtle-techies.com/post/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 <a href="https://github.com/asafg6/instant-rest-api" target="_blank">here</a>.  

## 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:  
```shell
$ git clone https://github.com/asafg6/instant-rest-api.git
```

I usually use virtualenvwrapper, but this is optional.  
If you don't have it and want to install it go <a href="https://virtualenvwrapper.readthedocs.io/en/latest/install.html" target="_blank">here</a>.
If you have it:  
```shell
$  mkvirtualenv -p python3 instant-api
```

Instant Rest Api is built with falcon so it has to be installed.  
Install the dependencies:  
```shell
$ cd instant-api
$ pip install -r dependencies.txt
```

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**
```python

"""
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


```


Run the server:  
```shell
$ python
```

Great! It's running!  

Let's test the server (in another terminal window):  
```shell
$ curl http://localhost:8000
{"routes": ["/dog"]}
```

The root url gives us the possible routes.  
Let's list our dogs:  
```shell
$ curl http://localhost:8000/dog
{"message": null, "body": [], "status": "OK"}
```

We don't have any dogs yet, let's create some:
```shell
$ curl -X POST ht&#8203;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"}
```

So now our server has some dogs. let's list again and look at the results (indented for convenience):  
```shell
$ 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"
}
```

Looking good.  
We can also filter our results:  
```shell
$ 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"
}
```

Or get an object by id:  
```shell 
$ curl http://localhost:8000/dog?id=1
{
  "message": null,
  "body": {
    "age": 2,
    "breed": "jack russel",
    "id": "1",
    "name": "rocky",
    "color": "white"
  },
  "status": "OK"
}
```

You can also use sort, desc, limit and offset.   
If an object doesn't exist we'll get an error
```shell
$ curl http://localhost:8000/dog?id=999
{"message": "Object 999 not found", "body": {}, "status": "ERROR"}
```

Of course we can also update an object:  
```shell
$ 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"
}
```

And finally delete an object:  
```shell
$ curl -X DELETE http://127.0.0.1:8000/dog?id=3
{"message": "Deleted", "body": {}, "status": "OK"}
```



## 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:
```python
    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()
```

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:
```python
        view = ViewResource(resource_model)
        route = '/%s' % name.lower()
        app.add_route(route, view)
        routes.append(route)
```

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.