Skip to content
This repository was archived by the owner on Mar 6, 2026. It is now read-only.

Add InstalledAppFlow#128

Merged
theacodes merged 7 commits intomasterfrom
installed-flow
Mar 22, 2017
Merged

Add InstalledAppFlow#128
theacodes merged 7 commits intomasterfrom
installed-flow

Conversation

@theacodes
Copy link
Copy Markdown
Contributor

Resolves #122

@theacodes
Copy link
Copy Markdown
Contributor Author

This is DO NOT MERGE because I want a sanity check before I go any further.

  1. What do you think about this being in the library in general?
  2. What do you think about the way the implementation is structured?

Specifically for (2), I had some thoughts that it might make more sense to separate the strategies into separate classes:

flow = google.oauth2.flow.InstalledAppFlow.from_client_secrets_file(...)

strategy = flow.ServerStrategy(port=9000)
# or
strategy = flow.ConsoleStrategy()

flow.run(strategy)
# or
flow.strategy = strategy
flow.run()

But I'm unsure if that's over-engineering, even if it feels cleaner.

@theacodes
Copy link
Copy Markdown
Contributor Author

/cc @proppy

@lukesneeringer
Copy link
Copy Markdown

Can you provide some sample code for what it looks like with a single, combined flow? It would make it easier to reason about without doing a deep dive.

@theacodes
Copy link
Copy Markdown
Contributor Author

@lukesneeringer not sure what you're asking for.

@lukesneeringer
Copy link
Copy Markdown

@lukesneeringer not sure what you're asking for.

I was referring to (2) specifically.

Right now it seems to be:

flow = InstalledAppFlow(...)
flow.run(strategy=SERVER, port=9000)

I think that is fine. I do not think strategy objects are necessary. And it does seem reasonable that some arguments (like port) are ignored if they are not applicable to the strategy in use.

@theacodes
Copy link
Copy Markdown
Contributor Author

@lukesneeringer that's nearly correct, it would be:

flow = InstalledAppFlow(...)
flow.web_port = 9000
flow.run(strategy=SERVER)

I can keep that same interface but separate the internals into two separate strategy classes. Curious as to what @dhermes thinks as well.

@lukesneeringer
Copy link
Copy Markdown

lukesneeringer commented Mar 2, 2017

That makes a little less sense to me, but it certainly seems good enough. And it is probably better than making the user create a strategy object.

@theacodes
Copy link
Copy Markdown
Contributor Author

That makes a little less sense to me

It makes more sense to pass into run then we can do that. There's plenty of malleability here.

Another option is to have two runs: run_console and run_server.

@lukesneeringer
Copy link
Copy Markdown

Oooh, I think run_console and run_server taking the appropriate arguments is a good approach.

@theacodes
Copy link
Copy Markdown
Contributor Author

Oooh, I think run_console and run_server taking the appropriate arguments is a good approach.

Cool, that's what I'll go with. I'll remove run and just have run_server and run_console.

@theacodes theacodes changed the title [DO NOT MERGE] Add InstalledAppFlow Add InstalledAppFlow Mar 16, 2017
@theacodes
Copy link
Copy Markdown
Contributor Author

@dhermes @lukesneeringer this is ready for review. :)

@theacodes
Copy link
Copy Markdown
Contributor Author

@proppy it would be super cool if you took a look as well.


.. warning::
This module is experimental and is subject to change signficantly
This module is experimental and is subject to change significantly

This comment was marked as spam.


import json
import logging
import webbrowser

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

import google.oauth2.oauthlib


_LOGGER = logging.getLogger(__name__)

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.


import google.oauth2.flow

flow = google.oauth2.flow.InstalledAppFlow.from_client_secrets_file(

This comment was marked as spam.

This comment was marked as spam.

"""
kwargs.setdefault('prompt', 'consent')

self.redirect_uri = self._OOB_REDIRECT_URI

This comment was marked as spam.

This comment was marked as spam.


auth_url, _ = self.authorization_url(**kwargs)

print(authorization_prompt_message.format(url=auth_url))

This comment was marked as spam.

This comment was marked as spam.

code is then exchanged for a token.

Args:
host (str): The web host for the local redirect server.

This comment was marked as spam.

This comment was marked as spam.


return self.credentials

class _LocalRedirectServer(BaseHTTPServer.HTTPServer):

This comment was marked as spam.

This comment was marked as spam.

long_description=long_description,
url='https://github.com/GoogleCloudPlatform/google-auth-library-python',
packages=find_packages(exclude=('tests', 'system_tests')),
packages=find_packages(exclude=('tests*', 'system_tests*')),

This comment was marked as spam.

This comment was marked as spam.

local_server = self._LocalRedirectServer(
success_message, (host, port), self._LocalRedirectRequestHandler)

webbrowser.open(auth_url, new=1, autoraise=True)

This comment was marked as spam.

This comment was marked as spam.

self.success_message = success_message
self.last_request_path = None

class _LocalRedirectRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):

This comment was marked as spam.

This comment was marked as spam.

@proppy
Copy link
Copy Markdown

proppy commented Mar 17, 2017

do we want a "smart" run that fallback to run_console if opening the browser failed?

@theacodes
Copy link
Copy Markdown
Contributor Author

do we want a "smart" run that fallback to run_console if opening the browser failed?

Webbrowser doesn't give us any indication if the open call was successful or not.

@theacodes
Copy link
Copy Markdown
Contributor Author

@dhermes @lukesneeringer should be good to review again.

Copy link
Copy Markdown
Contributor

@dhermes dhermes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM I think?


import json
import logging
import webbrowser

This comment was marked as spam.

import google.oauth2.oauthlib


_LOGGER = logging.getLogger(__name__)

This comment was marked as spam.

@theacodes
Copy link
Copy Markdown
Contributor Author

I meant "having this code period"

The good news is that it's in a separate package now, woohoo. :)

@theacodes theacodes merged commit 41a2bba into master Mar 22, 2017
@theacodes theacodes deleted the installed-flow branch March 22, 2017 20:43

auth_url, _ = self.authorization_url(**kwargs)

print(authorization_prompt_message.format(url=auth_url))

This comment was marked as spam.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants