This question already has answers here:
Configure Flask dev server to be visible across the network
(17 answers)
Closed 4 months ago.
I have a Flask api server running, worked absolutely fine on 127.0.0.1 right up until I started tinkering with trying to get it working across the LAN. I can see the connections from other devices on the LAN in the debug log, and it is receiving the connections fine, but not serving any pages, only 404, but not even my custom 404.
I have enabled Network Discovery, set network to Private, allowed Python through the firewall and tried using a non standard port (51234), disabled firewalls but I still get 404 errors.
127.0.0.1 - - [20/Oct/2022 12:38:00] "GET / HTTP/1.1" 404 -
192.168.1.205 - - [20/Oct/2022 12:38:11] "GET /api/companies?id=1 HTTP/1.1" 404 -
192.168.1.168 - - [20/Oct/2022 12:38:25] "GET / HTTP/1.1" 404 -
192.168.1.113 - - [20/Oct/2022 12:38:41] "GET / HTTP/1.1" 404 -
192.168.1.205 - - [20/Oct/2022 12:43:58] "GET / HTTP/1.1" 404 -
So in order to test it, I went back to basics and only allowed localhost again, and now nothing is working!
* Serving Flask app 'training_server' * Debug mode: on * Running on http://127.0.0.1:5155 Press CTRL+C to quit * Restarting with stat * Debugger is active! 127.0.0.1 - - [20/Oct/2022 12:44:54] "GET / HTTP/1.1" 404 - 127.0.0.1 - - [20/Oct/2022 12:45:12] "GET / HTTP/1.1" 404 - 127.0.0.1 - - [20/Oct/2022 12:45:12] "GET /favicon.ico HTTP/1.1" 404 - 127.0.0.1 - - [20/Oct/2022 12:50:09] "GET / HTTP/1.1" 404 -
from flask import Flask, json, jsonify, request
companies = [{"id": 0, "name": "ACME", "state":"Essex"},
{"id": 1, "name": "Bluebell", "state":"Hertfordshire"}
]
users = [{"company":"ACME","name": "Steve Herbert", "employeeID":"125785", "email":"sherbert#acme.com"},
{"company":"ACME","name": "Steve Herbert", "employeeID":"125785", "email":"sherbert#acme.com"}
]
api = Flask(__name__)
api.config["DEBUG"] = True
api.config['JSON_SORT_KEYS'] = False
api.run(host='127.0.0.1', port=5155)
#api.route('/', methods=['GET'])
def home():
return "<h1>Company Directory</h1><p>This site is a prototype API for company directory listing.</p>"
#api.route('/api/companies/all', methods=['GET'])
def get_companies():
return jsonify(companies)
#api.route('/api/companies', methods=['GET'])
# Check if a param was provided as part of the URL.
# If param is provided, assign it to a variable. If not, display an error in the browser.
def get_company():
print('req' + str(request.args))
print('hello' + next(iter(request.args.keys())))
#print([elem[0:] for elem in request.args.keys()])
if 'id' in request.args:
filter = next(iter(request.args.keys()))
param = int(next(iter(request.args.values())))
elif 'name' in request.args:
filter = next(iter(request.args.keys()))
param = str(next(iter(request.args.values())))
else:
return "Error: No param field provided. Please specify a value."
results = apiParam(param, filter, companies)
return jsonify(results)
def apiParam(param, filter, list):
print('filter' + str(filter))
results = []
# Loop through the data and match results that fit the requested parameter.
for li in list:
if li[filter] == param:
results.append(li)
return results
if __name__ == '__main__':
api.run()
Fixed it after some more research/Googling while I waited for answers
Moved the host declaration to underneath the if name call
import os
if __name__ == '__main__':
port = int(os.environ.get("PORT", 5155))
api.run(host='0.0.0.0', port=port)
The problem comes from run.api() at the start. This is blocking the script so the route handlers are never reached.
Move that line to the end, inside the if __name__ block.
Related
This question already has answers here:
Run code after flask application has started
(7 answers)
Closed 8 months ago.
I have a flask web app and I wanted a function to be called every time the page loads. I got it to work using "#app.before_request", my only problem is, I have 4 requests that are being made on every page load.
Here's my logs in my console
127.0.0.1 - - [14/Jun/2022 17:54:47] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [14/Jun/2022 17:54:48] "GET /static/style.css HTTP/1.1" 304 -
127.0.0.1 - - [14/Jun/2022 17:54:48] "GET /static/profile.jpg HTTP/1.1" 304 -
127.0.0.1 - - [14/Jun/2022 17:54:48] "GET /favicon.ico HTTP/1.1" 404 -
Obviously it's running before every single request, including requests just for loading my html and css files. I want to limit it so that it only runs once and not 4 times. I'm having it add +1 to a count on a database and since 4 requests are being run, it's running 4 times and adding 4 every time.
Here's my before_request class and function, that I want to somehow limit to running only once (maybe the initial request) and not all 4
#app.before_request
def before_request():
dbcounter = handler()
print(dbcounter)
#app.route('/')
def home():
count = handler()
return render_template("index.html")
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
#app.before_first_request is what solved it!
My code
from flask import Flask, jsonify
app = Flask(__name__)
#app.route('/api')
def my_microservice():
return jsonify({'Hello': 'World!'})
if __name__ == '__main__':
app.run()
Terminal output
python flask_basic.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [20/Nov/2018 14:14:39] "GET / HTTP/1.1" 404 -
I have checked with lsof -i:5000 command and got nothing.
Why?
You set the route to /api (#app.route('/api')), yet you sent the request to /: "GET / HTTP/1.1".
Either change the route to / or send the request to /api
I am currently developing a python web-app based on bottle so what I am trying to do is print the outcome of a for loop I have tried the following
#!/usr/bin/python
from bottle import *
#route('/')
def index():
for i in range(10):
return i
but this did not work and i got this from the development server output
localhost - - [13/Jan/2017 18:11:38] "GET /request HTTP/1.1" 200 0
localhost - - [13/Jan/2017 18:11:40] "GET /favicon.ico HTTP/1.1" 200 0
so i tried this
#!/usr/bin/python
from bottle import *
#route('/')
def index():
sumOfValues=0
for i in range(10):
sumOfValues+=i
return sumOfValues
this also did not work
and my devlopment server gave me this
localhost - - [13/Jan/2017 18:15:44] "GET /request HTTP/1.1" 500 746
localhost - - [13/Jan/2017 18:15:46] "GET /favicon.ico HTTP/1.1" 500 750
so how can I do it I tried searching google but nothing came back
, thanks in advance
Function has to return string - so use return str(sumOfValues)
If you return in a function, it immediately ends.
It looks like you want to do a streaming response of-sorts. Bottle can do this, but you must yield items.
See also:
Streaming Connection Using Python Bottle, Multiprocessing, and gevent
Flask seems to be not adding a slash at the url end before the get parameters in every case. But is doing it only in this case.
it changes /users?uid=1 to /users/?uid=1
After changing it to tha it even gives me a 404 error. "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."
Here's the code:
from flask import Flask, render_template, jsonify, Response, request
app = Flask(__name__)
#app.route("/users")
#app.route("/post")
#app.route("/bookmarks")
#app.route("/<target>")
def category_browser(target = ""):
if(target != "" and target not in ['categories']):
return render_template("404.html")
else:
return render_template("view.html")
if(__name__ == "__main__"):
app.debug = True;
app.run(port=int(80))
You had a stale cache entry in instance of Chromium when you had the route defined as #app.route("/users/"). You later changed to #app.route("/users") which Chrome still had it cached with the trailing /. Try accessing this simple example using incognito mode and see that /users?uid=1 remaining unchanged and that no 404 is reported. This is what happens when I first accessed it initially (using Chrome 42).
127.0.0.1 - - [07/Jul/2015 14:02:39] "GET /users?target=1 HTTP/1.1" 200 -
Then stopping that script (thanks for that complete almost self-contained example) and add #app.route("/users/") to the list of routes, below the original #app.route("/users/") route (to have a higher order of precedence so that Flask first trigger the redirect), i.e.:
#app.route("/users")
#app.route("/users/")
(Or simply remove the #app.route("/users") decorator)
Now try accessing the same page again in your incognito session, note that in your console:
127.0.0.1 - - [07/Jul/2015 14:04:11] "GET /users?target=1 HTTP/1.1" 301 -
127.0.0.1 - - [07/Jul/2015 14:04:11] "GET /users/?target=1 HTTP/1.1" 200 -
Ah, there's your redirect. Remove that extra line we just added, try going to /users?target=1 again, this is what happens:
127.0.0.1 - - [07/Jul/2015 14:07:22] "GET /users/?target=1 HTTP/1.1" 404 -
Chrome silently rewrites the URL to /users/?target=1 based on the cache entry in the incognito mode, and is reflected because only that URL is showing up on the Flask access log.
If you wish to support both methods, you have to do it this way:
#app.route("/users/")
#app.route("/users")
Then both access methods work:
127.0.0.1 - - [07/Jul/2015 14:08:49] "GET /users/?target=1 HTTP/1.1" 200 -
127.0.0.1 - - [07/Jul/2015 14:08:59] "GET /users?target=1 HTTP/1.1" 200 -
Rather than resulting in:
127.0.0.1 - - [07/Jul/2015 14:10:00] "GET /users?target=1 HTTP/1.1" 301 -
127.0.0.1 - - [07/Jul/2015 14:10:00] "GET /users/?target=1 HTTP/1.1" 200 -
I'm getting some really strange behaviour when running gevent's WSGIServer. It seems like every request that comes through is having its method interpreted incorrectly..
If I send the following requests:
requests.get('http://localhost:5000')
requests.head('http://localhost:5000')
requests.delete('http://localhost:5000')
requests.put('http://localhost:5000')
requests.post('http://localhost:5000')
This is what appears in the console:
127.0.0.1 - - [2012-01-22 14:55:36] "POST / HTTP/1.1" 405 183 "-" "python-requests/0.9.1"
127.0.0.1 - - [2012-01-22 14:55:41] "DELETE / HTTP/1.1" 405 185 "-" "python-requests/0.9.1"
127.0.0.1 - - [2012-01-22 14:55:46] "16 / HTTP/1.1" 405 181 "-" "python-requests/0.9.1"
127.0.0.1 - - [2012-01-22 14:55:50] "8 / HTTP/1.1" 405 180 "-" "python-requests/0.9.1"
127.0.0.1 - - [2012-01-22 14:56:13] "HEAD / HTTP/1.1" 200 0 "-" "python-requests/0.9.1"
For completeness, this is the script I'm running:
from gevent.wsgi import WSGIServer
from flask import Flask
app = Flask(__name__)
app.debug = True
#app.route("/")
def hello():
return 'hello'
port = 5000
http_server = WSGIServer(('', port), app)
http_server.serve_forever()
What could be going on?
Edit:
I'm using gevent version: 0.13.0
Libevent has a limited support for HTTP methods and which HTTP methods are supported depends on a libevent version. Why you have a number instead of a method is obviously a bug. Could it be that you're building and linking gevent against different versions?
Can you try switching to gevent.pywsgi? That'll fix the issue at the cost of some performance.
Also the 1.0 version of gevent has a number of great improvements. You can get it there: http://code.google.com/p/gevent/downloads/list