Using Flask, how can I read HTTP headers? I want to check the authorization header which is sent by the client.
-
2Related: [How do I get the user agent with Flask?](http://stackoverflow.com/q/9878020) – Martijn Pieters Nov 21 '15 at 13:06
-
1Also, see the [*Flask Quickstart*](http://flask.pocoo.org/docs/0.10/quickstart/#the-request-object) and [*API documentation*](http://flask.pocoo.org/docs/0.10/api/#incoming-request-data). – Martijn Pieters Nov 21 '15 at 13:06
4 Answers
from flask import request
request.headers.get('your-header-name')
request.headers
behaves like a dictionary, so you can also get your header like you would with any dictionary:
request.headers['your-header-name']

- 5,999
- 2
- 19
- 30
-
12FYI: I'm looking at http://flask.pocoo.org/snippets/8/ and it appears you could also access the username and password for basic authentication like so: `request.authorization.username` or `request.authorization.password`. – Karthic Raghupathi Nov 06 '15 at 20:08
-
2@Karthic Raghupathi, as long as the header doesn't have illegal characters like dashes, which most headers do (i.e., X-Api-Key), in which case you need to access it like a dictionary with keys. – Blairg23 Oct 12 '16 at 02:02
-
Adding `if hasattr(request, 'authorization'):` to code will help check for missing 'authorization' attribute in request. – Abhijeet Dec 14 '16 at 06:07
-
@Abhijeet: It seems this isn't always the case. When I use `curl` without specifying authorisation headers, `hasattr(request, 'authorization')` returns `True` but `getattr(request, 'authorization')` returns `None`. I'm not sure if this is the result of middleware or frameworks I'm using (Flask-Restful, for example). – Michael Scheper Apr 27 '17 at 20:35
-
@MichaelScheper may using `in` operator check might help, it worked for me `if 'authorization' in request:`, [other usage of in operator](http://stackoverflow.com/a/11447648/452708) – Abhijeet Apr 28 '17 at 14:25
-
@Abhijeet: Again, that checks whether the key exists, but not whether the value exists. A safer way would be `if request.headers.get('your-header-name', None)`—this will pass only if 'your-header-name' exists _and_ the value is non-null. – Michael Scheper Apr 28 '17 at 20:34
-
@MichaelScheper that's a fact, the logic needs to have few conditional together to take-care of `Non-Existence & None value` i.e., `if 'headers' in request and request.header is not None and 'authorization' in request.headers and request.headers['authorization'] is not None:` – Abhijeet Apr 29 '17 at 01:03
-
1@Abhijeet: ... or you could just use the code that I suggested in my previous comment. Much cleaner. – Michael Scheper May 04 '17 at 15:02
-
7Flask headers are not a dict, yeah?... i see them coming back as werkzeug.datastructures.EnvironHeaders in my tests. http://werkzeug.pocoo.org/docs/0.14/datastructures/#werkzeug.datastructures.EnvironHeaders – Pandem1c Sep 05 '18 at 21:33
-
1@MichaelScheper the second argument to `get` would seem to be redundant, since I believe `None` is the default. – holdenweb Feb 11 '19 at 11:38
-
@holdenweb: Thanks—you're right. I thought the second parameter was necessary to prevent a `KeyError`, but that's only true for `request.headers['your-header-name']`. (I should've known that.) But it's been a while since I've looked at this, so I'm not sure if that resolves Abhijeet's and Pandem1c's concerns. – Michael Scheper Feb 12 '19 at 23:02
-
just note, The different between the methods are, if the header is not exist
request.headers.get('your-header-name')
will return None
or no exception, so you can use it like
if request.headers.get('your-header-name'):
....
but the following will throw an error
if request.headers['your-header-name'] # KeyError: 'your-header-name'
....
You can handle it by
if 'your-header-name' in request.headers:
customHeader = request.headers['your-header-name']
....

- 1,725
- 13
- 16
If any one's trying to fetch all headers that were passed then just simply use:
dict(request.headers)
it gives you all the headers in a dict from which you can actually do whatever ops you want to. In my use case I had to forward all headers to another API since the python API was a proxy

- 4,976
- 2
- 24
- 71
-
3@JamieLindsey This is not true. `request.headers` is actually an `EnvironHeaders` object that can be accessed like a dictionary. https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.EnvironHeaders – jasonrhaas Feb 19 '20 at 21:47
-
1Although @jasonrhass is correct in most cases, `EnvironHeaders` isn't a subclass of `dict` so it fails many times where a `dict` would succeed (`isinstance(flask.request.headers, dict) == False`). For example, the following code produces an error: `print(json.dumps(flask.request.headers, indent=4))`. The fix is `print(json.dumps(dict(flask.request.headers), indent=4))`. – Tim Ludwinski Dec 14 '20 at 17:34
-
@TimLudwinski You're maybe missing out on the context. There was a deleted comment which claimed that the `request.headers` would be of type `dict` since it can be accessed/queried like a `dict`. The comment you see, is a response to that. – iam.Carrot Dec 14 '20 at 17:43
Let's see how we get the params, headers, and body in Flask. I'm gonna explain with the help of Postman.
The params keys and values are reflected in the API endpoint.
for example key1 and key2 in the endpoint :
https://127.0.0.1/upload?key1=value1&key2=value2
from flask import Flask, request
app = Flask(__name__)
@app.route('/upload')
def upload():
key_1 = request.args.get('key1')
key_2 = request.args.get('key2')
print(key_1)
#--> value1
print(key_2)
#--> value2
After params, let's now see how to get the headers:
header_1 = request.headers.get('header1')
header_2 = request.headers.get('header2')
print(header_1)
#--> header_value1
print(header_2)
#--> header_value2
Now let's see how to get the body
file_name = request.files['file'].filename
ref_id = request.form['referenceId']
print(ref_id)
#--> WWB9838yb3r47484
so we fetch the uploaded files with request.files
and text with request.form

- 2,938
- 3
- 13
- 24