NAV

Breaking Bad API

The idea was to create a simple platform for DEA agents, to manage information about characters from the Breaking Bad/Better Call Saul universe. To make the DEA agents' life easier, they need to have an API endpoint that allows filtering information about characters by their name, date of birth, occupation or the fact whether they are a suspect.

As the DEA is trying to put drug lords behind bars, they are tracking their, and the people around them location. They store timestamps and particular locations as geographical coordinates in a related table. The endpoint that will expose the data needs to allow filtering of location entries, that were within a specific distance from a particular geographical point, as well as who they were assigned to, and the datetime range of when they were recorded. The ordering for this endpoint should allow taking into consideration distance from a specified geopraphical point, both ascending and descending.

Setting up the project

Example request

import requests
import json

url = 'http://localhost:8000/api/characters/'

headers = {'Content-Type' : "application/json"}

response = requests.get(url, headers=headers, verify=False)

if response.status_code == 200:
    data = response.json()
    print(json.dumps(data, indent=2))
else:
    print("Request failed with status code:", response.status_code)

As prerequisites you will need to have Docker and docker-compose installed on your system.

At first, go to your project's folder and clone the Breaking Bad API repository:

git clone git@github.com:drangovski/breaking-bad-api.git

cd breaking-bad-api

Then you will need to create and .env file where you will put the values for the following variables:

POSTGRES_USER=heisenberg
POSTGRES_PASSWORD=iamthedanger
POSTGRES_DB=breakingbad
DEBUG=True
SECRET_KEY=""
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
SQL_ENGINE=django.db.backends.postgresql
SQL_DATABASE=breakingbad
SQL_USER=heisenberg
SQL_PASSWORD=iamthedanger
SQL_HOST=db
SQL_PORT=5432

Once you have this set, you can run:

docker-compose build

docker-compose up

This will start the django application at localhost:8000. To access the api, the url will be localhost:8000/api.

Mock Locations

For the sake of the theme of these projects (and eventually, to make your life a bit easier :)), you can eventually use the following locations and their coordinates:

Location Longitude Latitude
Los Pollos Hermanos 35.06534619552971 -106.64463423464572
Walter White House 35.12625330483283 -106.53566597939896
Saul Goodman Office 35.12958969793146 -106.53106126774908
Mike Ehrmantraut House 35.08486667169461 -106.64115047513016
Jessie Pinkman House 35.078341181544396 -106.62404891988452
Hank & Marrie House 35.13512843853582 -106.48159991250327

Characters

Retrieve all characters

To retrieves all existing characters in the database.

GET /api/characters/

Example response


[
    {
        "id": 1,
        "name": "Walter White",
        "occupation": "Chemistry Professor",
        "date_of_birth": "1971",
        "suspect": false
    },
    {
        "id": 2,
        "name": "Tuco Salamanca",
        "occupation": "Grandpa Keeper",
        "date_of_birth": "1976",
        "suspect": true
    }
]

Retrieve a single character

To retrieve a single character, pass the character's ID to the enpoint.

GET /api/characters/{id}

Create a new character

You can use the POST method to to /characters/ endpoint in order to create a new character.

POST /api/characters/

Creation parameters

You will need to pass the following parameters in the query, in order to successfully create a character:

{
    "name": "string",
    "occupation": "string",
    "date_of_birth": "string",
    "suspect": boolean
}
Parameter Description
name String value for the name of the character.
occupation String value for the occupation of the character.
date_of_birth String value for the date of brith.
suspect Boolean parameter. True if suspect, False if not.

Character ordering

Ordering of the characters can be done by two fields as a parameters: name and date_of_birth

GET /api/characters/?ordering={name / date_of_birth}

Parameter Description
name Order the results by the name field.
date_of_birth Order the results by the date_of_birth field.

Additionally, you can add the parameter ascending with value 1 or 0 to order the results in ascending or descending order.

GET /api/characters/?ordering={name / date_of_birth}&ascending={1 / 0}

Parameter Description
&ascending=1 Order the results in ascending order by passing 1 as a value.
&ascending=0 Order the results in descending order by passing 0 as a value.

Character filtering

To filter the characters, you can use the parameters in the table below. Case insensitive.

GET /api/characters/?name={text}

Parameter Description
/?name={text} Filter the results by name. It can be any length and case insensitive.
/?occupaton={text} Filter the results by occupation. It can be any length and case insensitive.
/?suspect={True / False} Filter the results by suspect status. It can be True or False.

You can also use search parameter in the query in order to search characters and retrieve results based on the fields listed below.

GET /api/characters/?search={text}

Update a character

To update a character, you will need to pass the {id} of a character to the url and make a PUT method request with the parameters in the table below.

PUT /api/characters/{id}

Example body

{
    "name": "Mike Ehrmantraut",
    "occupation": "Retired Officer",
    "date_of_birth": "1945",
    "suspect": false
}
Parameter Description
name String value for the name of the character.
occupation String value for the occupation of the character.
date_of_birth String value for the date of brith.
suspect Boolean parameter. True if suspect, False if not.

Delete a character

To delete a character, you will need to pass the {id} of a character to the url and make DELETE method request.

DELETE /api/characters/{id}

Locations

Retrieve all locations

To retrieves all existing locations in the database.

GET /api/locations/

Example response


[
    {
        "id": 1,
        "name": "Los Pollos Hermanos",
        "longitude": 35.065442792232716,
        "latitude": -106.6444840309555,
        "created": "2023-02-09T22:04:32.441106Z",
        "character": {
            "id": 2,
            "name": "Tuco Salamanca",
            "details": "http://localhost:8000/api/characters/2"
        }
    },
]

Retrieve a single location

To retrieve a single location, pass the locations's ID to the enpoint.

GET /api/locations/{id}

Create a new location

You can use the POST method to to /locations/ endpoint in order to create a new location.

POST /api/locations/

Creation parameters

You will need to pass the following parameters in the query, in order to successfully create a location:

{
    "name": "string",
    "longitude": float,
    "latitude": float,
    "character": integer
}
Parameter Description
name The name of the location.
longitude Longitude of the location.
latitude Latitude of the location.
character This is the id of a character. It is basically ForeignKey relation to the Character model.

Location ordering

Ordering of the locations can be done by providing the parameters for the longitude and latitude coordinates for a single point, and a radius (in meters). This will return all of the locatons stored in the database, that are in the provided radius from the provided point (coordinates).

GET /api/locations/?longitude={longitude}&latitude={latitude}&radius={radius}

Parameter Description
longitude The longitude parameter of the radius point.
latitude The latitude parameter of the radius point.
radius The radius parameter (in meters).

Additionally, you can add the parameter ascending with value 1 or 0 to order the results in ascending or descending order.

GET /api/locations/?longitude={longitude}&latitude={latitude}&radius={radius}&ascending={1 / 0}

Parameter Description
&ascending=1 Order the results in ascending order by passing 1 as a value.
&ascending=0 Order the results in descending order by passing 0 as a value.

Locaton filtering

To filter the locations, you can use the parameters in the table below. Case insensitive.

GET /api/locations/?character={text}

Parameter Description
/?name={text} Filter the results by location name. It can be any length and case insensitive.
/?character={text} Filter the results by character. It can be any length and case insensitive.
/?created={timeframe} Filter the results by when they were created. Options: today, yesterday, week, month & year.

Update a location

To update a location, you will need to pass the {id} of a locations to the url and make a PUT method request with the parameters in the table below.

PUT /api/locations/{id}

Example body

{
    "id": 1,
    "name": "Los Pollos Hermanos",
    "longitude": 35.065442792232716,
    "latitude": -106.6444840309555,
    "created": "2023-02-09T22:04:32.441106Z",
    "character": {
        "id": 2,
        "name": "Tuco Salamanca",
        "occupation": "Grandpa Keeper",
        "date_of_birth": "1975",
        "suspect": true
    }
}
Parameter Description
name String value for the name of the location.
longitude Float value for the longitude of the location.
latitude Float value for the latitude of the location.

Delete a location

To delete a location, you will need to pass the {id} of a location to the url and make DELETE method request.

DELETE /api/locations/{id}