@_helpers.positional(<NUM_LIT:3>)<EOL>def run_flow(flow, storage, flags=None, http=None):
if flags is None:<EOL><INDENT>flags = argparser.parse_args()<EOL><DEDENT>logging.getLogger().setLevel(getattr(logging, flags.logging_level))<EOL>if not flags.noauth_local_webserver:<EOL><INDENT>success = False<EOL>port_number = <NUM_LIT:0><EOL>for port in flags.auth_host_port:<EOL><INDENT>port_number = port<EOL>try:<EOL><INDENT>httpd = ClientRedirectServer((flags.auth_host_name, port),<EOL>ClientRedirectHandler)<EOL><DEDENT>except socket.error:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>success = True<EOL>break<EOL><DEDENT><DEDENT>flags.noauth_local_webserver = not success<EOL>if not success:<EOL><INDENT>print(_FAILED_START_MESSAGE)<EOL><DEDENT><DEDENT>if not flags.noauth_local_webserver:<EOL><INDENT>oauth_callback = '<STR_LIT>'.format(<EOL>host=flags.auth_host_name, port=port_number)<EOL><DEDENT>else:<EOL><INDENT>oauth_callback = client.OOB_CALLBACK_URN<EOL><DEDENT>flow.redirect_uri = oauth_callback<EOL>authorize_url = flow.step1_get_authorize_url()<EOL>if not flags.noauth_local_webserver:<EOL><INDENT>import webbrowser<EOL>webbrowser.open(authorize_url, new=<NUM_LIT:1>, autoraise=True)<EOL>print(_BROWSER_OPENED_MESSAGE.format(address=authorize_url))<EOL><DEDENT>else:<EOL><INDENT>print(_GO_TO_LINK_MESSAGE.format(address=authorize_url))<EOL><DEDENT>code = None<EOL>if not flags.noauth_local_webserver:<EOL><INDENT>httpd.handle_request()<EOL>if '<STR_LIT:error>' in httpd.query_params:<EOL><INDENT>sys.exit('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT:code>' in httpd.query_params:<EOL><INDENT>code = httpd.query_params['<STR_LIT:code>']<EOL><DEDENT>else:<EOL><INDENT>print('<STR_LIT>'<EOL>'<STR_LIT>')<EOL>sys.exit('<STR_LIT>')<EOL><DEDENT><DEDENT>else:<EOL><INDENT>code = input('<STR_LIT>').strip()<EOL><DEDENT>try:<EOL><INDENT>credential = flow.step2_exchange(code, http=http)<EOL><DEDENT>except client.FlowExchangeError as e:<EOL><INDENT>sys.exit('<STR_LIT>'.format(e))<EOL><DEDENT>storage.put(credential)<EOL>credential.set_store(storage)<EOL>print('<STR_LIT>')<EOL>return credential<EOL>
Core code for a command-line application.

    The ``run()`` function is called from your application and runs
    through all the steps to obtain credentials. It takes a ``Flow``
    argument and attempts to open an authorization server page in the
    user's default web browser. The server asks the user to grant your
    application access to the user's data. If the user grants access,
    the ``run()`` function returns new credentials. The new credentials
    are also stored in the ``storage`` argument, which updates the file
    associated with the ``Storage`` object.

    It presumes it is run from a command-line application and supports the
    following flags:

        ``--auth_host_name`` (string, default: ``localhost``)
           Host name to use when running a local web server to handle
           redirects during OAuth authorization.

        ``--auth_host_port`` (integer, default: ``[8080, 8090]``)
           Port to use when running a local web server to handle redirects
           during OAuth authorization. Repeat this option to specify a list
           of values.

        ``--[no]auth_local_webserver`` (boolean, default: ``True``)
           Run a local web server to handle redirects during OAuth
           authorization.

    The tools module defines an ``ArgumentParser`` the already contains the
    flag definitions that ``run()`` requires. You can pass that
    ``ArgumentParser`` to your ``ArgumentParser`` constructor::

        parser = argparse.ArgumentParser(
            description=__doc__,
            formatter_class=argparse.RawDescriptionHelpFormatter,
            parents=[tools.argparser])
        flags = parser.parse_args(argv)

    Args:
        flow: Flow, an OAuth 2.0 Flow to step through.
        storage: Storage, a ``Storage`` to store the credential in.
        flags: ``argparse.Namespace``, (Optional) The command-line flags. This
               is the object returned from calling ``parse_args()`` on
               ``argparse.ArgumentParser`` as described above. Defaults
               to ``argparser.parse_args()``.
        http: An instance of ``httplib2.Http.request`` or something that
              acts like it.

    Returns:
        Credentials, the obtained credential.