Repo to store back end infrastructure for Message in a Bottle

Overview


Message in a Bottle Backend API

RESTful API for Message in a Bottle frontend application consumption.

contributors_badge forks_badge stars_badge issues_badge

About The ProjectTools UsedLocal Set UpInstallationHow To UseDatabase SchemaContributingAcknowledgements

About The Project

Message in a Bottle is an application where users can discover stories about the communities around them. This app was designed as a way to interact with cities, neighborhoods, and the people that inhabit them. The Message in a Bottle backend is built with a Django framework that stores story and user data through PostgreSQL. We expose this data to our frontend team to build out the user interface.

Learning Goals

  • Building a RESTful API with a Python Django backend
  • Collaborating with a Front-End dev team
  • Geolocation calls and tracking
  • Applying best practices learned during Turing to a new language and framework
    • e.g. TDD, OOP, REST, MVC(Rails) <--> MTV(Django)
  • Making use of the git rebase workflow

Tools Used

Development Testing Packages
Python 3.9.7 Pytest-Django Django
Django Pytest-Cov Django CORS Headers
CircleCI Postman Django Heroku
PostgreSQL VCRPY Django REST Framework
Git/Github Gunicorn
Heroku Psycopg2
Pycodestyle
Python-Decouple
Python-DotENV
Requests

Local Set Up

  1. To clone and run this application, you'll need Python 3.9.7 and Django 3.2.8. Using the official Python docs, follow instructions to install python3 for your local OS.

  2. You can check for a successful installation using this command:

$ python3 -V
> Python 3.9.7

Installation

  1. Fork this repo
  2. Clone your new repo:
git clone https://github.com/MIBFB-COLLAB/message_in_a_bottle_backend.git
  1. Create and Invoke your virtual environment:
python3 -m virtualenv venv
source venv/bin/activate
  1. Install dependencies:
(venv) python -m pip install -r requirements.txt
  1. Set up the database:
$ psql

CREATE DATABASE <project name>;
CREATE USER <user name> WITH PASSWORD <password>;
ALTER ROLE <user name> SET client_encoding TO 'utf8';
ALTER ROLE <user name> SET default_transaction_isolation TO 'read committed';
ALTER ROLE <user name> SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE <project name> TO <user name>;
\q
  1. Add PostgreSQL database info to settings.py file:
DATABASES = {
  'default': {
      'ENGINE': 'django.db.backends.postgresql_psycopg2',
      'NAME': '
   
    '
   ,
      'USER': '
   
    '
   ,
      'PASSWORD': '
   
    '
   ,
      'HOST': '
   
    '
   ,
      'PORT': '
   
    '
   ,
  }
}
  1. Migrate database:
(venv) python manage.py makemigrations
(venv) python manage.py migrate
  1. Update CORS allowed origins in settings.py. Domains currently allowed are:
CORS_ALLOWED_ORIGINS = [
  'http://localhost:3000',
  'https://message-in-a-bottle-fe-app.herokuapp.com',
  'https://app-message-in-a-bottle.herokuapp.com',
]
  1. Run the test suite with:
(venv) export DJANGO_SETTINGS_MODULE=message_in_a_bottle.settings
(venv) pytest --cov
  1. Run your local Python server with:
(venv) python manage.py runserver

How To Use

To experience the front-end UI, please visit the application here. You can also hit our endpoints through an API client, such as Postman or HTTPie.

Endpoint Documentation

Domain: https://message-in-a-bottle-api.herokuapp.com

Stories Index Endpoint
The GET stories endpoint retrieves stories near you. You must supply valid longitude and latitude coordinates.

Query Params Required? Example Notes
latitude Yes /api/v1/stories?latitude=12.345&longitude=4.5968 requires longitude
longitude Yes /api/v1/stories?latitude=12.345&longitude=4.5968 requires latitude

Request: GET /api/v1/stories?latitude=12.3456&longitude=4.5968

Response:

{
  "data": {
    "input_location": "phoenix,az",
    "stories":[
      {
      "id": 1,
      "type": "story",
      "attributes": {
        "title": "my cool story",
        "latitude": 13.201,
        "longitude": 9.2673,
        "distance_in_miles": 1.2,
        "created_at": "2021-10-27T03:45:34.165600Z",
        "updated_at": "2021-10-27T03:45:36.855162Z"
        }
      },
      {
      "id": 2,
      "type": "story",
      "attributes": {
        "title": "story",
        "latitude": 13.563,
        "longitude": 10.2673,
        "distance_in_miles": 3,
        "created_at": "2021-10-27T04:45:34.165600Z",
        "updated_at": "2021-10-27T04:45:36.855162Z"
        }
      }
    ]
  }
}

Story Show Endpoint
Request: GET /api/v1/stories/:id?latitude=12.3456&longitude=-4.5968

Response:

{
  "data": {
    "id": 1,
    "type": "story",
    "attributes": {
      "title": "my cool story",
      "message": "This one time I saw a bird",
      "name": "Anonymous",
      "created_at": "2021-10-08T23:28:51.897746Z",
      "updated_at": "2021-10-08T23:28:51.897746Z",
      "latitude": 30.071945143440377,,
      "longitude": 31.225164325479227,
      "distance_in_miles": 1.2,
      "location": "Cairo Governorate, EG"
      }
   }
}

Directions Endpoint
Request: GET /api/v1/stories/:id/directions?latitude=1230&longitude=1209.3

Response:

{
  "data": [
    {
      "id": null,
      "type": "directions",
      "attributes": {
        "narrative": "Turn left on Bob St.",
        "distance": ".8 miles"
      }
    },
    {
      "id": null,
      "type": "directions",
      "attributes": {
        "narrative": "Turn right on Starry Road",
        "distance": ".2 miles"
      }
    }
  ]
}

Create Story Endpoint
Request: POST /api/v1/stories

Request Body:

{
  "title": "A new title",
  "message": "I'm coming up",
  "latitude": 27.717311514603534,
  "longitude": 85.32098499247293
}

Response:

{
  "data": {
    "id": 2,
    "type": "story",
    "attributes": {
      "title": "A new title",
      "message": "I'm coming up",
      "name": "Anonymous",
      "created_at": "2021-10-08T23:28:51.897746Z",
      "updated_at": "2021-10-08T23:28:51.897746Z",
      "latitude": 27.717311514603534,
      "longitude": 85.32098499247293,
      "location": "Kathmandu, NP"
    }
  }
}

Update Story Endpoint
Request: PATCH /api/v1/stories/:id

Request Body:

{
  "title": "My Fixed Title",
  "message": "Hello World.",
  "name": "Sally"
}

Response:

{
  "data": {
    "id": 1,
    "type": "story",
    "attributes": {
      "title": "My Fixed Title",
      "message": "Hello World.",
      "name": "Sally",
      "created_at": "2021-10-08T23:28:51.897746Z",
      "updated_at": "2021-10-18T23:28:51.897746Z",
      "latitude": 40.3830,
      "longitude": 105.5190,
      "location": "Estes Park, CO"
    }
  }
}

Delete Story Endpoint
Request: DELETE /api/v1/stories/:id

Error Handling
Here are some examples of error messages you could receive if you send an invalid request:

Bad Request URI: GET /api/v1/stories/:id or /api/v1/stories/:id?latitude=&longitude=

Response:

{
    "errors": {
        "messages": [
            "Latitude or longitude can't be blank."
        ],
        "code": 1
    }
}

Bad Request URI: GET /api/v1/stories/:id?latitude=1000&longitude=1000

Response:

{
    "errors": {
        "messages": [
            "Invalid latitude or longitude."
        ],
        "code": 1
    }
}

Bad Request URI: GET /api/v1/stories/:id?latitude=0&longitude=0

Response:

{
    "errors": {
        "messages": [
            "Impossible route."
        ],
        "code": 2
    }
}

POST /api/v1/stories Bad Request Body:

{
    "title":"Here's Johnny!",
    "message": "allworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboyallworkandnoplaymakesjackadullboy",
    "name":"Jack Torrance",
    "latitude":40.3830,
    "longitude":105.5190
}

Response:

{
    "errors": {
        "message": [
            "Ensure this field has no more than 1000 characters."
        ],
        "location": [
            "This field may not be blank."
        ]
    }
}

Database Schema

Screen Shot 2021-10-27 at 17 33 14

Contributing

👤 Marla Schulz

👤 Taylor Varoglu

👤 Matt Kragen

👤 Mae Duphorne

👤 Fara Akhatova

👤 Justin Anthony

Acknowledgements

A command line interface tool converting starknet warp transpiled outputs into readable cairo contracts.

warp-to-cairo warp-to-cairo is a simple tool converting starknet warp outputs (NethermindEth/warp) outputs into readable cairo contracts. The warp out

Michael K 5 Jun 10, 2022
Shell scripts made simple 🐚

zxpy Shell scripts made simple 🐚 Inspired by Google's zx, but made much simpler and more accessible using Python. Rationale Bash is cool, and it's ex

Tushar Sadhwani 492 Dec 27, 2022
Context-free grammar to Sublime-syntax file

Generate a sublime-syntax file from a non-left-recursive, follow-determined, context-free grammar

Haggai Nuchi 8 Nov 17, 2022
Telegram bot to upload media to telegra.ph

Telegraph @StarkTelegraphBot A star ⭐ from you means a lot to us ! Telegram bot to upload media to telegra.ph Usage Deploy to Heroku Tap on above butt

Stark Bots 24 Dec 29, 2022
Insights in greek football league 2020-2021 and bookmaker's accuracy

Greek_Football_League_Analysis_2020_2021 Aim of Project: This project aims in deriving useful insights from greek football league 2020-2021 by mean st

2 Jan 16, 2022
Python implementation of the Lox language from Robert Nystrom's Crafting Interpreters

pylox Python implementation of the Lox language from Robert Nystrom's Crafting Interpreters. https://craftinginterpreters.com. This only implements th

David Beazley 37 Dec 28, 2022
Enjoy Discords Unlimited Storage

Discord Storage V.3.5 (Beta) Made by BoKa Enjoy Discords free and unlimited storage... Prepare: Clone this from Github, make sure there either a folde

0 Dec 16, 2021
A python program to detect rickrolls with just the youtube link.

rickroll_detector A python program to detect rickrolls with just the youtube link. Usage: clone this repo or download zip run the main.py file with py

Tricky 4 Nov 06, 2022
Blender addon that simplifies access to useful operators and adds missing functionality

Quick Menu is a Blender addon that simplifies common tasks Compatible with Blender 3.x.x Install through Edit - Preferences - Addons - Install... -

passivestar 94 Dec 27, 2022
Density is a open-sourced multi-purpose tool for ROBLOX with some cool

Density is a open-sourced multi-purpose tool for ROBLOX with some cool

ssl 5 Jul 16, 2022
List Less Than Ten with python

List Less Than Ten with python

PyLaboratory 0 Feb 07, 2022
A country information finder module

A country information finder module

Fayas Noushad 3 Nov 28, 2021
IST-Website - IST Tutoring Portal for python

IST Tutoring Portal This portal is a web based interface to handle student help

Jean 3 Jan 03, 2022
A pet facts python api

Pet-Facts-API A pet facts python api Project Links API :- https://pet-facts-api.vercel.app Docs :- https://fayasnoushad.github.io/Pet-Facts-API

Fayas Noushad 3 Dec 18, 2021
Python script for converting obsidian md-file to html (recursively adds all link/images)

ObsidianToHtmlConverter I made a small python script for converting obsidian md-file to static (local) html (recursively adds all link/images) I made

47 Jan 03, 2023
A Lego Mindstorm robot for dealing out cards based on a birds-eye view of a poker table and given ArUco fiducial tags.

A Lego Mindstorm robot for dealing out cards based on a birds-eye view of a poker table and given ArUco fiducial tags.

4 Dec 06, 2021
👀 nothing to see here

Woofy Woofy is blue dog companion token of YFI (Wifey) It utilizes a special Woof bonding curve which allows two-way conversion between the tokens. Th

Yearn Finance 36 Mar 14, 2022
Medical appointments No-Show classifier

Medical Appointments No-shows Why do 20% of patients miss their scheduled appointments? A person makes a doctor appointment, receives all the instruct

4 Apr 20, 2022
Addon for Blender 2.8+ that automatically creates NLA tracks for all animations. Useful for GLTF export.

PushDownAll An addon for Blender 2.8+ that runs Push Down on all animations, creating NLA tracks for each. This is useful if you have an object with m

Cory Petkovsek 16 Oct 06, 2022
An example of Connecting a MySQL Database with Python Code

An example of Connecting And Query Data a MySQL Database with Python Code And How to install Table of contents General info Technologies Setup General

Mohammad Hosseinzadeh 1 Nov 23, 2021