I want to crate Keep-Alive http connection, but i failed.
I build a demo app.
from flask import Flask, make_response, Response
from flask import jsonify
try:
from http.server import BaseHTTPRequestHandler
except:
from BaseHTTPServer import BaseHTTPRequestHandler
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def hello_world():
resp = make_response("{'123':'aaa'}")
return resp
if __name__ == '__main__':
BaseHTTPRequestHandler.protocol_version = "HTTP/1.1"
app.run()
I send some requests,:
{"text":-1193959466}
{"text":-1139614796}
{"text":837415749}
{"text":-1220615319}
{"text":-1429538713}
{"text":118249332}
{"text":-951589224}
and i received some error:
127.0.0.1 - - [18/Apr/2019 20:14:15] "POST / HTTP/1.1" 200 -
127.0.0.1 - - [18/Apr/2019 20:14:16] "{"text":-1193959466}POST / HTTP/1.1" 405 -
127.0.0.1 - - [18/Apr/2019 20:14:16] "{"text":-1139614796}POST / HTTP/1.1" 405 -
127.0.0.1 - - [18/Apr/2019 20:14:17] "{"text":837415749}POST / HTTP/1.1" 405 -
127.0.0.1 - - [18/Apr/2019 20:14:17] "{"text":-1220615319}POST / HTTP/1.1" 405 -
127.0.0.1 - - [18/Apr/2019 20:14:18] "{"text":-1429538713}POST / HTTP/1.1" 405 -
127.0.0.1 - - [18/Apr/2019 20:14:19] "{"text":118249332}POST / HTTP/1.1" 405 -
127.0.0.1 - - [18/Apr/2019 20:14:19] "{"text":-951589224}POST / HTTP/1.1" 405 -
for this log, first request is success, but others failed.
It does not seem to clear the last request content.
if i remove this code:
BaseHTTPRequestHandler.protocol_version = "HTTP/1.1"
it's ok again.
Has anyone encountered the same problem? i used flask version : 1.0.2
update:
i know what happened, i need to read the request contents:
#app.route('/', methods=['POST'])
def hello_world():
# read the request content
print(request.json)
print("\n")
resp = make_response("{'123':'aaa'}")
return resp
thanks all.
Instead of using BaseHTTPRequestHandler, you can employ the default request_handler WSGIRequestHandler.
Since WSGIRequestHandler extends BaseHTTPRequestHandler, you can specify the HTTP protocol version you want to use. If you set the property to HTTP/1.1, the connection will stay alive.
from flask import Flask, make_response, Response
from werkzeug.serving import WSGIRequestHandler
from flask import jsonify
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def hello_world():
resp = make_response("{'123':'aaa'}")
return resp
if __name__ == '__main__':
WSGIRequestHandler.protocol_version = "HTTP/1.1"
app.run()
Don't forget to include from werkzeug.serving import WSGIRequestHandler
Related
You see Im having a problem where in flask, I made a web app. and I added the URL prefix as views
and you see without /views attached to localhost it throws a 404, I wanna change it so it will redirect automatically to /views when you go to the regular URL such as http://127.0.0.1:8000/
I tried adding #app.route in app.py but it just caused even more problems
You could redirect automatically from http://127.0.0.1:8000/ to http://127.0.0.1:8000/views using the code below.
from flask import Flask, jsonify, redirect
app = Flask(__name__)
#Page 1
#app.route('/', methods=['GET'])
def welcome():
return redirect("http://127.0.0.1:8000/views", code=302)
#Page 2
#app.route('/views', methods=['GET'])
def hello():
return jsonify({"data": "Hello"})
if __name__ == '__main__':
app.run(host="0.0.0.0", port="8000")
Output
#127.0.0.1 - - [01/Dec/2022 15:23:23] "GET / HTTP/1.1" 302 - (Redirecting to views page)
#127.0.0.1 - - [01/Dec/2022 15:23:23] "GET /views HTTP/1.1" 200 -
Hope this helps. Happy Coding :)
Flask restx is a library that develops api functions by dividing them into files in the flask framework and supports swaggerui.
When serving api and web pages on one flask server, the api part can be divided into files and developed using restx.
However, there is a caution when registering namespace to write flask restx.
The difference between the two source codes below is whether the namespace registration part of api and the app.route function part of api, and whether the namespace registration part of api comes before the app.route or later.
from flask import Flask, render_template, url_for
from datetime import datetime
from flask_restx import Api
from test import test
app = Flask(__name__)
#app.route('/')
def index():
return 'index'
api = Api(
app,
doc="/doc/",
version="0.1",
title="test",
)
api.add_namespace(test, '/test')
if __name__ == '__main__':
app.run(debug=True)
from flask import Flask, render_template, url_for
from datetime import datetime
from flask_restx import Api
from test import test
app = Flask(__name__)
api = Api(
app,
doc="/doc/",
version="0.1",
title="test",
)
api.add_namespace(test, '/test')
#app.route('/')
def index():
return 'index'
if __name__ == '__main__':
app.run(debug=True)
First, when executed with the first source code, it is normally recognized when approaching the / and /test path.
127.0.0.1 - - [27/Sep/2021 15:40:40] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [27/Sep/2021 15:40:40] "GET /test HTTP/1.1" 404 -
However, the second source code recognizes only /test normally and / does not.
127.0.0.1 - - [27/Sep/2021 15:40:40] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [27/Sep/2021 15:40:40] "GET /test HTTP/1.1" 200 -
It can be seen that the console log and web browser are also displaying 404 errors when approaching / route.
However, in the second source code, not all of the subroutes of / are not possible.
from flask import Flask, render_template, url_for
from datetime import datetime
from flask_restx import Api
from test import test
app = Flask(__name__)
api = Api(
app,
doc="/doc/",
version="0.1",
title="test",
)
api.add_namespace(test, '/test')
#app.route('/')
def index():
return 'index'
#app.route('/main')
def main():
return 'main'
if __name__ == '__main__':
app.run(debug=True)
In this way, / root is not recognized, but /main recognizes.
127.0.0.1 - - [27/Sep/2021 15:40:35] "GET / HTTP/1.1" 404 -
127.0.0.1 - - [27/Sep/2021 15:40:40] "GET /test HTTP/1.1" 200 -
127.0.0.1 - - [27/Sep/2021 15:40:45] "GET /main HTTP/1.1" 200 -
I don't know why they do this.
Try leaving the route string empty to see if that works
#app.route('')
def index():
return 'index'
I am new to Python and Flask and I need to work on a code base. I have the following files in directory called migration
Name
app
env
__pycache__
requirements.txt
run.py
In the run.py, I have a the following code:
from app import app
app.run(debug=True)
and inside the app directory, I have one __init__.py, which as code :
from app.helpers import get_page_display_name, get_page_url_name
# from app import views
from flask import Flask
app = Flask(__name__)
app.config['JSON_SORT_KEYS'] = False
app.jinja_env.globals.update(get_page_display_name=get_page_display_name)
app.jinja_env.globals.update(get_page_url_name=get_page_url_name)
Now I have a views.py file inside the same app folder and it has the route configuration and corresponding code like :
#app.route('/')
def index():
if 'username' in session:
return render_template("index.html")
return redirect(url_for('login'))
I am trying to run the application. I have used the following commands:
env/Scripts/activate
This has activated the environment and then:
$env:FLASK_APP=.\run.py
flask run
This has shown a message like it is running on http://127.0.0.1:5000 and printed the following messages when I opened the URL in browser:
127.0.0.1 - - [19/Nov/2020 10:23:15] "GET / HTTP/1.1" 404 -
127.0.0.1 - - [19/Nov/2020 10:23:15] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [19/Nov/2020 10:23:16] "GET / HTTP/1.1" 404 -
127.0.0.1 - - [19/Nov/2020 10:23:17] "GET / HTTP/1.1" 404 -
127.0.0.1 - - [19/Nov/2020 10:23:18] "GET / HTTP/1.1" 404 -
127.0.0.1 - - [19/Nov/2020 10:23:18] "GET / HTTP/1.1" 404 -
127.0.0.1 - - [19/Nov/2020 10:23:18] "GET / HTTP/1.1" 404 -
I have also tried with
$env:FLASK_APP=.\app\views.py
flask run
This also has printed the same message as it is running on the same port, but when opened, the same 404 messages are being shown.
How can I run this application ? I have checked the documentation, but the structure is little different for this application. Thanks in advance for the help.
You have to import your views file after definition of app. I suggest you to use blueprint.
EDIT
views.py
from flask import Blueprint
bp = Blueprint('test', __name__, url_prefix='/')
#bp.route('/')
def index():
if 'username' in session:
return render_template("index.html")
return redirect(url_for('login'))
__init__py
from app.helpers import get_page_display_name, get_page_url_name
from views import bp
from flask import Flask
app = Flask(__name__)
app.register_blueprint(bp)
app.config['JSON_SORT_KEYS'] = False
app.jinja_env.globals.update(get_page_display_name=get_page_display_name)
app.jinja_env.globals.update(get_page_url_name=get_page_url_name)
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
Changes made to the application.py file don't seem to be detected by the server after I save the file, even though debug mode is on. The only way I've been able to see changes is by exiting the server and restarting with flask run
Here is the code for application.py:
import os
import requests
from flask import Flask, session, render_template, request, url_for, flash, redirect, jsonify
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config["SECRET_KEY"] = 'secret!'
socketio = SocketIO(app)
#app.route("/")
def index():
print('hello world')
return 'hello!'
if __name__ == '__main__':
socketio.run(app, debug=True)
And here's the command line/terminal:
λ flask run
* Serving Flask-SocketIO app "application.py"
* Forcing debug mode on
* Restarting with stat
* Debugger is active!
* Debugger PIN: 156-884-244
(3824) wsgi starting up on http://127.0.0.1:5000
(3824) accepted ('127.0.0.1', 50569)
127.0.0.1 - - [10/Sep/2018 20:07:40] "GET /socket.io/?EIO=3&transport=polling&t=1536624459432-5 HTTP/1.1" 200 381 0.000000
(3824) accepted ('127.0.0.1', 50571)
127.0.0.1 - - [10/Sep/2018 20:07:40] "GET /socket.io/?EIO=3&transport=polling&t=1536624460314-6&sid=79eb8e587f664e3383c946bb046717ca HTTP/1.1" 200 215 0.000000
(3824) accepted ('127.0.0.1', 50568)
127.0.0.1 - - [10/Sep/2018 20:07:44] "GET /socket.io/?EIO=3&transport=websocket&sid=79eb8e587f664e3383c946bb046717ca HTTP/1.1" 200 0 4.610168
hello world
127.0.0.1 - - [10/Sep/2018 20:07:44] "GET / HTTP/1.1" 200 152 0.000000
hello world
127.0.0.1 - - [10/Sep/2018 20:07:58] "GET / HTTP/1.1" 200 152 0.000000
hello world
127.0.0.1 - - [10/Sep/2018 20:08:06] "GET / HTTP/1.1" 200 152 0.000000
wsgi exiting
(3824) wsgi exited, is_accepting=True
Those hello world's in command show up every time I change the text in print('hello world') and refresh the browser. Regardless of what I change it to, I always get the original version of the code's print argument.
Couple things I'm noticing:
this issue doesn't occur when I'm just running Flask. When I'm just running Flask, I see in the command line/terminal that changes were detected.
if I return a template of an HTML file, changes to the HTML file are automatically updated.
Hmm. It looks like the reloader does not work with you run the application via flask run. It does work, however, when you run it by running your application file (i.e. python application.py).
I'll log a bug and investigate.