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

peace-performance (Rust) binding for python. To calculate star ratings and performance points for all osu! gamemodes

peace-performance-python Fast, To calculate star ratings and performance points for all osu! gamemodes peace-performance (Rust) binding for python bas

9 Sep 19, 2022
LOL英雄联盟云顶之弈挂机刷代币脚本,全自动操作,智能逻辑,功能齐全。

LOL云顶之弈挂机刷代币脚本 这是2019年全球总决赛写的一个云顶挂机脚本,python完成的。 功能: 自动拿牌卖牌 策略是高星策略,非固定阵容 自动登陆账号、打码、异常重启 战利品截图上传百度云 web中控发号,改密码,查看信息等 代码是三天赶出来的,所以有点混乱,WEB中控代码也不知道扔哪去了

77 Oct 10, 2022
Collaboration project to creating bank application maded by Anzhelica Sakun and Yuriy Konyukh

Collaboration project to creating bank application maded by Anzhelica Sakun and Yuriy Konyukh

Yuriy 1 Jan 08, 2022
An awesome list of AI for art and design - resources, and popular datasets and how we may apply computer vision tasks to art and design.

Awesome AI for Art & Design An awesome list of AI for art and design - resources, and popular datasets and how we may apply computer vision tasks to a

Margaret Maynard-Reid 20 Dec 21, 2022
Auto Join Zoom Meeting

Auto-Join-Zoom-Meeting Join a zoom meeting with out filling in meeting id's or passcodes, one button for it all! Setup See attached excel document. MA

JareBear 1 Jan 25, 2022
Proyecto - Análisis de texto de eventos históricos

Acceder al código desde Google Colab para poder ver de manera adecuada todas las visualizaciones y poder interactuar con ellas. Link de acceso: https:

1 Jan 31, 2022
A Python version of Canvacord

A copy of canvacord made in python! Installation Run any of these commands in terminal: Mac / Linux pip install canvacord Windows python -m pip insta

10 Mar 28, 2022
Plugins for Agisoft Metashape

Данные плагины предназначены для расширения функциональных возможностей Agisoft Metashape. Плагины представляют собой отдельные программы с собственным интерфейсом, которые запускаются внутри Agisoft

GeoScan 17 Dec 10, 2022
Custom Python code for calculating the Probability of Profit (POP) for options trading strategies using Monte Carlo Simulations.

Custom Python code for calculating the Probability of Profit (POP) for options trading strategies using Monte Carlo Simulations.

35 Nov 22, 2022
Script to use SysWhispers2 direct system calls from Cobalt Strike BOFs

SysWhispers2BOF Script to use SysWhispers2 direct system calls from Cobalt Strike BOFs. Introduction This script was initially created to fix specific

FalconForce 101 Dec 20, 2022
Prop-based map editor for the Apex Legends mod, R5Reloaded

R5R Map Editor A tool to build maps out of props in the Apex Legends mod, R5Reloaded Instuctions Install R5R Download this program Get the prop spawne

7 Dec 16, 2022
Minimal, super readable string pattern matching for python.

simplematch Minimal, super readable string pattern matching for python. import simplematch simplematch.match("He* {planet}!", "Hello World!") {"p

Thomas Feldmann 147 Dec 01, 2022
FollowSpot is a comprehensive audition tracking fullstack web application for entertainment industry professionals.

FollowSpot is a comprehensive audition tracking fullstack web application for entertainment industry professionals. This app allows users to store information/media for all of their auditions while a

Jen Brissman 9 Jul 12, 2022
A frontend to ease the use of pulseaudio's routing capabilities, mimicking voicemeeter's workflow

Pulsemeeter A frontend to ease the use of pulseaudio's routing capabilities, mimicking voicemeeter's workflow Features Create virtual inputs and outpu

Gabriel Carneiro 164 Jan 04, 2023
The FLARE team's open-source library to disassemble Common Intermediate Language (CIL) instructions.

dncil is a Common Intermediate Language (CIL) disassembly library written in Python that supports parsing the header, instructions, and exception hand

MANDIANT 95 Jan 08, 2023
Never get kicked for inactivity ever again!

FFXIV AFK Bot Tired of getting kicked from games due to inactivity? This Bot will make random movements in random intervals to prevent you from gettin

5 Jan 12, 2022
Automatically give thanks to Pypi packages you use in your project!

Automatically give thanks to Pypi packages you use in your project!

Ward 25 Dec 20, 2021
ViberExport - Export messages from Viber messenger using viber.db file

📲 ViberExport Export messages from Viber messenger using viber.db file ⚡ Usage:

7 Nov 23, 2022
Anonfiles files leaker via keyword.

Anonfiles files leaker via keyword

Trac3D1y 6 Nov 23, 2022
A minimal configuration for a dockerized kafka project.

Docker Kafka Quickstart A minimal configuration for a dockerized kafka project. Usage: Run this command to build kafka and zookeeper containers, and c

Nouamane Tazi 5 Jan 12, 2022