Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

prepared URL API #2516

Open
x0zzz opened this issue Nov 13, 2017 · 6 comments
Open

prepared URL API #2516

x0zzz opened this issue Nov 13, 2017 · 6 comments

Comments

@x0zzz
Copy link

x0zzz commented Nov 13, 2017

Is there a way to get prepared URL, which will be used in a query? Something like:

req = ClientSession().Request(method='GET', url='http://path.org', data={'a':1, 'b':2})
url = req.prepared_url() -> 'http://path.org?a=1&b=2'
req.headers.update({'auth': auth_fun(url)})

I need this for authentication purposes.
Till now I used requests.Request.prepare().path_url for the URL and yet sent aiohttp request, but I just found out that sometimes the argument ordering in the output URL will differ between the libraries. Nasty bug.

My first reflex was to try with ClientRequest but it requries YARL's URL object (I think?), which is doable I guess, but maybe there's something short and sweet already available.

Can you please help me out?

@asvetlov asvetlov added this to the 3.0 milestone Nov 17, 2017
@asvetlov
Copy link
Member

We have no such functionality yet but not maybe we need to invite something.

@kxepal
Copy link
Member

kxepal commented Nov 17, 2017

Isn't yarl about this? IIRC, it's possible to pass yarl.URL instance as url to request object.

@asvetlov
Copy link
Member

Yes, sure.
requests.PreparedRequest contains headers also.
Not sure if we need it though.

@asvetlov asvetlov modified the milestones: 3.0, 3.1 Feb 9, 2018
@asvetlov asvetlov modified the milestones: 3.1, 3.2 Mar 22, 2018
@asvetlov asvetlov modified the milestones: 3.2, 3.3 May 7, 2018
@asvetlov asvetlov modified the milestones: 3.3, 3.5 Oct 18, 2018
@mjpieters
Copy link
Contributor

The use-case I'd use this for HMAC signing the HTTP request for API authentication purposes. Some APIs require that you provide an HMAC signature that's based on a combination of body, URL and headers. The signature is then added to the request (as a another header, URL parameter or extra element in the post body).

See https://stackoverflow.com/questions/42100488/how-do-i-sign-a-post-request-using-hmac-sha512-and-the-python-requests-library for an example of HMAC request signing based on the post body, with the signature placed in the header.

@ndhansen
Copy link

@asvetlov I thought I'd take a look at this, but I realised it isn't as easy a fix as I'd hoped.
If I understood the source code correctly, when you create a request (such as in the example above):
req = ClientSession().request(method='GET', url='http://path.org', data={'a':1, 'b':2})
.request() directly calls ClientSession._request(), which connects to the server. So unless there's a prepared request, you'd only be able to retroactively get the resolved url from the response, not the request itself.

Have I missunderstood the problem? If so, where would you be able to implement this functionality? If not, is there any intention of adding a prepared request feature such as requests PreparedRequests?

@Dreamsorcerer
Copy link
Member

I feel like there's maybe something you could already do with a custom request class, like maybe:

class MyRequest(ClientRequest):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Add some auth header here.

This might also have the advantage of making the auth process automatic and encapsulated in this class, avoiding any need to change the way requests are made.

Otherwise, maybe you can move the code which creates this to another location in the client so it can be retrieved more easily:
https://github.com/aio-libs/aiohttp/blob/master/aiohttp/client.py#L451

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants