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

External transport discussion #15

Closed
theacodes opened this issue Oct 10, 2016 · 7 comments
Closed

External transport discussion #15

theacodes opened this issue Oct 10, 2016 · 7 comments
Assignees
Labels
discussion 🚨 This issue needs some love. triage me I really want to be triaged.
Milestone

Comments

@theacodes
Copy link
Contributor

theacodes commented Oct 10, 2016

Continuing from #1, we need to figure out the story for use case (2):

It needs to allow users to attach credentials to an HTTP object of their choosing.

The usage of this is external-only. This is the means by which users will make authenticated requests. We want to initially support urllib3, but we should be aware of anything that will cause issues with a requests implementation.

How oauth2client does this

oauth2client only supports httplib2. The way that it accomplishes this is by monkeypatching an existing httplib2.Http object's request method.

  1. The user must construct the http object themselves (this gives them the opportunity to configure settings such as SSL and proxies).
  2. oauth2client modifies the object in place and returns it. The original request method is only available as a closure (via http.request.func_closure[0].cell_contents, which is insanity).

How oauth2client's transport refactor did it.

In the transport refactor, I modified this behavior slightly. Instead of monkeypatching, it wrapped the http object using an AuthedHttp wrapper class that has a common interface with httplib2.Http.

  1. The user still must construct the http object themselves.
  2. oauth2client returns a AuthedHttp wrapper instance that uses the original http object under the covers. The original http object is not modified in any way.

What we could do

We could largely adopt the second method without much heartache, as long a we're still okay with the wrapper pattern:

import google.auth
from google.auth.transport.urllib3 import AuthedHttp
import urllib3

http = urllib3.PoolManager()
credentials, _ = google.auth.default()
authed_http = AuthedHttp(credentials, http)

Similarly with requests:

import google.auth
from google.auth.transport.requests import AuthedSession
import urllib3

session = requests.Session()
credentials, _ = google.auth.default()
authed_session = AuthedSession(credentials, session)

We could also have these items construct their own underlying object using sane defaults if none is specified:

# Creates a PoolManager behind the scenes
authed_http = AuthedHttp(credentials)
# Creates a Session behind the scenes.
authed_session = AuthedSession(credentials)

The only concern I have about this is the long import path (google.auth.transport.urllib3). I can't think of a good, clean way to do something like oauth2client's authorize and I'm not sure that I want to.

Thoughts? Concerns? Alternatives?

@dhermes
Copy link
Contributor

dhermes commented Oct 10, 2016

I like what you've constructed above.

@theacodes
Copy link
Contributor Author

I like what you've constructed above.

Yay!

Any thoughts on this:

The only concern I have about this is the long import path (google.auth.transport.urllib3). I can't think of a good, clean way to do something like oauth2client's authorize and I'm not sure that I want to.

@dhermes
Copy link
Contributor

dhermes commented Oct 10, 2016

Long import paths don't bother me. You can make transport the thing that people import.

@theacodes
Copy link
Contributor Author

You can make transport the thing that people import.

How so? Import all the submodules?

@dhermes
Copy link
Contributor

dhermes commented Oct 10, 2016

Yes.

@jplanza
Copy link

jplanza commented Aug 3, 2017

@jonparrott Is this the expected pattern for people to follow when they need to attach a custom http object to a google.auth.default() request? I'm trying to sort out how to run google-auth through a proxy; using a proxy is a pretty common use case, so if this is the right way to do it, some documentation pointers would be very helpful here:

https://google-auth.readthedocs.io/en/latest/user-guide.html

@theacodes
Copy link
Contributor Author

If you're using a proxy and the requests transport you can just set the standard HTTP_PROXY and HTTPS_PROXY environment variables.

helen-fornazier pushed a commit to helen-fornazier/google-auth-library-python that referenced this issue Apr 20, 2018
Some media download APIs does not support partial downloads and do not
return a 'Content-length' or 'Content-range' header and is therefore
never considered done.

This change is to consider responses where the media length is
unknown to be done.

This commit could potentially break media downloads where the API
supports partial download and only returns a 'Content-length' header
when the entire file has been served/read.

This commit fixes issue googleapis#15
@yoshi-automation yoshi-automation added triage me I really want to be triaged. 🚨 This issue needs some love. labels Apr 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion 🚨 This issue needs some love. triage me I really want to be triaged.
Projects
None yet
Development

No branches or pull requests

6 participants