Skip to content
Browse files

Convert build downloading to use SideFX Web API.

Convert to using 3rd party code for styled outputs.

Reoranize some code used only by the wrapper.
  • Loading branch information...
captainhammy committed Jul 21, 2019
1 parent a596ae2 commit 4fa2dd7c287ede7c8e3c44b69c900e4640575419
@@ -1,4 +1,4 @@
#!/usr/bin/env python
"""Launch Houdini related applications."""

# =============================================================================
@@ -8,14 +8,14 @@
# Python Imports
import os
import signal
import six
import subprocess
import sys
from termcolor import colored, cprint

# Houdini Toolbox Imports
import ht.argument
import ht.houdini.package
import ht.output
import ht.utils
import ht.houdini.argparser

# =============================================================================
@@ -39,12 +39,12 @@ def _build_parser():
"""Build an ArgumentParser for the wrapper.
:return: The wrapper argument parser.
:rtype: ht.argument.ArgumentParser
:rtype: ht.houdini.argparser.ArgumentParser
# Don't allow abbreviations since we don't want them to interfere with any
# flags that might need to be passed through.
parser = ht.argument.ArgumentParser(
parser = ht.houdini.argparser.ArgumentParser(
description="Run Houdini related applications.",
@@ -128,23 +128,23 @@ def _display_versions(arguments):

# List builds that can be installed.
if arguments.install:
_print("Houdini builds to install:")
six.print_("Houdini builds to install:")

'\t' + " ".join(
[str(build) for build in manager.installable]


# Builds that can be ran can also be uninstalled.
if arguments.uninstall:
_print("Houdini builds to uninstall:")
six.print_("Houdini builds to uninstall:")

_print("Installed Houdini builds:")
six.print_("Installed Houdini builds:")

default_build = manager.get_default_build()

@@ -153,16 +153,16 @@ def _display_versions(arguments):
for build in manager.installed:
if build == default_build:
# Run the message through the style function.
msg =
msg = colored(str(build), "cyan")



_print('\t' + ' '.join(output))
six.print_('\t' + ' '.join(output))


def _download_and_install(arguments):
@@ -180,8 +180,7 @@ def _download_and_install(arguments):

def _find_build(arguments):
"""Search for the selected build. If no valid build was selected
print a message.
"""Search for the selected build. If no valid build was selected print a message.
:param arguments: The wrapper args.
:type arguments: argparse.Namespace
@@ -209,13 +208,13 @@ def _find_build(arguments):
# Couldn't find any builds, so print the appropriate message.
if not search_builds:
if arguments.install:
_print("No builds found to install.")
six.print_("No builds found to install.")

elif arguments.uninstall:
_print("No builds found to uninstall.")
six.print_("No builds found to uninstall.")

_print("No builds found.")
six.print_("No builds found.")

return None

@@ -234,7 +233,7 @@ def _find_build(arguments):
result = ht.houdini.package.find_matching_builds(version, search_builds)

if result is None:
_print("Could not find version: {ver}".format(ver=version))
six.print_("Could not find version: {ver}".format(ver=version))

build = result
@@ -255,7 +254,7 @@ def _handler(signal_num, current_frame):
signal_name = _SIGNALS[signal_num]
print "Houdini wrapper caught sig SIG{}".format(signal_name)
six.print_("Houdini wrapper caught sig SIG{}".format(signal_name))

# Ignore further signals.
for sig in _SIGNALS:
@@ -271,25 +270,6 @@ def _handler(signal_num, current_frame):

def _print(msg="", colored=None):
"""Print a message, optionally with color.
:param msg: The message to print.
:type msg: str
:param colored: Output color.
:type colored: str
# Doing colored output.
if colored is not None:
# Run the message through the style function.
msg = getattr(ht.output.ShellOutput, colored)(msg)

# Print the message.
print msg

def _set_no_jemalloc(build_path, program_name):
"""Set the environment in order to run without jemalloc.
@@ -354,7 +334,7 @@ def main():
test_path = arguments.test_path
# log_level = arguments.log_level

_print("Houdini Wrapper:\n", colored="darkyellow")
cprint("Houdini Wrapper:\n", "yellow")

# If version is False (no argument), display any available versions and
# exit.
@@ -408,18 +388,18 @@ def main():
program_name = "hconfig"
program_args = ["-a"]

_print("Dumping env settings\n", colored="darkyellow")
cprint("Dumping env settings\n", "yellow")

# Dump the environment with 'printenv'.
proc = subprocess.Popen(


# Start with the name of the program to run.
# Start with the name of the program to run.
run_args = [program_name]

# If we don't want to have Houdini use jemalloc we need to replace the
@@ -429,24 +409,24 @@ def main():
run_args = _set_no_jemalloc(build.path, program_name)

# Print the Houdini version information.
_print("\tHoudini {}: {}\n".format(build, build.path))
six.print_("\tHoudini {}: {}\n".format(build, build.path))

# Print the command being run.
"Launching {} {} ... ".format(
" ".join(run_args),
" ".join(program_args)

# Run the application.
proc = subprocess.Popen(run_args + program_args)

# Display the process id.
"{} process id: {}".format(program_name,,

# Wait for the program to complete.
@@ -457,12 +437,12 @@ def main():

# If the program didn't end clean, print a message.
if return_code != 0:
"{} exited with signal {}.".format(

# Exit with the program's return code.
@@ -10,6 +10,7 @@ defined settings there.
This file has two components:

=== System Settings ===

These are used to tell the wrapper where installed builds are, where to look
for files to install and where they will be installed. It can also provide
information about where you might have compiled plugins.
@@ -19,7 +20,7 @@ information about where you might have compiled plugins.
These are used to defined various env variables and paths that should be set
when running. Variables will be set first so that any paths you wish to set
can include them if necessary. The test_* versions are for when running using
the -testpath flag for testing purposes.
the --test-path flag for testing purposes.

== Build Data ==
@@ -32,29 +33,38 @@ files you can install and what the latest builds and such are.
== Build Downloading ==

The wrapper can automatically handle downloading and installing builds from the
SideFX website. It is possible to attempt to download a specific build number
SideFX. It is possible to attempt to download a specific build number
(14.0.123) or to try to get "today's" build for a specific major.minor (15.0)
combination. Use the -dlinstall wrapper flag.
combination. Use the --dl-install wrapper flag.

Note: Automatic installation is only supported on Linux.

# To download and install a specific build:
wrapper -dlinstall 14.0.123
wrapper --dl-install 17.5.123

# To download and install the latest build:
wrapper --dl-install 17.5

# To download and install the lastest build:
wrapper -dlinstall 15.0
=== Configuration ===

To accomplish this it is necessary to log into the website. This is
supported using a .sesi_login_details json file located in your $HOME
Automatic downloading is handled via the SideFX Web API. In order to use this
feature you'll need to create credentials and have them available to the tooling.

The following is the simple template for the .sesi_login_details file:
Please see for instructions on how to
create credentials to download.

Once you have your credentials you just need to place them in a sesi_app_info.json
file located in your $HOME directory and the tooling will use that to connect and
download available builds.

The following is the simple template for the sesi_app_info.json file:

"username": "someusername",
"password": "somepassword"
"access_token_url": "",
"client_id": "your OAuth application ID",
"client_secret": "your OAuth application secret"
"endpoint_url": ""

When downloading packages automatically it will download them to the first
When automatically downloading builds they will be downloaded to the first
location in the 'archive_locations' list.

@@ -1,10 +1,11 @@
"""This module contains a custom version of argparse.ArgumentParser."""

# =============================================================================
# Import
# =============================================================================

# Python Imports
from __future__ import absolute_import
import argparse

@@ -27,29 +27,7 @@

"versions": {
"18.0": {
"reference_date": ["30/03/19", 60]

"17.5": {
"reference_date": ["28/03/19", 209]

"17.0": {
"reference_date": ["25/10/18", 381]

"16.5": {
"reference_date": ["18/7/18", 536],
"types": {
"Linux": {
"arch": "linux_x86_64_gcc4.8"

"16.0": {
"reference_date": ["6/09/17", 721],
"types": {
"Linux": {
"arch": "linux_x86_64_gcc4.8"

0 comments on commit 4fa2dd7

Please sign in to comment.
You can’t perform that action at this time.