Skip to content

Commit

Permalink
2 new endpoints to post and get watchlist
Browse files Browse the repository at this point in the history
  • Loading branch information
fulder committed Nov 12, 2017
0 parents commit 7cbe38b
Show file tree
Hide file tree
Showing 22 changed files with 244 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# 4 space indentation
[*.py]
indent_style = space
indent_size = 4
insert_final_newline = true
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea/
*.pyc
config.json
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added
- `/movies` route
- First version of swagger docs.
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM python:2.7

ADD . "/usr/local/src"
WORKDIR "/usr/local/src"

EXPOSE 5000

RUN ["pip", "install", "-r", "requirements.txt"]
CMD ["python", "run_flask.py"]
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Pre requirements

* python2.7
* pip install -r requirements.txt

# Start server

* python run_flask.py
* API base URL: `http://localhost:5000/`

# API docs

For api docs go to http://localhost:5000/apidocs

# Running in docker

* docker build -t movie-service:1.0 .
* docker run -p 5000:5000 -d -t movie-service:1.0

9 changes: 9 additions & 0 deletions config_example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"api": {
"tmdb": {
"key": "<KEY>",
"user_token": "<TOKEN>",
"base_url": "https://api.themoviedb.org/3"
}
}
}
Empty file added domain/__init__.py
Empty file.
6 changes: 6 additions & 0 deletions domain/movie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

class Movie:

def __init__(self, movie_id, watch_date):
self.movie_id = movie_id
self.watch_date = watch_date
15 changes: 15 additions & 0 deletions domain/watch_histories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from domain.watch_history import WatchHistory


class WatchHistories:

def __init__(self):
self.watch_histories = {}

def get_watch_history(self, user_id):
if user_id not in self.watch_histories:
self.watch_histories[user_id] = WatchHistory(user_id)

return self.watch_histories[user_id]


17 changes: 17 additions & 0 deletions domain/watch_history.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import json
import time


from domain.movie import Movie


class WatchHistory:

def __init__(self, user_id):
self.user_id = user_id
self.movies = {}

def add_movie(self, movie_id):
self.movies[movie_id] = Movie(movie_id, int(time.time()))


4 changes: 4 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
flask
requests
flasgger
flask-cors
7 changes: 7 additions & 0 deletions run_flask.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import os

from subprocess import Popen

os.environ["FLASK_APP"] = "service/server.py"
flask_ps = Popen(["flask", "run", "--host=0.0.0.0"])
flask_ps.communicate()
Empty file added service/__init__.py
Empty file.
Empty file added service/dto/__init__.py
Empty file.
5 changes: 5 additions & 0 deletions service/dto/movie_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class MovieDto:

@staticmethod
def create(movie):
return {"movie_id": movie.movie_id, "watch_date": movie.watch_date}
9 changes: 9 additions & 0 deletions service/dto/watch_history_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from service.dto.movie_dto import MovieDto


class WatchHistoryDto:
@staticmethod
def create(watch_history):
return list(map(
lambda movie_id: MovieDto().create(watch_history.movies[movie_id]),
watch_history.movies))
39 changes: 39 additions & 0 deletions service/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from flasgger import swag_from, Swagger
from flask import Flask, request, Response, jsonify
from flask_cors import CORS

from domain.watch_histories import WatchHistories
from service.dto.watch_history_dto import WatchHistoryDto
from utils.log import Log

app = Flask(__name__)
cors = CORS(app, resources={r"/*": {"origins": "*"}})
Swagger(app, template_file='swagger/template.yml')

watch_histories = WatchHistories()

log = Log().get_logger(__name__)


@app.route("/watch-history", methods=["post"])
@swag_from("swagger/movie.yml")
def add_movie():
user_id = 1
data = request.get_json(silent=True)
movie_id = data["movie_id"]

watch_history = watch_histories.get_watch_history(user_id)
watch_history.add_movie(movie_id)
log.debug("Added movie: {} for user: {}".format(movie_id, user_id))
return Response(status=200, mimetype='application/json')


@app.route("/watch-history", methods=["get"])
@swag_from("swagger/movie.yml")
def get_watch_history():
user_id = 1
watch_history = watch_histories.get_watch_history(user_id)

data = WatchHistoryDto().create(watch_history)

return jsonify(data)
14 changes: 14 additions & 0 deletions service/swagger/movies.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Search for movies
---
tags:
- Movies
parameters:
- in: query
type: string
name: search
description: movie title to search for
responses:
200:
description: A list of movies
schema:
$ref: '#/definitions/Movies'
28 changes: 28 additions & 0 deletions service/swagger/template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
basePath: "/"
definitions:
Movie:
properties:
id:
type: integer
title:
type: string
Movies:
properties:
page:
type: integer
results:
type: array
items:
$ref: '#/definitions/Movie'
info:
description: Serving routes for movie operations
termsOfService: "/tos"
title: Movio movie service api
version: 0.0.1
contact:
responsibleOrganization: "Michal Sadowski"
responsibleDeveloper: "Michal Sadowski"
email: "[email protected]"
url: "test"
swagger: '2.0'
Empty file added utils/__init__.py
Empty file.
20 changes: 20 additions & 0 deletions utils/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import json
import os

from utils.log import Log

log = Log().get_logger(__name__)


class Config(object):
def __init__(self):
self.config_path = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"..", "config.json")
self._read_config()
log.debug(self.cfg)

def _read_config(self):
log.debug("Reading config from: {}".format(self.config_path))
with open(self.config_path) as config_file:
self.cfg = json.load(config_file)
24 changes: 24 additions & 0 deletions utils/log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import logging
import sys


class Log(object):

@staticmethod
def get_logger(name):
log = logging.getLogger(name)
Log()._format_logger(log)
log.propagate = False
return log

@staticmethod
def _format_logger(log, level=logging.DEBUG):
log.setLevel(level)
# log format
log_format = logging.Formatter(
"%(asctime)s - %(name)s - %(levelname)s - %(message)s")

# log handler
ch = logging.StreamHandler(sys.stdout)
ch.setFormatter(log_format)
log.addHandler(ch)

0 comments on commit 7cbe38b

Please sign in to comment.