[SOLVED] Python and FastAPI: keep getting 405 when posting response

Issue

This Content is from Stack Overflow. Question asked by Reventlow

I have made at fasstapi at https://lectio-fastapi.herokuapp.com/docs#/

from fastapi import FastAPI
from starlette.responses import JSONResponse
from . import lectio
app = FastAPI()


@app.get("/")
def read_root():
    return {'success': True}

@app.get("/school_ids/{lectio_school_name}")
def get_school_id(lectio_school_name: str):
    json_object = lectio.lectio_search_webpage_for_schools(lectio_school_name)
    return JSONResponse(content=json_object)

@app.get("/message_send/{lectio_school_id, lectio_user, lectio_password}")
def test_login(lectio_school_id: int, lectio_user: str, lectio_password: str):
    browser = lectio.get_webdriver()
    lectio_login_result = lectio.lectio_login(lectio_school_id, lectio_user, lectio_password, browser)
    return lectio_login_result

@app.get("/message_send/{lectio_school_id, lectio_user, lectio_password, send_to, subject, msg, msg_can_be_replied}")
def send_msg(lectio_school_id: int, lectio_user: str, lectio_password: str, send_to :str, subject: str, msg: str, msg_can_be_replied: bool):
    browser = lectio.get_webdriver()
    lectio_login_result = lectio.lectio_login(lectio_school_id, lectio_user, lectio_password,browser)
    if lectio_login_result['success']:
        lectio_send_msg_result = lectio.lectio_send_msg(send_to, subject, msg, msg_can_be_replied, lectio_school_id, browser)
        return lectio_send_msg_result
    else:
        return {'msg': 'Login failed, wrong username, password and school_id combination ', 'success': False}

def main():
    pass

if __name__ == "__main__":
    main()

When I test on the fastapi site it works like a charm.

But when I try to access it from another python program i get 404 returns and 405

import requests
from requests.structures import CaseInsensitiveDict


API_ENDPOINT = "https://lectio-fastapi.herokuapp.com" #link to fastapi

def lectio_root():
    url = API_ENDPOINT
    print(url)

    headers = CaseInsensitiveDict()
    headers["accept"] = "application/json"
    headers["Content-Type"] = "application/json"

    payload = {}

    resp = requests.post(url, data=payload, headers=headers)
    print(resp.text)
    return resp

def lectio_send_msg(lectio_school_id: int, lectio_user: str, lectio_password: str, send_to :str, subject: str, msg: str, msg_can_be_replied: bool):
    url = API_ENDPOINT+"/message_send/"
    print(url)

    headers = CaseInsensitiveDict()
    headers["accept"] = "application/json"
    headers["Content-Type"] = "application/json"


    payload = '{"lectio_school_id": ' + str(lectio_school_id) + ', "lectio_user": ' + lectio_user + ', "lectio_password": ' + lectio_password + ', "send_to": ' + send_to + ', "subject": ' + subject + ', "msg": ' + msg + ', "msg_can_be_replied": ' + str(msg_can_be_replied) + '}'

    resp = requests.post(url, headers=headers, data=payload)
    print(resp.text)
    return resp

def main():
    lectio_school_id = 235
    lectio_user = 'test_user'
    lectio_password = 'test_password'
    send_to = 'Mr test'
    subject = 'test subject'
    msg = 'test msg'
    msg_can_be_replied = False
    print(lectio_root())
    print(lectio_send_msg(lectio_school_id, lectio_user, lectio_password, send_to, subject, msg, msg_can_be_replied))



if __name__ == '__main__':
    main()

the output I am getting is:

https://lectio-fastapi.herokuapp.com
{"detail":"Method Not Allowed"}
<Response [405]>
https://lectio-fastapi.herokuapp.com/message_send/
{"detail":"Not Found"}
<Response [404]>

And I am expecting to get these returns:

{'success': True}


{'msg': 'Login failed, wrong username, password and school_id combination ', 'success': False}

It seems like to me I need to define something more in FastAPI but not sure what is missing.



Solution

First, you need to change request in the lectio_root

resp = requests.post(url, data=payload, headers=headers)

to

resp = requests.get(url, headers=headers)

because, in your app, read_root function have GET request, not POST.

Second, you need to change send_msg decorator

@app.get("/message_send/{lectio_school_id, lectio_user, lectio_password, send_to, subject, msg, msg_can_be_replied}")

to

@app.post("/message_send/{lectio_school_id, lectio_user, lectio_password, send_to, subject, msg, msg_can_be_replied}")

because, inside lectio_send_msg function you are sending POST request.


This Question was asked in StackOverflow by Reventlow and Answered by Milos Bogdanovic It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?