Posts: 3
Threads: 1
Joined: Jan 2019
Hello everyone,
While working with HTTP headers in python, am usually faced with the situation of setting or requesting for some common header information; be it headers.get('Host') or something similar.
I was wondering if the python standard library (or any other library) defines constants for these headers' names, so that the developer need not type out the string equivalent for them.
I came across this in the Rust documentation: https://docs.rs/http/0.1.15/http/header/...#constants, which is exactly what I would like to see in the Python library.
Any suggestions on where I can look for this? I didn't have any luck doing a web search, or via the python console.
Thank you,
Kiran
Posts: 7,319
Threads: 123
Joined: Sep 2016
Requests is like a standard when working with HTTP in Python
HTTPie for command line.
>>> import requests
>>> req = requests.get('http://python-forum.io')
>>> req.status_code
200
>>> req.encoding
'UTF-8'
>>> req.headers['Content-Type']
'text/html; charset=UTF-8'
>>> req.headers['Server']
'Apache'
>>> url = 'https://api.github.com/some/endpoint'
>>> headers = {'user-agent': 'my-app/0.0.1'}
>>> r = requests.get(url, headers=headers)
Posts: 3
Threads: 1
Joined: Jan 2019
Jan-31-2019, 10:03 AM
(This post was last modified: Jan-31-2019, 10:04 AM by kirans.)
Thanks for the response.
Am aware of the requests, and httpie libraries.
I think I need to elaborate, on my original query.
I want to refer to the Http headers as constants, and not as strings. So, for example headers.get(http.HOST) . This will eliminate a class of typo errors, and also not require one to remember the exact spelling of the Http header. Should it be referer or referrer , and does case matter, etc.
Therefore, was wondering if there is a module, like the http one referred above, (stdlib or otherwise), that could help with this.
Posts: 7,319
Threads: 123
Joined: Sep 2016
Okay i understand,i don't know of a library that dos this.
Could be idea to make it yourself,with a wrapper around Requests.
But it can some work if need all constants that the Rust library has.
Posts: 3,458
Threads: 101
Joined: Sep 2016
I don't know if there's anything like that already, but it wouldn't be difficult to write.
class http:
HOST = "Host"
headers.get(http.HOST)
Posts: 2,953
Threads: 48
Joined: Sep 2016
Hm! That is a common problem with all networking tools and libraries. They just give you an interpretation of all the packets received and nothing else. For example, the ping command or the Python requests library. You have to deal with the packets themselves.
I would suggest the Scapy module. You have to do a handshake first and after that the HTTP request. But I can't tell you how to do that. I am not familiar with the TCP or any other networking protocol. However, using that library you could create any tool you need. The benefits? You get all the data of any packet.
Posts: 7,319
Threads: 123
Joined: Sep 2016
Feb-01-2019, 07:10 AM
(This post was last modified: Feb-01-2019, 07:10 AM by snippsat.)
I not sure if you quite understand the task @ wavic,Scapy would add a whole new level of complexity that may not be needed.
It can be use to add some features if build this,but may also not be needed.
To give n rough example when i say wrapper around Requests.
Can also bring in stuff from requests.utils eg as i do with url.user_agent ,
which has a lot features that not so good documented.
import requests
class Url:
def __init__(self, url):
try:
self.req = requests.get(url)
self.server = self.req.headers['Server']
self.date = self.req.headers['Date']
self.user_agent = requests.utils.default_headers()
except requests.exceptions.ConnectionError as e:
print("Wrong domains,chek spelling")
def __getattr__(self, attr):
return "API has not that name,check spelling"
@property
def header(self):
'''May be needed later'''
pass
@header.setter
def header(self):
'''May be needed later'''
pass
Use:
>>> url = Url('https://www.python.org99')
Wrong domains,chek spelling
>>> url = Url('https://www.python.org')
>>> # all Requests build in constants will be under "req"
>>> url.req.status_code
200
>>> url.req.encoding
'utf-8'
>>> # New constants added
>>> url.server
'nginx'
# Miss-spelling will call __getattr__
>>> url.serverrr
'API has not that name,check spelling'
>>> url.date
'Fri, 01 Feb 2019 01:50:02 GMT'
>>> url.user_agent
{'User-Agent': 'python-requests/2.21.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
>>> url.user_agentt
'API has not that name,check spelling'
>>>
Posts: 2,953
Threads: 48
Joined: Sep 2016
Well, I am not familiar with those requests features. Perhaps the socket module is capable to do all of this too. Good to know...
Posts: 7,319
Threads: 123
Joined: Sep 2016
Feb-02-2019, 05:37 PM
(This post was last modified: Feb-02-2019, 05:38 PM by snippsat.)
(Feb-02-2019, 10:52 AM)wavic Wrote: Perhaps the socket module is capable to do all of this too. Good to know... Yes,but that would be a lot work(already done bye Requests).
Requests has all features @ kirans ask for,just that he want constants of HTTP headers reason he explain here.
kirans Wrote:This will eliminate a class of typo errors, and also not require one to remember the exact spelling of the Http header. Should it be referer or referrer, and does case matter, etc
To give a demo that also has spelling correction with advice,using TextBlob.
Also all constants will have lower case in calls.
import requests
from textblob import TextBlob
class Url:
def __init__(self, url):
try:
self.req = requests.get(url)
self.server = self.req.headers['Server']
self.date = self.req.headers['Date']
self.user_agent = requests.utils.default_headers()
except requests.exceptions.ConnectionError as e:
print("Wrong domains,chek spelling")
def __getattr__(self, attr):
spell = b = TextBlob(attr)
return f"Name not found,did you mean <{spell.correct()}>"
@property
def header(self):
'''May be needed later'''
pass
@header.setter
def xname(self):
'''May be needed later'''
pass Use:
>>> header = Url('http://python-forum.io')
>>> header.server
'Apache'
>>> # Now miss-spell server
>>> header.srver
'Name not found,did you mean <server>'
>>> header.servery
'Name not found,did you mean <server>'
>>> header.user_agent
{'User-Agent': 'python-requests/2.21.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'} Now just do this with all HTTP headers,and have new library
Posts: 3
Threads: 1
Joined: Jan 2019
Thank you everyone for your comments on this thread.
I have gone ahead and created a library. Your feedback helps https://github.com/kirsn/py-message-headers
|