python: server is not receiving input from client flask
Chris Angelico
rosuav at gmail.com
Mon Jun 28 15:59:20 EDT 2021
On Tue, Jun 29, 2021 at 5:43 AM Jerry Thefilmmaker
<jerrythefilmmaker at gmail.com> wrote:
>
> Do you mind elaborating a bit more on making one function for any given request?
>
> As far as defining a bunch of functions that get called when particular requests come in I thought that's what I had going on in my codes. No?
>
> Also thank you, on making use of the print statement. Thought once I crossed over to the web side there was no more need for it. But what you said makes sense in terms of debugging, because sometimes I couldn't tell whether the client's variable was getting pass to my function which caused it not to be triggered.
>
> Thank you!
>
Sure. I'll take a step back and look quickly at the way HTTP works and
how Flask figures out what function to call; you probably know all
this but it'll make the explanation easier.
Every HTTP request has a method (GET, POST, PUT, DELETE, etc) and a
request URI. Some of the URI just figures out whether it goes to your
server or not, and the rest is which page within your server. So if
you're running on, say, port 5000 on the same computer the web browser
is on, then you can go to http://localhost:5000/any/path/here and
it'll be handled by your web app. Since the "http://localhost:5000"
part is the way to find the whole server, Flask just looks at the rest
of it - "/any/path/here" - to do its routing. So we have two parts - a
path and a method - that define which function is called.
When you point your browser at "http://localhost:5000/", that's a GET
request (normal web page fetches are GET requests) with a path of "/".
When you submit the form, that's a POST request (because the form's
method) with a path of "/" (because that's the form's action). I'm
assuming here that nothing is getting in the way of that, but that's
what printing stuff out can help with.
So far, so good. I'm pretty sure none of what I just said is news to
you, but let's focus on those two requests: "GET /" and "POST /".
The app.route decorator lets you associate a function with some
path/method combination. What you have in the code you shared is this:
> @app.route("/", methods = ['POST', 'GET'])
> def play():
>
> @app.route("/", methods = ['POST', 'GET'])
> def check_answer(ans, user):
That tells Flask that the play function should be associated with
"POST /" and "GET /". And then it tells Flask that the check_answer
function should be associated with... the same two routes.
I suspect that what you actually intend is for one of those functions
to just handle GET, and the other to just handle POST. But another way
you could fix this would be to change the URL used as the form's
action. It's up to you and what your plans are for the rest of this
app.
(My recommendation is to start out with each function handling just
one route - say, "GET /" for play() and "POST /" for check_answer -
and only combine them (with multiple keywords in methods=[...]) once
you find that the two functions are duplicating a lot of code.)
Once that's sorted out, you'll want to figure out exactly what
parameters your functions take. As a general rule, the function's
parameters will match the placeholders in the route, so if you're not
using placeholders, you'll probably just want them all to take no
parameters. Here are some examples from a project of mine:
@app.route("/login")
def login():
@app.route("/force/<id>")
def force_timer(id):
@app.route("/")
@app.route("/editor/<channelid>")
def mainpage(channelid=None):
In the case of mainpage, it handles both "GET /" and "GET
/editor/12345", so the function might get a parameter and might not -
hence it takes a parameter with a default. For what you're doing here,
there are no placeholders in your routes, so all your routed functions
will take no args (like login in my example - it only ever handles
"GET /login", so it doesn't need anything else).
Hope that helps!
ChrisA
More information about the Python-list
mailing list