Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 0.9.22 (2025-10-23)

### Changes

- Add an option for skipping TLS verification.
- Allow redirects for HEAD and POST requests.

## 0.9.21 (2025-10-16)

### Changes
Expand Down
3 changes: 2 additions & 1 deletion bin/mujin_webstackclientpy_applyconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ def _RunMain():
parser.add_argument('--force', action='store_true', dest='force', default=False, help='apply without confirmation [default=%(default)s]')
parser.add_argument('--dryrun', action='store_true', dest='dryrun', default=False, help='shows differences and quit [default=%(default)s]')
parser.add_argument('--oneline', action='store_true', dest='oneline', default=False, help='shows each difference in one line [default=%(default)s]')
parser.add_argument('--tlsSkipVerify', type=bool, default=True, help='Whether to skip TLS verification (default: %(default)s)')
options = parser.parse_args()

# configure logging
Expand All @@ -265,7 +266,7 @@ def _RunMain():

# construct client
if options.controller:
webstackclient = WebstackClient('http://%s' % options.controller, options.username, options.password)
webstackclient = WebstackClient('http://%s' % options.controller, options.username, options.password, tlsSkipVerify=options.tlsSkipVerify)
webstackclient.Ping()
config = webstackclient.GetConfig()
target = webstackclient.controllerIp
Expand Down
3 changes: 2 additions & 1 deletion bin/mujin_webstackclientpy_downloaddata.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def _ParseArguments():
parser.add_argument('--password', type=str, default='mujin', help='Password to login with (default: %(default)s)')
parser.add_argument('--backupSceneFormat', type=str, default=None, help='The scene format to use in backup files, one of "msgpack", "json", or "yaml" (default: %(default)s)')
parser.add_argument('--timeout', type=float, default=600, help='Timeout in seconds (default: %(default)s)')
parser.add_argument('--tlsSkipVerify', type=bool, default=True, help='Whether to skip TLS verification (default: %(default)s)')
return parser.parse_args()


Expand Down Expand Up @@ -92,7 +93,7 @@ def _Main():
options = _ParseArguments()
_ConfigureLogging(options.loglevel)

webClient = _CreateWebstackClient(options.url, options.username, options.password)
webClient = _CreateWebstackClient(options.url, options.username, options.password, tlsSkipVerify=options.tlsSkipVerify)
sceneList = _GetScenes(webClient)
downloadDirectory = _DownloadBackup(webClient, sceneList, options.backupSceneFormat, timeout=options.timeout)
print(downloadDirectory) # other scripts can read stdout and learn the directory path
Expand Down
3 changes: 2 additions & 1 deletion bin/mujin_webstackclientpy_runshell.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def _ParseArguments():
parser.add_argument('--url', type=str, default='http://localhost', help='URL of the controller (default: %(default)s)')
parser.add_argument('--username', type=str, default='mujin', help='Username to login with (default: %(default)s)')
parser.add_argument('--password', type=str, default='mujin', help='Password to login with (default: %(default)s)')
parser.add_argument('--tlsSkipVerify', type=bool, default=True, help='Whether to skip TLS verification (default: %(default)s)')
return parser.parse_args()


Expand All @@ -33,7 +34,7 @@ def _Main():
options = _ParseArguments()
_ConfigureLogging(options.loglevel)

self = WebstackClient(options.url, options.username, options.password)
self = WebstackClient(options.url, options.username, options.password, tlsSkipVerify=options.tlsSkipVerify)

# launch interactive shell
from IPython.terminal import embed
Expand Down
4 changes: 3 additions & 1 deletion python/mujinwebstackclient/controllerwebclientraw.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ def __init__(
userAgent: Optional[str] = None,
additionalHeaders: Optional[Dict[str, str]] = None,
unixEndpoint: Optional[str] = None,
tlsSkipVerify: bool = False,
warnOnUseFromDifferentThreads: bool = False,
) -> None:
self._baseurl = baseurl
Expand All @@ -182,6 +183,7 @@ def __init__(

# Create session
self._session = requests.Session()
self._session.verify = not tlsSkipVerify

# Use basic auth by default, use JWT if available
self._session.auth = JSONWebTokenAuth(self._username, self._password)
Expand Down Expand Up @@ -278,7 +280,7 @@ def Request(

if 'allow_redirects' not in kwargs:
# by default, disallow redirect since DELETE with redirection is too dangerous
kwargs['allow_redirects'] = method in ('GET',)
kwargs['allow_redirects'] = method in ('HEAD', 'GET', 'POST')

if self._threadName is not None:
currentName = threading.current_thread().name
Expand Down
2 changes: 1 addition & 1 deletion python/mujinwebstackclient/version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__version__ = '0.9.21'
__version__ = '0.9.22'

# Do not forget to update CHANGELOG.md
5 changes: 4 additions & 1 deletion python/mujinwebstackclient/webstackclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def offset(self):
_webclient = None
_userinfo = None # A dict storing user info, like locale

controllerurl = '' # URl to controller
controllerurl = '' # URL to controller
controllerusername = '' # Username to login with
controllerpassword = '' # Password to login with

Expand All @@ -128,6 +128,7 @@ def __init__(
userAgent=None,
additionalHeaders=None,
unixEndpoint=None,
tlsSkipVerify: bool = True,
warnOnUseFromDifferentThreads: bool = False,
):
"""Logs into the Mujin controller.
Expand All @@ -139,6 +140,7 @@ def __init__(
userAgent (str): User agent to be sent on each request
additionalHeaders (dict): Additional HTTP headers to be included in requests
unixEndpoint (str): Unix socket endpoint for communicating with HTTP server over unix socket
tlsSkipVerify (bool): Whether to skip TLS verification
warnOnUseFromDifferentThreads (bool): Whether to warn callers if the client is used from different threads.
Defaults to not warning since checking the thread name on each call may significantly degrade performance.
"""
Expand Down Expand Up @@ -175,6 +177,7 @@ def __init__(
userAgent=userAgent,
additionalHeaders=additionalHeaders,
unixEndpoint=unixEndpoint,
tlsSkipVerify=tlsSkipVerify,
warnOnUseFromDifferentThreads=warnOnUseFromDifferentThreads,
)

Expand Down