Hello community,

here is the log from the commit of package python-pydata-google-auth for 
openSUSE:Factory checked in at 2020-07-14 08:00:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pydata-google-auth (Old)
 and      /work/SRC/openSUSE:Factory/.python-pydata-google-auth.new.3060 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pydata-google-auth"

Tue Jul 14 08:00:15 2020 rev:5 rq:820677 version:1.1.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-pydata-google-auth/python-pydata-google-auth.changes
      2020-04-21 13:09:51.628715737 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-pydata-google-auth.new.3060/python-pydata-google-auth.changes
    2020-07-14 08:01:12.210161458 +0200
@@ -1,0 +2,10 @@
+Mon Jul 13 10:16:25 UTC 2020 - Marketa Calabkova <[email protected]>
+
+- Update to 1.1.0
+  * Try a range of ports between 8080 and 8090 when ``use_local_webserver`` is
+    ``True``. (:issue:`35`)
+  * Mark package as 1.0, generally available.
+  * Update introduction with link to instructions on creating a Google Cloud
+    project. (:issue:`18`)
+
+-------------------------------------------------------------------

Old:
----
  pydata-google-auth-0.3.0.tar.gz

New:
----
  pydata-google-auth-1.1.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pydata-google-auth.spec ++++++
--- /var/tmp/diff_new_pack.L250rW/_old  2020-07-14 08:01:14.178167830 +0200
+++ /var/tmp/diff_new_pack.L250rW/_new  2020-07-14 08:01:14.178167830 +0200
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %bcond_without python2
 Name:           python-pydata-google-auth
-Version:        0.3.0
+Version:        1.1.0
 Release:        0
 Summary:        PyData helpers for authenticating to Google APIs
 License:        BSD-3-Clause

++++++ pydata-google-auth-0.3.0.tar.gz -> pydata-google-auth-1.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydata-google-auth-0.3.0/docs/source/changelog.rst 
new/pydata-google-auth-1.1.0/docs/source/changelog.rst
--- old/pydata-google-auth-0.3.0/docs/source/changelog.rst      2020-02-04 
19:38:01.000000000 +0100
+++ new/pydata-google-auth-1.1.0/docs/source/changelog.rst      2020-04-23 
16:27:51.000000000 +0200
@@ -1,6 +1,23 @@
 Changelog
 =========
 
+.. _changelog-1.1.0:
+
+1.1.0 / (2020-04-23)
+--------------------
+
+- Try a range of ports between 8080 and 8090 when ``use_local_webserver`` is
+  ``True``. (:issue:`35`)
+
+.. _changelog-1.0.0:
+
+1.0.0 / (2020-04-20)
+--------------------
+
+- Mark package as 1.0, generally available.
+- Update introduction with link to instructions on creating a Google Cloud
+  project. (:issue:`18`)
+
 .. _changelog-0.3.0:
 
 0.3.0 / (2020-02-04)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydata-google-auth-0.3.0/docs/source/index.rst 
new/pydata-google-auth-1.1.0/docs/source/index.rst
--- old/pydata-google-auth-0.3.0/docs/source/index.rst  2020-02-04 
19:38:01.000000000 +0100
+++ new/pydata-google-auth-1.1.0/docs/source/index.rst  2020-04-23 
16:27:51.000000000 +0200
@@ -9,12 +9,6 @@
 The :mod:`pydata_google_auth` module provides a wrapper to authenticate to
 Google APIs, such as Google BigQuery.
 
-.. warning::
-
-   To use this module, you will need a valid BigQuery account. Refer to the
-   `BigQuery Documentation 
<https://cloud.google.com/bigquery/what-is-bigquery>`__
-   for details on the service itself.
-
 Contents:
 
 .. toctree::
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydata-google-auth-0.3.0/docs/source/install.rst 
new/pydata-google-auth-1.1.0/docs/source/install.rst
--- old/pydata-google-auth-0.3.0/docs/source/install.rst        2020-02-04 
19:38:01.000000000 +0100
+++ new/pydata-google-auth-1.1.0/docs/source/install.rst        2020-04-23 
16:27:51.000000000 +0200
@@ -37,5 +37,5 @@
 
 This module requires following additional dependencies:
 
-- `google-auth 
<https://github.com/GoogleCloudPlatform/google-auth-library-python>`__: 
authentication and authorization for Google's API
-- `google-auth-oauthlib 
<https://github.com/GoogleCloudPlatform/google-auth-library-python-oauthlib>`__:
 integration with `oauthlib <https://github.com/idan/oauthlib>`__ for end-user 
authentication
+- `google-auth <https://github.com/googleapis/google-auth-library-python>`__: 
authentication and authorization for Google's API
+- `google-auth-oauthlib 
<https://github.com/googleapis/google-auth-library-python-oauthlib>`__: 
integration with `oauthlib <https://github.com/idan/oauthlib>`__ for end-user 
authentication
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydata-google-auth-0.3.0/docs/source/intro.rst 
new/pydata-google-auth-1.1.0/docs/source/intro.rst
--- old/pydata-google-auth-0.3.0/docs/source/intro.rst  2020-02-04 
19:38:01.000000000 +0100
+++ new/pydata-google-auth-1.1.0/docs/source/intro.rst  2020-04-23 
16:27:51.000000000 +0200
@@ -7,6 +7,13 @@
 to get and cache user credentials for accessing the Google APIs from
 locally-installed data tools and libraries.
 
+.. warning::
+
+   To use this module, you will need a Google account and developer project.
+   Follow the `Using the BigQuery sandbox
+   <https://cloud.google.com/bigquery/docs/sandbox>`_ instructions to get
+   started with big data on Google Cloud without a credit card.
+
 See the `Google Cloud Platform authentication guide
 <https://cloud.google.com/docs/authentication/>`_ for best practices on
 authentication in production server contexts.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydata-google-auth-0.3.0/noxfile.py 
new/pydata-google-auth-1.1.0/noxfile.py
--- old/pydata-google-auth-0.3.0/noxfile.py     2020-02-04 19:38:01.000000000 
+0100
+++ new/pydata-google-auth-1.1.0/noxfile.py     2020-04-23 16:27:51.000000000 
+0200
@@ -10,8 +10,8 @@
 import nox
 
 
-latest_python = "3.7"
-python_versions = ["2.7", "3.5", "3.6", "3.7"]
+latest_python = "3.8"
+python_versions = ["2.7", "3.5", "3.6", "3.7", "3.8"]
 
 
 @nox.session(python=latest_python)
@@ -56,7 +56,7 @@
 @nox.session(python=latest_python)
 def cover(session):
     session.install("coverage", "pytest-cov")
-    session.run("coverage", "report", "--show-missing", "--fail-under=40")
+    session.run("coverage", "report", "--show-missing", "--fail-under=50")
     session.run("coverage", "erase")
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pydata-google-auth-0.3.0/pydata_google_auth/__main__.py 
new/pydata-google-auth-1.1.0/pydata_google_auth/__main__.py
--- old/pydata-google-auth-0.3.0/pydata_google_auth/__main__.py 2020-02-04 
19:38:01.000000000 +0100
+++ new/pydata-google-auth-1.1.0/pydata_google_auth/__main__.py 2020-04-23 
16:27:51.000000000 +0200
@@ -31,8 +31,9 @@
 )
 LOGIN_USE_LOCAL_WEBSERVER_HELP = (
     "Use a local webserver for the user authentication. This starts "
-    "a webserver on localhost, which allows the browser to pass a token "
-    "directly to the program."
+    "a webserver on localhost with a port between 8080 and 8089, "
+    "inclusive, which allows the browser to pass a token directly to the "
+    "program."
 )
 
 PRINT_TOKEN_HELP = "Load a credentials JSON file and print an access token."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pydata-google-auth-0.3.0/pydata_google_auth/_version.py 
new/pydata-google-auth-1.1.0/pydata_google_auth/_version.py
--- old/pydata-google-auth-0.3.0/pydata_google_auth/_version.py 2020-02-04 
19:38:01.000000000 +0100
+++ new/pydata-google-auth-1.1.0/pydata_google_auth/_version.py 2020-04-23 
16:27:51.000000000 +0200
@@ -22,9 +22,9 @@
     # setup.py/versioneer.py will grep for the variable names, so they must
     # each be defined on a line of their own. _version.py will just call
     # get_keywords().
-    git_refnames = " (HEAD -> master, tag: 0.3.0)"
-    git_full = "dc6ce92e4d243d5aec635faa91c6feeb4ac6c822"
-    git_date = "2020-02-04 12:38:01 -0600"
+    git_refnames = " (tag: 1.1.0)"
+    git_full = "c224a80372d17ab1e803c9dfc6a2ffc282d0dc49"
+    git_date = "2020-04-23 09:27:51 -0500"
     keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
     return keywords
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pydata-google-auth-0.3.0/pydata_google_auth/_webserver.py 
new/pydata-google-auth-1.1.0/pydata_google_auth/_webserver.py
--- old/pydata-google-auth-0.3.0/pydata_google_auth/_webserver.py       
1970-01-01 01:00:00.000000000 +0100
+++ new/pydata-google-auth-1.1.0/pydata_google_auth/_webserver.py       
2020-04-23 16:27:51.000000000 +0200
@@ -0,0 +1,89 @@
+"""Helpers for running a local webserver to receive authorization code."""
+
+import socket
+from contextlib import closing
+
+from pydata_google_auth import exceptions
+
+
+LOCALHOST = "localhost"
+DEFAULT_PORTS_TO_TRY = 100
+
+
+def is_port_open(port):
+    """Check if a port is open on localhost.
+
+    Based on StackOverflow answer: https://stackoverflow.com/a/43238489/101923
+
+    Parameters
+    ----------
+    port : int
+        A port to check on localhost.
+
+    Returns
+    -------
+    is_open : bool
+        True if a socket can be opened at the requested port.
+    """
+    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
+        try:
+            sock.bind((LOCALHOST, port))
+            sock.listen(1)
+        except socket.error:
+            is_open = False
+        else:
+            is_open = True
+    return is_open
+
+
+def find_open_port(start=8080, stop=None):
+    """Find an open port between ``start`` and ``stop``.
+
+    Parameters
+    ----------
+    start : Optional[int]
+        Beginning of range of ports to try. Defaults to 8080.
+    stop : Optional[int]
+        End of range of ports to try (not including exactly equals ``stop``).
+        This function tries 100 possible ports if no ``stop`` is specified.
+
+    Returns
+    -------
+    Optional[int]
+        ``None`` if no open port is found, otherwise an integer indicating an
+        open port.
+    """
+    if not stop:
+        stop = start + DEFAULT_PORTS_TO_TRY
+
+    for port in range(start, stop):
+        if is_port_open(port):
+            return port
+
+    # No open ports found.
+    return None
+
+
+def run_local_server(app_flow):
+    """Run local webserver installed app flow on some open port.
+
+    Parameters
+    ----------
+    app_flow : google_auth_oauthlib.flow.InstalledAppFlow
+        Installed application flow to fetch user credentials.
+
+    Returns
+    -------
+    google.auth.credentials.Credentials
+        User credentials from installed application flow.
+
+    Raises
+    ------
+    pydata_google_auth.exceptions.PyDataConnectionError
+        If no open port can be found in the range from 8080 to 8089,
+        inclusive.
+    """
+    port = find_open_port()
+    if not port:
+        raise exceptions.PyDataConnectionError("Could not find open port.")
+    return app_flow.run_local_server(host=LOCALHOST, port=port)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydata-google-auth-0.3.0/pydata_google_auth/auth.py 
new/pydata-google-auth-1.1.0/pydata_google_auth/auth.py
--- old/pydata-google-auth-0.3.0/pydata_google_auth/auth.py     2020-02-04 
19:38:01.000000000 +0100
+++ new/pydata-google-auth-1.1.0/pydata_google_auth/auth.py     2020-04-23 
16:27:51.000000000 +0200
@@ -11,6 +11,7 @@
 
 from pydata_google_auth import exceptions
 from pydata_google_auth import cache
+from pydata_google_auth import _webserver
 
 
 logger = logging.getLogger(__name__)
@@ -69,7 +70,9 @@
         Windows.
     use_local_webserver : bool, optional
         Use a local webserver for the user authentication
-        :class:`google_auth_oauthlib.flow.InstalledAppFlow`. Defaults to
+        :class:`google_auth_oauthlib.flow.InstalledAppFlow`. Binds a
+        webserver to an open port on ``localhost`` between 8080 and 8089,
+        inclusive, to receive authentication token. If not set, defaults to
         ``False``, which requests a token via the console.
     auth_local_webserver : deprecated
         Use the ``use_local_webserver`` parameter instead.
@@ -210,7 +213,9 @@
         Windows.
     use_local_webserver : bool, optional
         Use a local webserver for the user authentication
-        :class:`google_auth_oauthlib.flow.InstalledAppFlow`. Defaults to
+        :class:`google_auth_oauthlib.flow.InstalledAppFlow`. Binds a
+        webserver to an open port on ``localhost`` between 8080 and 8089,
+        inclusive, to receive authentication token. If not set, defaults to
         ``False``, which requests a token via the console.
     auth_local_webserver : deprecated
         Use the ``use_local_webserver`` parameter instead.
@@ -256,7 +261,7 @@
 
         try:
             if use_local_webserver:
-                credentials = app_flow.run_local_server()
+                credentials = _webserver.run_local_server(app_flow)
             else:
                 credentials = app_flow.run_console()
         except oauthlib.oauth2.rfc6749.errors.OAuth2Error as exc:
@@ -310,7 +315,9 @@
         client's identity when using Google APIs.
     use_local_webserver : bool, optional
         Use a local webserver for the user authentication
-        :class:`google_auth_oauthlib.flow.InstalledAppFlow`. Defaults to
+        :class:`google_auth_oauthlib.flow.InstalledAppFlow`. Binds a
+        webserver to an open port on ``localhost`` between 8080 and 8089,
+        inclusive, to receive authentication token. If not set, defaults to
         ``False``, which requests a token via the console.
 
     Returns
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pydata-google-auth-0.3.0/pydata_google_auth/exceptions.py 
new/pydata-google-auth-1.1.0/pydata_google_auth/exceptions.py
--- old/pydata-google-auth-0.3.0/pydata_google_auth/exceptions.py       
2020-02-04 19:38:01.000000000 +0100
+++ new/pydata-google-auth-1.1.0/pydata_google_auth/exceptions.py       
2020-04-23 16:27:51.000000000 +0200
@@ -2,3 +2,9 @@
     """
     Raised when invalid credentials are provided, or tokens have expired.
     """
+
+
+class PyDataConnectionError(RuntimeError):
+    """
+    Raised when unable to fetch credentials due to connection error.
+    """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydata-google-auth-0.3.0/setup.py 
new/pydata-google-auth-1.1.0/setup.py
--- old/pydata-google-auth-0.3.0/setup.py       2020-02-04 19:38:01.000000000 
+0100
+++ new/pydata-google-auth-1.1.0/setup.py       2020-04-23 16:27:51.000000000 
+0200
@@ -29,7 +29,7 @@
     author_email="[email protected]",
     url="https://github.com/pydata/pydata-google-auth";,
     classifiers=[
-        "Development Status :: 4 - Beta",
+        "Development Status :: 5 - Production/Stable",
         "Environment :: Console",
         "Intended Audience :: Science/Research",
         "Operating System :: OS Independent",
@@ -40,6 +40,7 @@
         "Programming Language :: Python :: 3.5",
         "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
+        "Programming Language :: Python :: 3.8",
         "Topic :: Scientific/Engineering",
         "License :: OSI Approved :: BSD License",
     ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pydata-google-auth-0.3.0/tests/unit/test_webserver.py 
new/pydata-google-auth-1.1.0/tests/unit/test_webserver.py
--- old/pydata-google-auth-0.3.0/tests/unit/test_webserver.py   1970-01-01 
01:00:00.000000000 +0100
+++ new/pydata-google-auth-1.1.0/tests/unit/test_webserver.py   2020-04-23 
16:27:51.000000000 +0200
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+
+import socket
+
+try:
+    from unittest import mock
+except ImportError:  # pragma: NO COVER
+    import mock
+
+import google_auth_oauthlib.flow
+import pytest
+
+from pydata_google_auth import exceptions
+
+
[email protected]
+def module_under_test():
+    from pydata_google_auth import _webserver
+
+    return _webserver
+
+
+def test_find_open_port_finds_start_port(monkeypatch, module_under_test):
+    monkeypatch.setattr(socket, "socket", mock.create_autospec(socket.socket))
+    port = module_under_test.find_open_port(9999)
+    assert port == 9999
+
+
+def test_find_open_port_finds_stop_port(monkeypatch, module_under_test):
+    socket_instance = mock.create_autospec(socket.socket, instance=True)
+
+    def mock_socket(family, type_):
+        return socket_instance
+
+    monkeypatch.setattr(socket, "socket", mock_socket)
+    socket_instance.listen.side_effect = [socket.error] * 99 + [None]
+    port = module_under_test.find_open_port(9000, stop=9100)
+    assert port == 9099
+
+
+def test_find_open_port_returns_none(monkeypatch, module_under_test):
+    socket_instance = mock.create_autospec(socket.socket, instance=True)
+
+    def mock_socket(family, type_):
+        return socket_instance
+
+    monkeypatch.setattr(socket, "socket", mock_socket)
+    socket_instance.listen.side_effect = socket.error
+    port = module_under_test.find_open_port(9000)
+    assert port is None
+    socket_instance.listen.assert_has_calls(mock.call(1) for _ in range(100))
+
+
+def test_run_local_server_calls_flow(monkeypatch, module_under_test):
+    mock_flow = mock.create_autospec(
+        google_auth_oauthlib.flow.InstalledAppFlow, instance=True
+    )
+    module_under_test.run_local_server(mock_flow)
+    mock_flow.run_local_server.assert_called_once_with(host="localhost", 
port=8080)
+
+
+def test_run_local_server_raises_connectionerror(monkeypatch, 
module_under_test):
+    def mock_find_open_port():
+        return None
+
+    monkeypatch.setattr(module_under_test, "find_open_port", 
mock_find_open_port)
+    mock_flow = mock.create_autospec(
+        google_auth_oauthlib.flow.InstalledAppFlow, instance=True
+    )
+
+    with pytest.raises(exceptions.PyDataConnectionError):
+        module_under_test.run_local_server(mock_flow)
+
+    mock_flow.run_local_server.assert_not_called()


Reply via email to