Home > front end >  405: Method Not Allowed. Why am I getting this error in Flask
405: Method Not Allowed. Why am I getting this error in Flask

Time:03-22

I tried all posiible ways and read many posts in SO. I haven't got any solution for my "method not allowed" error. Can anyone check and let me know what did I do wrong? I am getting frustrated cause I am new to flask and I cannot proceed further.

This is my template file add_cars.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Datastore and Firebase Auth Example</title>
    <script src="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth.js"></script>
    <link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth.css" />
    <script src="{{ url_for('static', filename='script.js') }}"></script>
    <link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
    <link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='navstyle.css') }}">
</head>
    <body>
    <div >
        <a  href="{{ url_for('root') }}">Home</a>
        <a href="{{ url_for('list_ev') }}">EV List</a>
        <a href="#contact">Contact</a>
        <a href="#about">About</a>
    </div>
    <h2>Add car details</h2>
    <div id="firebase-auth-container"></div>
    {% if user_data %}
    <p align="right">Email: {{ user_data['email'] }}</p>
    <button id="sign-out" hidden="true" style="float: right;">Sign out</button>
    <div id="login-info" hidden="true">
        <form action="/add_cars" method="post">
            Car name:<input type="text" value="" name="name_update"/><br/>
            Manufacturer:<input type="text" value="" name="manufacturer_update"/><br/>
            Year:<input type="number" value="" name="year_update"/><br/>
            Battery size:<input type="number" value="0.0" name="battery_update" step="any"/><br/>
            Range:<input type="number" value="" name="range_update"/><br/>
            Cost:<input type="number" value="" name="cost_update"/><br/>
            Power:<input type="number" value="" name="power_update" step="any"/><br/><br>
            <input type="submit"  value="Add details" name="submit_button"/>
        </form>
        {% elif error_message %}
        <p>Error Message: {{ error_message }}</p>
    {% endif %}
    </div>
    <br>
<!--    <div>-->
<!--        <a href="{{ url_for('list_ev') }}" >View all cars</a>-->
<!--    </div>-->

    <script src="https://www.gstatic.com/firebasejs/7.14.5/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/7.8.0/firebase-auth.js"></script>
    <script src="{{ url_for('static', filename='app-setup.js') }}"></script>

</body>
</html>

This is my main.py

from flask import Flask, render_template, request, redirect, url_for
import google.oauth2.id_token
from google.auth.transport import requests
from google.cloud import datastore
import os, random
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="google_auth_json.json"

firebase_req_adapter=requests.Request()

app = Flask(__name__)
datastore_client = datastore.Client()

def store_time(email):
    entity = datastore.Entity(key = datastore_client.key('User', email, 'visit'))
    entity.update({'email' : email})
    datastore_client.put(entity)

def retrieveCarInfo(claims):
    entity_key = datastore_client.key('CarInfo', claims['email'])
    entity = datastore_client.get(entity_key)
    return entity

def createCarInfo(claims):
    entity_key = datastore_client.key('CarInfo', claims['email'])
    entity = datastore.Entity(key = entity_key)
    entity.update({
        'email': claims['email'],
        'name': claims['name'],
        'cars_list': []
    })
    datastore_client.put(entity)

def retrieveCars(car_info):
    car_ids = car_info['cars_list']
    car_keys = []
    for i in range(len(car_ids)):
        car_keys.append(datastore_client.key('car', car_ids[i]))
    cars_list = datastore_client.get_multi(car_keys)
    return cars_list

def createCarDetails(claims, new_car_string, new_man_string, new_yr_int, new_bt_float, new_rg_int, new_cost_int, new_pr_int):
    id = random.getrandbits(63)
    entity_key = datastore_client.key('car', id)
    entity = datastore.Entity(key = entity_key)
    entity.update({
        'name': new_car_string,
        'manufacturer': new_man_string,
        'year': new_yr_int,
        'battery_size': new_bt_float,
        'range': new_rg_int,
        'cost': new_cost_int,
        'power': new_pr_int,
    })
    datastore_client.put(entity)
    return id

def addcarToUser(car_info, id):
    car_keys = car_info['cars_list']
    car_keys.append(id)
    car_info.update({
        'cars_list': car_keys
    })
    datastore_client.put(car_info)

def deleteCars(claims, id):
    car_info = retrieveCarInfo(claims)
    car_list_keys = car_info['cars_list']
    car_key = datastore_client.key('Car', car_list_keys[id])
    datastore_client.delete(car_key)
    del car_list_keys[id]
    car_info.update({
        'car_info' : car_list_keys
    })
    datastore_client.put(car_info)

# All functions below to render data to templates

@app.route("/")
def root():
    id_token = request.cookies.get("token")
    error_message = None
    claims = None
    car_info = None
    cars = None
    if id_token:
        try:
            claims = google.oauth2.id_token.verify_firebase_token(id_token,
                                                                  firebase_req_adapter)
            store_time(claims['email'])
            car_info = retrieveCarInfo(claims)
            if car_info == None:
                createCarInfo(claims)
                car_info = retrieveCarInfo(claims)
                cars = retrieveCars(car_info)
        except ValueError as exc:
            error_message = str(exc)
    return render_template('index.html', user_data=claims, error_message=error_message,
                           car_info=car_info, cars=cars)
    # return render_template('index.html', user_data=claims, error_message=error_message)

@app.route("/add_cars", methods=['POST'])
def add_ev():
    # add ev's
    id_token = request.cookies.get("token")
    error_message = None
    claims = None
    car_info = None
    if id_token and  request.method=='POST':
        try:
            claims = google.oauth2.id_token.verify_firebase_token(id_token, firebase_req_adapter)
            car_info = retrieveCarInfo(claims)
            id = createCarDetails(claims,
                                  request.form['name_update'],
                                  request.form['manufacturer_update'],
                                  request.form['year_update'],
                                  request.form['battery_update'],
                                  request.form['range_update'],
                                  request.form['cost_update'],
                                  request.form['power_update'])
            addcarToUser(car_info, id)
        except ValueError as exc:
            error_message = str(exc)

    return redirect(url_for("add_ev"))
    # return render_template('add-cars.html', user_data=claims, error_message=error_message, car_info=car_info)

@app.route("/list")
def list_ev():
    # listing all ev's
    id_token = request.cookies.get("token")
    error_message = None
    claims = None
    car_info = None
    if id_token:
        try:
            claims = google.oauth2.id_token.verify_firebase_token(id_token,
                                                                  firebase_req_adapter)
            car_info = retrieveCarInfo(claims)
            if car_info == None:
                createCarInfo(claims)
                car_info = retrieveCarInfo(claims)
        except ValueError as exc:
            error_message = str(exc)
    return render_template('list_ev.html', user_data=claims, error_message=error_message, car_info=car_info)

@app.route('/delete_cars/<int:id>', methods=['POST'])
def deleteCarFromUser(id):
    id_token = request.cookies.get("token")
    error_message = None
    if id_token:
        try:
            claims = google.oauth2.id_token.verify_firebase_token(id_token, firebase_req_adapter)
            deleteCars(claims, id)
        except ValueError as exc:
            error_message = str(exc)
    return redirect('/')

if __name__=='__main__':
    app.run(host='127.0.0.1', port=8082, debug=True)

CodePudding user response:

Could you try adding GET as a supported method to the below endpoint?

@app.route("/add_cars", methods=['GET', 'POST'])
def add_ev():
    # add ev's
    ...

CodePudding user response:

You need to add support for GET inside your add_ev and limit redirect to POST only (otherwise you will end with endless loop) i.e. something akin to

@app.route("/add_cars", methods=['GET','POST'])
def add_ev():
    ...
    if request.method == 'POST':
        return redirect(url_for("add_ev"))
    elif request.method == 'GET':
        return render_template('add_cars.html')
  • Related