0

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.

Reventlow
  • 147
  • 1
  • 10
  • 1
    You have only defined 3 GET endpoints, yet you're trying to make a POST request to the endpoint. – rdas Sep 18 '22 at 15:47
  • I tried altering them to POST endpoints but I still get the same result. – Reventlow Sep 18 '22 at 16:00
  • 1
    Please have a look at [this answer](https://stackoverflow.com/a/70636163/17865804), as well as [this](https://stackoverflow.com/a/70640522/17865804) and [this](https://stackoverflow.com/a/73761724/17865804) answer. – Chris Sep 18 '22 at 19:35
  • Chris that fixed my issues thanks :-) – Reventlow Sep 19 '22 at 05:28

1 Answers1

2

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.