Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-softlayer for 
openSUSE:Factory checked in at 2026-03-24 18:48:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-softlayer (Old)
 and      /work/SRC/openSUSE:Factory/.python-softlayer.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-softlayer"

Tue Mar 24 18:48:57 2026 rev:26 rq:1342128 version:6.2.8

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-softlayer/python-softlayer.changes        
2025-11-21 16:56:55.642989939 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-softlayer.new.8177/python-softlayer.changes  
    2026-03-24 18:49:52.656953287 +0100
@@ -1,0 +2,7 @@
+Mon Mar 23 23:03:25 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 6.2.8:
+  * Remove unused dependency prettytable
+  * Internal updates
+
+-------------------------------------------------------------------

Old:
----
  v6.2.7.tar.gz

New:
----
  v6.2.8.tar.gz

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

Other differences:
------------------
++++++ python-softlayer.spec ++++++
--- /var/tmp/diff_new_pack.hWDA3o/_old  2026-03-24 18:49:53.216976394 +0100
+++ /var/tmp/diff_new_pack.hWDA3o/_new  2026-03-24 18:49:53.220976559 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-softlayer
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-softlayer
-Version:        6.2.7
+Version:        6.2.8
 Release:        0
 Summary:        A set of Python libraries that assist in calling the SoftLayer 
API
 License:        MIT
@@ -26,12 +26,11 @@
 Source:         
https://github.com/softlayer/softlayer-python/archive/v%{version}.tar.gz
 BuildRequires:  %{python_module click >= 8.0.4}
 BuildRequires:  %{python_module pip}
-BuildRequires:  %{python_module prettytable >= 2.5.0}
 BuildRequires:  %{python_module prompt_toolkit >= 2}
 BuildRequires:  %{python_module pygments >= 2.0.0}
 BuildRequires:  %{python_module pytest}
-BuildRequires:  %{python_module requests >= 2.20.0}
-BuildRequires:  %{python_module rich >= 14.0.0}
+BuildRequires:  %{python_module requests >= 2.32.2}
+BuildRequires:  %{python_module rich >= 14.3.3}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  %{python_module softlayer-zeep >= 5.0.0}
 BuildRequires:  %{python_module testtools}
@@ -40,11 +39,10 @@
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
 Requires:       python-click >= 8.0.4
-Requires:       python-prettytable >= 2.5.0
 Requires:       python-prompt_toolkit >= 2
 Requires:       python-pygments >= 2.0.0
-Requires:       python-requests >= 2.20.0
-Requires:       python-rich >= 12.5.1
+Requires:       python-requests >= 2.32.2
+Requires:       python-rich >= 14.3.3
 Requires:       python-urllib3 >= 1.24
 Suggests:       python-softlayer-zeep >= 5.0.0
 Requires(post): update-alternatives

++++++ v6.2.7.tar.gz -> v6.2.8.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/softlayer-python-6.2.7/README.rst 
new/softlayer-python-6.2.8/README.rst
--- old/softlayer-python-6.2.7/README.rst       2025-06-27 21:31:44.000000000 
+0200
+++ new/softlayer-python-6.2.8/README.rst       2026-03-19 03:24:14.000000000 
+0100
@@ -173,7 +173,6 @@
 
 Python Packages
 ---------------
-* prettytable >= 2.5.0
 * click >= 8.0.4
 * requests >= 2.32.2
 * prompt_toolkit >= 2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/softlayer-python-6.2.7/SoftLayer/API.py 
new/softlayer-python-6.2.8/SoftLayer/API.py
--- old/softlayer-python-6.2.7/SoftLayer/API.py 2025-06-27 21:31:44.000000000 
+0200
+++ new/softlayer-python-6.2.8/SoftLayer/API.py 2026-03-19 03:24:14.000000000 
+0100
@@ -50,6 +50,38 @@
 ))
 
 
+def _build_transport(url, proxy, timeout, user_agent, verify):
+    """Construct the appropriate transport based on the endpoint URL.
+
+    Selects RestTransport when the URL contains '/rest', otherwise falls back
+    to XmlRpcTransport. Extracted to avoid duplicating this logic across
+    ``create_client_from_env``, ``employee_client``, and ``BaseClient``.
+
+    :param str url: The API endpoint URL.
+    :param str proxy: Optional proxy URL.
+    :param timeout: Request timeout in seconds (``None`` means no timeout).
+    :param str user_agent: Optional User-Agent string override.
+    :param verify: SSL verification — ``True``, ``False``, or a path to a CA 
bundle.
+    :returns: A :class:`~SoftLayer.transports.RestTransport` or
+              :class:`~SoftLayer.transports.XmlRpcTransport` instance.
+    """
+    if url is not None and '/rest' in url:
+        return transports.RestTransport(
+            endpoint_url=url,
+            proxy=proxy,
+            timeout=timeout,
+            user_agent=user_agent,
+            verify=verify,
+        )
+    return transports.XmlRpcTransport(
+        endpoint_url=url,
+        proxy=proxy,
+        timeout=timeout,
+        user_agent=user_agent,
+        verify=verify,
+    )
+
+
 def create_client_from_env(username=None,
                            api_key=None,
                            endpoint_url=None,
@@ -62,7 +94,7 @@
                            verify=True):
     """Creates a SoftLayer API client using your environment.
 
-    Settings are loaded via keyword arguments, environemtal variables and
+    Settings are loaded via keyword arguments, environmental variables and
     config file.
 
     :param username: an optional API username if you wish to bypass the
@@ -104,25 +136,13 @@
                                           config_file=config_file)
 
     if transport is None:
-        url = settings.get('endpoint_url')
-        if url is not None and '/rest' in url:
-            # If this looks like a rest endpoint, use the rest transport
-            transport = transports.RestTransport(
-                endpoint_url=settings.get('endpoint_url'),
-                proxy=settings.get('proxy'),
-                timeout=settings.get('timeout'),
-                user_agent=user_agent,
-                verify=verify,
-            )
-        else:
-            # Default the transport to use XMLRPC
-            transport = transports.XmlRpcTransport(
-                endpoint_url=settings.get('endpoint_url'),
-                proxy=settings.get('proxy'),
-                timeout=settings.get('timeout'),
-                user_agent=user_agent,
-                verify=verify,
-            )
+        transport = _build_transport(
+            url=settings.get('endpoint_url'),
+            proxy=settings.get('proxy'),
+            timeout=settings.get('timeout'),
+            user_agent=user_agent,
+            verify=verify,
+        )
 
     # If we have enough information to make an auth driver, let's do it
     if auth is None and settings.get('username') and settings.get('api_key'):
@@ -157,13 +177,13 @@
                     verify=True):
     """Creates an INTERNAL SoftLayer API client using your environment.
 
-    Settings are loaded via keyword arguments, environemtal variables and 
config file.
+    Settings are loaded via keyword arguments, environmental variables and 
config file.
 
     :param username: your user ID
-    :param access_token: hash from 
SoftLayer_User_Employee::performExternalAuthentication(username, password, 
token)
-    :param password: password to use for employee authentication
+    :param access_token: hash from 
SoftLayer_User_Employee::performExternalAuthentication
     :param endpoint_url: the API endpoint base URL you wish to connect to.
-        Set this to API_PRIVATE_ENDPOINT to connect via SoftLayer's private 
network.
+        Must contain 'internal'. Set this to API_PRIVATE_ENDPOINT to connect
+        via SoftLayer's private network.
     :param proxy: proxy to be used to make API calls
     :param integer timeout: timeout for API requests
     :param auth: an object which responds to get_headers() to be inserted into 
the xml-rpc headers.
@@ -173,56 +193,54 @@
         calls if you wish to bypass the packages built in User Agent string
     :param transport: An object that's callable with this signature: 
transport(SoftLayer.transports.Request)
     :param bool verify: decide to verify the server's SSL/TLS cert.
+        DO NOT SET TO FALSE WITHOUT UNDERSTANDING THE IMPLICATIONS.
     """
+    # Pass caller-supplied verify so it is not silently discarded; the config
+    # file value will take precedence if present (via get_client_settings).
     settings = config.get_client_settings(username=username,
                                           api_key=None,
                                           endpoint_url=endpoint_url,
                                           timeout=timeout,
                                           proxy=proxy,
-                                          verify=None,
+                                          verify=verify,
                                           config_file=config_file)
 
     url = settings.get('endpoint_url', '')
-    verify = settings.get('verify', True)
+    # Honour the config-file value; fall back to the caller-supplied default.
+    verify = settings.get('verify', verify)
 
     if 'internal' not in url:
         raise exceptions.SoftLayerError(f"{url} does not look like an Internal 
Employee url.")
 
+    # url is guaranteed non-empty here (the guard above ensures it contains
+    # 'internal'), so no additional None-check is needed.
     if transport is None:
-        if url is not None and '/rest' in url:
-            # If this looks like a rest endpoint, use the rest transport
-            transport = transports.RestTransport(
-                endpoint_url=url,
-                proxy=settings.get('proxy'),
-                timeout=settings.get('timeout'),
-                user_agent=user_agent,
-                verify=verify,
-            )
-        else:
-            # Default the transport to use XMLRPC
-            transport = transports.XmlRpcTransport(
-                endpoint_url=url,
-                proxy=settings.get('proxy'),
-                timeout=settings.get('timeout'),
-                user_agent=user_agent,
-                verify=verify,
-            )
+        transport = _build_transport(
+            url=url,
+            proxy=settings.get('proxy'),
+            timeout=settings.get('timeout'),
+            user_agent=user_agent,
+            verify=verify,
+        )
 
+    # Resolve all settings-derived credentials together before auth selection.
     if access_token is None:
         access_token = settings.get('access_token')
-
     user_id = settings.get('userid')
-    # Assume access_token is valid for now, user has logged in before at least.
-    if settings.get('auth_cert', False):
-        auth = slauth.X509Authentication(settings.get('auth_cert'), verify)
-        return EmployeeClient(auth=auth, transport=transport, 
config_file=config_file)
-    elif access_token and user_id:
-        auth = slauth.EmployeeAuthentication(user_id, access_token)
-        return EmployeeClient(auth=auth, transport=transport, 
config_file=config_file)
-    else:
-        # This is for logging in mostly.
-        LOGGER.info("No access_token or userid found in settings, creating a 
No Auth client for now.")
-        return EmployeeClient(auth=None, transport=transport, 
config_file=config_file)
+
+    # Select the appropriate auth driver only when the caller has not already
+    # supplied one.  A single return keeps construction separate from 
selection.
+    if auth is None:
+        if settings.get('auth_cert'):
+            auth = slauth.X509Authentication(settings.get('auth_cert'), verify)
+        elif access_token and user_id:
+            auth = slauth.EmployeeAuthentication(user_id, access_token)
+        else:
+            # No credentials available — caller must authenticate explicitly
+            # (e.g. via EmployeeClient.authenticate_with_internal).
+            LOGGER.info("No access_token or userid found in settings, creating 
a No Auth client for now.")
+
+    return EmployeeClient(auth=auth, transport=transport, 
config_file=config_file)
 
 
 def Client(**kwargs):
@@ -751,9 +769,7 @@
 
     def call(self, service, method, *args, **kwargs):
         """Handles refreshing Employee tokens in case of a HTTP 401 error"""
-        if (service == 'SoftLayer_Account' or service == 'Account') and not 
kwargs.get('id'):
-            if not self.account_id:
-                raise exceptions.SoftLayerError("SoftLayer_Account service 
requires an ID")
+        if self.account_id and not kwargs.get('id', False):
             kwargs['id'] = self.account_id
 
         try:
@@ -763,6 +779,7 @@
                 userId = self.settings['softlayer'].get('userid')
                 access_token = self.settings['softlayer'].get('access_token')
                 LOGGER.warning("Token has expired, trying to refresh. %s", 
ex.faultString)
+                print("Token has expired, trying to refresh. %s", 
ex.faultString)
                 self.refresh_token(userId, access_token)
                 # Try the Call again this time....
                 return BaseClient.call(self, service, method, *args, **kwargs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/softlayer-python-6.2.7/SoftLayer/CLI/core.py 
new/softlayer-python-6.2.8/SoftLayer/CLI/core.py
--- old/softlayer-python-6.2.7/SoftLayer/CLI/core.py    2025-06-27 
21:31:44.000000000 +0200
+++ new/softlayer-python-6.2.8/SoftLayer/CLI/core.py    2026-03-19 
03:24:14.000000000 +0100
@@ -22,7 +22,7 @@
 from SoftLayer.CLI import formatting
 from SoftLayer import consts
 
-# pylint: disable=too-many-public-methods, broad-except, unused-argument
+# pylint: disable=too-many-public-methods, broad-except, unused-argument, 
invalid-name
 # pylint: disable=redefined-builtin, super-init-not-called, arguments-differ
 
 START_TIME = time.time()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/softlayer-python-6.2.7/SoftLayer/CLI/login.py 
new/softlayer-python-6.2.8/SoftLayer/CLI/login.py
--- old/softlayer-python-6.2.7/SoftLayer/CLI/login.py   2025-06-27 
21:31:44.000000000 +0200
+++ new/softlayer-python-6.2.8/SoftLayer/CLI/login.py   2026-03-19 
03:24:14.000000000 +0100
@@ -17,15 +17,60 @@
 
 
 @click.command(cls=SLCommand)
[email protected]('--session-token',
+              default=None,
+              help='An existing employee session token (hash). Click the "Copy 
Session Token" in the internal portal '
+                   'to get this value.'
+                   'Can also be set via the SLCLI_SESSION_TOKEN environment 
variable.',
+              envvar='SLCLI_SESSION_TOKEN')
[email protected]('--user-id',
+              default=None,
+              type=int,
+              help='Employee IMS ID. The number in the url when you click your 
username in the internal portal, '
+                   'under "user information". Can also be set via the 
SLCLI_USER_ID environment variable. '
+                   'Or read from the configuration file.',
+              envvar='SLCLI_USER_ID')
[email protected]('--legacy',
+              default=False,
+              type=bool,
+              is_flag=True,
+              help='Login with username, password, yubi key combination. Only 
valid if ISV is not required. '
+                   'If using ISV, use your session token.')
 @environment.pass_env
-def cli(env):
+def cli(env, session_token, user_id, legacy):
     """Logs you into the internal SoftLayer Network.
 
     username: Set this in either the softlayer config, or SL_USER ENV variable
     password: Set this in SL_PASSWORD env variable. You will be prompted for 
them otherwise.
+
+    To log in with an existing session token instead of username/password/2FA:
+
+        slcli login --session-token <token> --user-id <id>
+
+    Or via environment variables:
+
+        SLCLI_SESSION_TOKEN=<token> SLCLI_USER_ID=<id> slcli login
     """
     config_settings = config.get_config(config_file=env.config_file)
     settings = config_settings['softlayer']
+
+    if not user_id:
+        user_id = int(settings.get('userid', 0)) or 
int(os.environ.get('SLCLI_USER_ID', 0))
+    # --session-token supplied on the CLI (or via SLCLI_SESSION_TOKEN env var):
+    # authenticate directly, persist to config, and return immediately.
+    if not legacy:
+        if not user_id:
+            user_id = int(input("User ID (number): "))
+        if not session_token:
+            session_token = os.environ.get('SLCLI_SESSION_TOKEN', '') or 
input("Session Token: ")
+        env.client.authenticate_with_hash(user_id, session_token)
+        settings['access_token'] = session_token
+        settings['userid'] = str(user_id)
+        config_settings['softlayer'] = settings
+        config.write_config(config_settings, env.config_file)
+        click.echo(f"Logged in with session token for user ID {user_id}.")
+        return
+
     username = settings.get('username') or os.environ.get('SLCLI_USER', None)
     password = os.environ.get('SLCLI_PASSWORD', '')
     yubi = None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/softlayer-python-6.2.7/SoftLayer/consts.py 
new/softlayer-python-6.2.8/SoftLayer/consts.py
--- old/softlayer-python-6.2.7/SoftLayer/consts.py      2025-06-27 
21:31:44.000000000 +0200
+++ new/softlayer-python-6.2.8/SoftLayer/consts.py      2026-03-19 
03:24:14.000000000 +0100
@@ -5,7 +5,7 @@
 
     :license: MIT, see LICENSE for more details.
 """
-VERSION = 'v6.2.7'
+VERSION = 'v6.2.8'
 API_PUBLIC_ENDPOINT = 'https://api.softlayer.com/xmlrpc/v3.1/'
 API_PRIVATE_ENDPOINT = 'https://api.service.softlayer.com/xmlrpc/v3.1/'
 API_PUBLIC_ENDPOINT_REST = 'https://api.softlayer.com/rest/v3.1/'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/softlayer-python-6.2.7/docs/requirements.txt 
new/softlayer-python-6.2.8/docs/requirements.txt
--- old/softlayer-python-6.2.7/docs/requirements.txt    2025-06-27 
21:31:44.000000000 +0200
+++ new/softlayer-python-6.2.8/docs/requirements.txt    2026-03-19 
03:24:14.000000000 +0100
@@ -1,7 +1,6 @@
-sphinx_rtd_theme==3.0.2
-sphinx==8.2.3
-sphinx-click==6.0.0
+sphinx_rtd_theme==3.1.0
+sphinx==9.1.0
+sphinx-click==6.2.0
 click
-prettytable
 rich
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/softlayer-python-6.2.7/setup.py 
new/softlayer-python-6.2.8/setup.py
--- old/softlayer-python-6.2.7/setup.py 2025-06-27 21:31:44.000000000 +0200
+++ new/softlayer-python-6.2.8/setup.py 2026-03-19 03:24:14.000000000 +0100
@@ -15,7 +15,7 @@
 
 setup(
     name='SoftLayer',
-    version='v6.2.7',
+    version='v6.2.8',
     description=DESCRIPTION,
     long_description=LONG_DESCRIPTION,
     long_description_content_type='text/x-rst',
@@ -32,13 +32,12 @@
     },
     python_requires='>=3.7',
     install_requires=[
-        'prettytable >= 2.5.0',
         'click >= 8.0.4',
         'requests >= 2.32.2',
         'prompt_toolkit >= 2',
         'pygments >= 2.0.0',
         'urllib3 >= 1.24',
-        'rich == 14.0.0'
+        'rich == 14.3.3'
     ],
     keywords=['softlayer', 'cloud', 'slcli', 'ibmcloud'],
     classifiers=[
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/softlayer-python-6.2.7/tests/api_tests.py 
new/softlayer-python-6.2.8/tests/api_tests.py
--- old/softlayer-python-6.2.7/tests/api_tests.py       2025-06-27 
21:31:44.000000000 +0200
+++ new/softlayer-python-6.2.8/tests/api_tests.py       2026-03-19 
03:24:14.000000000 +0100
@@ -389,10 +389,7 @@
     @mock.patch('SoftLayer.API.BaseClient.call')
     def test_account_check(self, _call):
         self.client.transport = self.mocks
-        exception = self.assertRaises(
-            exceptions.SoftLayerError,
-            self.client.call, "SoftLayer_Account", "getObject")
-        self.assertEqual(str(exception), "SoftLayer_Account service requires 
an ID")
+
         self.client.account_id = 1234
         self.client.call("SoftLayer_Account", "getObject")
         self.client.call("SoftLayer_Account", "getObject1", id=9999)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/softlayer-python-6.2.7/tools/requirements.txt 
new/softlayer-python-6.2.8/tools/requirements.txt
--- old/softlayer-python-6.2.7/tools/requirements.txt   2025-06-27 
21:31:44.000000000 +0200
+++ new/softlayer-python-6.2.8/tools/requirements.txt   2026-03-19 
03:24:14.000000000 +0100
@@ -1,9 +1,9 @@
-prettytable >= 2.5.0
-click >= 8.0.4
+
+click == 8.1.8
 requests >= 2.32.2
 prompt_toolkit >= 2
 pygments >= 2.0.0
 urllib3 >= 1.24
-rich == 14.0.0
+rich == 14.3.3
 # only used for soap transport
 # softlayer-zeep >= 5.0.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/softlayer-python-6.2.7/tools/test-requirements.txt 
new/softlayer-python-6.2.8/tools/test-requirements.txt
--- old/softlayer-python-6.2.7/tools/test-requirements.txt      2025-06-27 
21:31:44.000000000 +0200
+++ new/softlayer-python-6.2.8/tools/test-requirements.txt      2026-03-19 
03:24:14.000000000 +0100
@@ -4,8 +4,7 @@
 pytest-cov
 mock
 sphinx
-prettytable >= 2.5.0
-click >= 8.0.4
+click == 8.1.8
 requests >= 2.32.2
 prompt_toolkit >= 2
 pygments >= 2.0.0

Reply via email to