-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
127 lines (102 loc) · 9.98 KB
/
app.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
"""
An application with API endpoints to perform Create, Retrieve, Update, and Delete operations on the above data using a Flask server.
Your application should allow you to add a product, retrieve the products, retrieve a specific product with its id, update a specific product with its id, and delete a product with its id.
All these operations will be achieved through the REST API endpoints in your Flask server.
"""
from flask import Flask # import the Flask class from the flask module
from flask import request # import the request class from the flask module for handling and making HTTP requests
from flask import jsonify # import the jsonify class from the flask module for converting a Python dictionary or list into JSON format
from flask_cors import CORS # import the CORS class from the flask_cors module, this allows cross origin resource sharing which allows for use of your api by other domains
# CORS is a Flask extension for handling Cross Origin Resource Sharing (CORS), making cross-origin AJAX possible. It is a way to relax the same-origin policy, which is a set of restrictions imposed by browsers to prevent interactions between resources from different origins.
# you can configure CORS options to specify allowed origins, headers, and other settings according to your requirements.
app = Flask(__name__) # creates an instance of the Flask class called "app", this allows Flask to find the location and root path of the application's resources, such as templates and static files.
# __name__ is the name of the current Python module. The app needs to know where it's located to set up some paths, and __name__ is a convenient way to tell it that.
# you can also use the specific name of the file, but using __name__ is better because it's more reliable and just points to whatever module is currently being used as the entry point (so it won't break if you change the file name).
# The app variable is an instance of Flask, so you can use it like any other Python object. The Flask class has a constructor that takes the name of the current module (__name__) as argument.
CORS(app) # use the CORS class to pass in the app variable, this allows cross origin resource sharing which allows for use of your api by other domains
products = [
{'id': 1, 'name': 'Sedan', 'price': 1644000.00}, # 20000 * 82
{'id': 2, 'name': 'SUV', 'price': 2870000.00}, # 35000 * 82
{'id': 3, 'name': 'Pickup Truck', 'price': 2296000.00}, # 28000 * 82
{'id': 4, 'name': 'Coupe', 'price': 2050000.00}, # 25000 * 82
{'id': 5, 'name': 'Convertible', 'price': 3690000.00}, # 45000 * 82
{'id': 6, 'name': 'Minivan', 'price': 2460000.00}, # 30000 * 82
{'id': 7, 'name': 'Hatchback', 'price': 1476000.00}, # 18000 * 82
{'id': 8, 'name': 'Wagon', 'price': 1896000.00}, # 23000 * 82
{'id': 9, 'name': 'Motorcycle', 'price': 820000.00}, # 10000 * 82
{'id': 10, 'name': 'Electric Car', 'price': 3280000.00} # 40000 * 82
]
# REST API endpoints: (The REST API endpoints are the URLs that your application will expose to the outside world. These URLs will be used to perform CRUD operations on your data.)
# Create a product: POST /products
# Retrieve all products: GET /products
# Retrieve a specific product: GET /products/<id>
# Update a specific product: PUT /products/<id>
# Delete a product: DELETE /products/<id>
# Retrieve all products: GET /products. This endpoint should return a JSON representation of all the products in the products list. Example request - http://localhost:5000/products
@app.route('/products', methods=['GET'], strict_slashes=False) # strict_slashes=False allows for both '/products' and '/products/' to return the same thing and methods=['GET'] specifies that this endpoint will only accept GET requests
def get_products():
"""returns all products"""
return jsonify(products)
# Retrieve a specific product: GET /products/<id>. This endpoint should return a JSON representation of the product with the given id. Example request - http://localhost:5000/products/143
@app.route('/products/<int:id>', methods=['GET'], strict_slashes=False) # strict_slashes=False allows for both '/products/<int:id>' and '/products/<int:id>/' to return the same thing and methods=['GET'] specifies that this endpoint will only accept GET requests
def get_product(id):
"""returns a specific product"""
for product in products:
if product['id'] == id: # if the product id matches the id passed in, return the product as JSON
return jsonify(product) # return the product as JSON
return jsonify({'error': 'Product not found'}), 404 # return an error if the product is not found
# Create a product: POST /products. This endpoint should create a new product in the products list. The request body should contain the name and price of the product. Example request - http://localhost:5000/products
@app.route('/products', methods=['POST'], strict_slashes=False) # strict_slashes=False allows for both '/products' and '/products/' to return the same thing and methods=['POST'] specifies that this endpoint will only accept POST requests
def create_product():
"""creates a new product"""
product = request.get_json() # get the request body as JSON
if not product:
return jsonify({'error': 'Product not found'}), 400 # return an error if the request body is not JSON
if 'name' not in product:
return jsonify({'error': 'Missing name'}), 400 # return an error if the request body does not contain a name
if 'price' not in product:
return jsonify({'error': 'Missing price'}), 400 # return an error if the request body does not contain a price
if 'id' not in product:
product['id'] = len(products) + 1 # add an id to the new product if it is not already in the request body
products.append(product) # add the new product to the products list
return jsonify(product), 201 # return the new product as JSON with a 201 status code (201 = created)
# Update a specific product: PUT /products/<id>. This endpoint should update the product with the given id in the products list. The request body should contain the name and price of the product. Example request - http://localhost:5000/products/143
@app.route('/products/<int:id>', methods=['PUT'], strict_slashes=False) # strict_slashes=False allows for both '/products/<int:id>' and '/products/<int:id>/' to return the same thing and methods=['PUT'] specifies that this endpoint will only accept PUT requests
def update_product(id):
id = int(id) # convert the id to an integer
updated_product = request.get_json() # get the request body as JSON
for product in products:
if product['id'] == id:
for key, value in updated_product.items():
product[key] = value
return jsonify(product), 200 # return the updated product as JSON with a 200 status code (200 = OK)
return jsonify({'error': 'Product not found'}), 404 # return an error if the product is not found
# Delete a product: DELETE /products/<id>. This endpoint should delete the product with the given id from the products list. Example request - http://localhost:5000/products/143
@app.route('/products/<int:id>', methods=['DELETE'], strict_slashes=False) # strict_slashes=False allows for both '/products/<int:id>' and '/products/<int:id>/' to return the same thing and methods=['DELETE'] specifies that this endpoint will only accept DELETE requests
def delete_product(id):
id = int(id) # convert the id to an integer
for product in products:
if product['id'] == id:
products.remove(product)
return jsonify({'message': 'Product deleted'}), 200 # return a message that the product was deleted with a 200 status code (200 = OK)
return jsonify({'error': 'Product not found'}), 404 # return an error if the product is not found
if __name__ == '__main__': # if the script is executed directly, the code block is executed, if the script is imported, the code block is not executed.
app.run(host='0.0.0.0', port='3000', debug = True) #specify the url and port, and debug = True allows for the server to automatically reload when changes are made to the code
# on terminal enter = 'export FLASK_APP=0-hello_route.py' to set the file to be run as the flask app
# on terminal enter = 'flask run' to run the flask app
# or enter = 'python3 <filename>' to run the file directly
# The method should be restarted manually for any change in the code. To overcome this, the debug support is enabled so as to track any error.
# To test the endpoints, you can use Postman, a popular tool for testing REST APIs. You can also use curl, a command line tool for making HTTP requests.
# To test the GET /products endpoint, you can use the following curl command: curl http://localhost:5070/products
# To test the GET /products/<id> endpoint, you can use the following curl command: curl http://localhost:5070/products/143
# To test the POST /products endpoint, you can use the following curl command:
# curl -X POST -H "Content-Type: application/json" -d '{"name": "Pencil", "price": 1.99}' http://localhost:5070/products (x = specify the request method, H = specify the request header, d = specify the request body)
# To test the PUT /products/<id> endpoint, you can use the following curl command:
# curl -X PUT -H "Content-Type: application/json" -d '{"name": "Pencil", "price": 1.99}' http://localhost:5070/products/143 (x = specify the request method, H = specify the request header, d = specify the request body)
# To test the DELETE /products/<id> endpoint, you can use the following curl command: curl -X DELETE http://localhost:5070/products/143 (x = specify the request method)
"""
While the GET endpoints are easy to test with curl using a command line interface, the POST, PUT and DELETE commands can be cumbersome.
To circumvent this problem, you can use Postman, which is a software that is available as a service.
Postman is a software that allows you to test your APIs. It is available as a service, and also as a desktop application.
You can download the desktop application from https://www.getpostman.com/downloads/.
"""