Skip to content
Advertisement

Python and FastAPI: keep getting 405 when posting response

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 {'msg': 'welcome to the lectio-fastapi', 'success': True}


@app.post("/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.post("/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/")
def send_msg():
    return {'msg': 'message_send function for lectio', 'success': True}

@app.post("/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 405 when posting

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"



    resp = requests.get(url, 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_get = requests.get(url, headers=headers)
    resp_post = requests.post(url, data=payload, headers=headers)
    print(resp_get.text)
    print(resp_get)
    print(resp_post.text)
    return resp_post

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/
{"msg":"welcome to the lectio-fastapi","success":true}
<Response [200]>
https://lectio-fastapi.herokuapp.com/message_send/
{"msg":"message_send function for lectio","success":true}
<Response [200]>
{"detail":"Method Not Allowed"}
<Response [405]>

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 to get my post function to work. But not sure what is missing.

Advertisement

Answer

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.

Advertisement