简体   繁体   中英

Can someone help me with an error about my post request for my API in python?

So I have code that shows the information about certain cars. First I created a list about certain types of cars such as make, model, year, etc. I successfully created code that can show me all the data or a specific type of data using a URL. Here is my code:

import datetime
import time
from flask import Flask, request, jsonify, make_response, abort
import mysql.connector
from mysql.connector import Error
import myfunctions


# setting up an application name
app = Flask(__name__) #set up application
app.config["DEBUG"] = True #allow to show error message in browser

cars = [
    {'id': 0,
     'make': 'Jeep',
     'model': 'Grand Cherokee',
     'year': '2000',
     'color': 'black'},
    {'id': 1,
     'make': 'Ford',
     'model': 'Mustang',
     'year': '1970',
     'color': 'white'},
    {'id': 2,
     'make': 'Dodge',
     'model': 'Challenger',
     'year': '2020',
     'color': 'red'}
]


@app.route('/', methods=['GET'])  #routing = mapping urls to functions; home is usually mapped to '/'
def home():
    return "<h1>Hi and welcome to our first API!</h1>"

# A route to return all of the cars
@app.route('/api/cars/all', methods=['GET'])
def api_all():
    return jsonify(cars)

# A route to return a specific car by id e.g. http://127.0.0.1:5000/api/cars?id=1
@app.route('/api/cars', methods=['GET'])
def api_id():
    if 'id' in request.args: #check for id as part of the url, use it if it's there, throw error if it isn't
        id = int(request.args['id'])
    else:
        return "Error: No id provided."

    results = [] #the resulting car(s) we want to return

    for car in cars: #find the car(s) we're looking for by id
        if car['id'] == id:
            results.append(car)

    return jsonify(results)

And my output would be:

    [ { "color": "black", "id": 0, "make": "Jeep", "model": "Grand Cherokee", "year": "2000" },
     { "color": "white", "id": 1, "make": "Ford", "model": "Mustang", "year": "1970" }, 
    { "color": "red", "id": 2, "make": "Dodge", "model": "Challenger", "year": "2020" } ]

On the browser.

Now I want to add new information about a car using the post method so here is my code:

# Example to use POST as your method type, sending parameters as payload from POSTMAN (raw, JSON)
@app.route('/post-example', methods=['POST'])
def post_example():
    request_data = request.get_json()
    newid = request_data['id']
    newmake = request_data['make']
    newmodel = request_data['model']
    newyear = request_data['year']
    newcolor = request_data['color']
    cars.append({'id': newid, 'make': newmake, 'model': newmodel, 'year': newyear, 'color': newcolor}) #adding a new car to my car collection on the server.
    #IF I go check the /api/cars/all route in the browser now, I should see this car added to the returned JSON list of cars
    return 'POST REQUEST WORKED'

But when I run it, this pops up:

File "C:\Users\User\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 2450, in wsgi_app
    response = self.handle_exception(e)
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "D:\PYTHON\API\data_api3.py", line 81, in post_example
    newid = request_data['id']
TypeError: 'NoneType' object is not subscriptable
127.0.0.1 - - [06/Apr/2021 17:25:47] "GET /api/cars/all HTTP/1.1" 200 -

Can someone help me spot the error please

It is request.json which returns a dictionary of the JSON data. To get a value you use request.json.get('key_name') .

@app.route('/post-example', methods=['POST'])
def post_example():
    newid = request.json.get('id')
    newmake = request.json.get('make')
    newmodel = request.json.get('model')
    newyear = request.json.get('year')
    newcolor = request.json.get('color')
    cars.append({'id': newid, 'make': newmake, 'model': newmodel, 'year': newyear, 'color': newcolor}) #adding a new car to my car collection on the server.
    #IF I go check the /api/cars/all route in the browser now, I should see this car added to the returned JSON list of cars
    return 'POST REQUEST WORKED'

Instead of using

newid = request_data['id']

You should use

newid = request_data.get('id')

You should apply these changes to all dictionary keys.

@app.route('/post-example', methods=['POST'])
def post_example():
    request_data = request.get_json()
    newid = request_data.get('id')
    newmake = request_data.get('make')
    newmodel = request_data.get('model')
    newyear = request_data.get('year')
    newcolor = request_data.get('color')
    cars.append({
        'id': newid, 
        'make': newmake, 
        'model': newmodel,
        'year': newyear, 
        'color': newcolor
    })
    
    return 'POST REQUEST WORKED'

Shorter version:

@app.route('/post-example', methods=['POST'])
def post_example():
    request_data = request.get_json()
    cars.append(request_data)
    
    return 'POST REQUEST WORKED'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM