TheGainadl
TheGainadl

Reputation: 653

How to make post requests work with ngrok?

I am using python to develop an application. I am doing some tests to see how it works.

First I tried this code with Flask

from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
    return 'The GET works'

if __name__ == "__main__":
    app.run()

And it worked fine. Then, because I want everyone to access my application, I used ngrok for that, I just typed in the console:

./ngrok http 5000

And it worked fine, I can access the URL from everywhere, but for my application, I need to be able to make POST requests from everywhere. But whenever I try to make a post request like this

import requests
r = requests.post('http://10d2b892.ngrok.io/',data={'key':'value'})

r returns Response [405] and I cant post anything. What should I do in order to make Post requests work?

Upvotes: 1

Views: 7177

Answers (3)

alexdlaird
alexdlaird

Reputation: 1293

You're almost there. The annotation you're using

@app.route("/")

creates a default route with the GET method, but you're trying to POST. Since you didn't define POST, you get a 405 Method Not Allowed. To fix that, simply define POST, as documented here

@app.route('/', methods=['GET', 'POST'])

As an added bonus, you can also manage ngrok in your Python script using pyngrok. There's a Flask documented example here, but the short if it is you'd simply do from pyngrok import ngrok and ngrok.connect(5000). Boom, now you have a tunnel to the Flask dev server.

Upvotes: 0

rSkogeby
rSkogeby

Reputation: 309

ngrok will forward whatever http request you send it. Your problem is that the Flask application isn't written to handle post requests. On that note, I will assume you're new to Flask and will recommend you to just do the switch to FastAPI immediately:

from fastapi import FastAPI

app = FastAPI()

@app.get('/', status_code=200)
def index():
    return {'message':'Hello, World!'}

@app.post('/', status_code=201)
def index_post():
    return {'message':'Hello, Post!'}

I believe it will make your life easier in both the short and long run. If you also run it using Uvicorn you'll be off to a good start:

from fastapi import FastAPI
import uvicorn

app = FastAPI()

@app.get('/', status_code=200)
def index():
    return {'message':'Hello, World!'}

@app.post('/', status_code=201)
def index_post():
    return {'message':'Hello, Post!'}

if __name__ == "__main__":
    uvicorn.run(
        "views:app", 
        host="localhost", 
        port=5000,
        reload=True    
    )

Go ahead and name that file views.py.

Create your virtual environment (venv):

python3 -m venv venv

Source it

source venv/bin/activate

Install the modules

pip install uvicorn fastapi

and run it

python views.py

Now you can make it accessible with ngrok

ngrok http 5000

When you save changes in views.py your uvicorn server will restart automatically, and you should be able to try your changes out without restarting anything.

Hope this gets you going.

Upvotes: 0

Danizavtz
Danizavtz

Reputation: 3280

As stated by the documentation, you should use annotations:

from flask import request

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        return do_the_login()
    else:
        return show_the_login_form()

Upvotes: 1

Related Questions