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