-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbooks_catalog_api.py
186 lines (160 loc) · 5.43 KB
/
books_catalog_api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
import logging
from flask import Flask, request, jsonify
from flasgger import Swagger, swag_from
from flask_cors import CORS
from util import get_sqlalchemy_session
from models import Author, Book
app = Flask(__name__)
swagger = Swagger(app)
#enable CORS for all routes in order to be possible to request from different origins in UI
#In PROD we should have the same origin for both API and UI to avoid enabling CORS
#it will add header Access-Control-Allow-Origin: * to each HTTP response
CORS(app)
@app.route('/books/')
@swag_from("swagger/get_all_books.yml")
def get_all_books():
"""
Return all books from database
"""
with get_sqlalchemy_session() as db:
query = db.query(Book).order_by("title")
books = []
for book in query:
books.append({
"book_id": book.book_id,
"title": book.title,
"description": book.description,
"author": book.author,
})
logging.info(f"GET all books: \n{books}")
return jsonify(books)
@app.route('/books/', methods=["POST"])
@swag_from("swagger/create_new_book.yml")
def create_new_book():
"""
Create new book in the database
"""
title = request.json.get("title")
description = request.json.get("description")
author_id = request.json.get("author_id")
if not title or not description or not author_id:
return jsonify({'error': 'Please provide title, description, author_id in the body'}), 400
with get_sqlalchemy_session() as db:
query = db.query(Author).filter_by(author_id=author_id)
author = query.first()
if not author:
return jsonify({'error': f'Author with id {author_id} not found'}), 404
book = Book(
title=title,
description=description,
author=author,
)
db.add(book)
db.commit()
logging.info(f"POST book: {book}")
return jsonify({
"book_id": book.book_id,
"title": book.title,
"description": book.description,
"author": book.author,
})
@app.route('/books/<book_id>', methods=["DELETE"])
@swag_from("swagger/delete_book.yml")
def delete_book(book_id):
"""
DELETE new book in the database
"""
with get_sqlalchemy_session() as db:
query = db.query(Book).filter_by(book_id=int(book_id))
book = query.first()
logging.info(f"DELETE book: {book}")
if not book:
return jsonify({'error': f'Book with id {book_id} not found'}), 404
db.delete(book);
db.commit();
return jsonify({
"book_id": book.book_id,
})
@app.route('/books/<book_id>')
@swag_from("swagger/get_book.yml")
def get_book(book_id):
"""
Return single book based on book id
"""
with get_sqlalchemy_session() as db:
query = db.query(Book).filter_by(book_id=int(book_id))
book = query.first()
logging.info(f"GET book: {book}")
if not book:
return jsonify({'error': f'Book with id {book_id} not found'}), 404
return jsonify({
"book_id": book.book_id,
"title": book.title,
"description": book.description,
"author": book.author,
})
@app.route('/authors/')
@swag_from("swagger/get_all_authors.yml")
def get_all_authors():
"""
Return all authors from database
"""
with get_sqlalchemy_session() as db:
query = db.query(Author).order_by("last_name")
authors = []
for author in query:
authors.append({
"author_id": author.author_id,
"first_name": author.first_name,
"last_name": author.last_name,
})
logging.info(f"GET all authors: \n{authors}")
return jsonify(authors)
@app.route('/authors/', methods=["POST"])
@swag_from("swagger/create_new_author.yml")
def create_new_author():
"""
Create new author in the database
"""
first_name = request.json.get("first_name")
last_name = request.json.get("last_name")
if not first_name or not last_name:
return jsonify({'error': 'Please provide first_name and last_name in the body'}), 400
with get_sqlalchemy_session() as db:
author = Author(first_name=first_name, last_name=last_name)
db.add(author)
db.commit()
logging.info(f"POST author: {author}")
return jsonify({
"author_id": author.author_id,
"first_name": author.first_name,
"last_name": author.last_name,
})
@app.route('/authors/<author_id>')
@swag_from("swagger/get_author.yml")
def get_author(author_id):
"""
Return single author based on author id
"""
with get_sqlalchemy_session() as db:
query = db.query(Author).filter_by(author_id=int(author_id))
author = query.first()
logging.info(f"GET author: {author}")
if not author:
return jsonify({'error': f'Author with id {author_id} not found'}), 404
return jsonify({
"author_id": author.author_id,
"first_name": author.first_name,
"last_name": author.last_name,
})
@app.route('/')
def route():
with get_sqlalchemy_session() as db:
logging.info("Keeping db connection open...")
return {}
# We only need this for local development.
if __name__ == '__main__':
app.run()