geni.portal

Library for dealing with scripts that are run in the context of a portal.

class Context(*args, **kwargs)[source]

Handle context for scripts being run inside a portal.

This class handles context for the portal, including where to put output RSpecs and handling parameterized scripts.

Scripts using this class can also be run “standalone” (ie. not by the portal), in which case they take parameters on the command line and put RSpecs on the standard output.

This class is a singleton. Most programs should access it through the portal.context variable; any additional “instances” of the object will be references to this.

bindParameters(altParamSrc=None)[source]

Returns values for the parameters defined by defineParameter().

Returns a Namespace (like argparse), so if you call foo = bindParameters(), a parameter defined with name “bar” is accessed as foo.bar . Since defaults are required, all parameters are guaranteed to have values in the Namespace

If run standaline (not in the portal), parameters are pulled from the command line (try running with –help); if run in the portal, they are pulled from the portal itself. Or, if you provide the altParamSrc argument, you can specify your own parameters. If altParamSrc is a dict, we will bind the params as a dict, using the keys as parameter names, and the values as parameter values. If altParamSrc is a geni.rspec.pgmanifest.Manifest, we will extract the parameters and their values from the Manifest. Finally, if altParamSrc is a string, we’ll try to parse it as a PG manifest xml document. No other forms of altParamSrc are currently specified.

bindRequestRSpec(rspec)[source]

Bind the given request RSpec to the context, so that it can be automatically used with methods like printRequestRSpec.

At the present time, only one request can be bound to a context

defineParameter(name, description, typ, defaultValue, legalValues=None, longDescription=None, inputFieldHint=None, inputConstraints=None, advanced=False, groupId=None, hide=False, multiValue=False, min=None, max=None, itemDefaultValue=None, multiValueTitle=None, prefix='emulab.net.parameter.')[source]

Define a new paramter to the script.

The given name will be used when parameters are bound. The description is brief help text that will be shown to the user when making his/her selection. The type should be one of the types defined by ParameterType. defaultValue is required, but legalValues (a list) is optional; the defaultValue must be one of the legalValues. Entries in the legalValues list may be either simple strings (eg. “m400”), in which case they will be show directly to the user, or 2-element tuples (eg. (“m400”, “ARM64”),), in which the second entry is what is shown to the user. defaultValue may be a tuple, so that one can pass, say, ‘legalvalues[0]’ for the option. The longDescription is an optional, detailed description of this parameter and how it relates to other parameters; it will be shown to the user if they ask to see the help, or as a pop-up/tooltip. advanced, group, and groupName all provide parameter group abstractions. Parameter groups are hidden by default from the user, and the user can expand them to view and modify them if desired. By setting advanced to True, you create a parameter group named “Advanced Parameters”; this group will not exist or be shown if none of your parameters set the ‘advanced’ argument to True.

After defining parameters, bindParameters() must be called exactly once.

defineParameterGroup(groupId, groupName)[source]

Define a parameter group. Parameters may be added to this group, which has an identifying token composed of alphanumeric characters (groupId), and a human-readable name (groupName). Groups are intended to be used for advanced parameters; in the portal UI, they hidden in an expandable panel with the groupName — and the user can choose to see and modify them, or not. You do not need to specify any groups; you can simply stuff all your parameters into the “Advanced Parameters” group by setting the ‘advanced’ argument of defineParameter to True. If you need multiple groups, define your own groups this way.

makeParameterWarningsFatal()[source]

Enable this option if you want to return an error to the user for incorrect parameter values, even if they can be autocorrected. This can be useful to show the user that

makeRequestRSpec()[source]

Make a new request RSpec, bind it to this context, and return it

printRequestRSpec(rspec=None)[source]

Print the given request RSpec, or the one bound to this context if none is given.

If run standalone (not in the portal), the request will be printed to the standard output; if run in the portal, it will be placed someplace the portal can pick it up.

If the given rspec does not have a Tour object, this will attempt to build one from the file’s docstring

reportError(parameterError, immediate=False)[source]

Report a parameter error to the portal. @parameterError is an exception object of type ParameterError. If @immediate is True, your script will exit immediately at this point with a dump of the errors (and fatal warnings, if enabled via Context.makeParameterWarningsFatal) in JSON format. If @immediate is False, the errors will accumulate until Context.verifyParameters is called (and the errors will then be printed).

reportWarning(parameterError)[source]

Record a parameter warning. Warnings will be printed if there are other errors or if warnings have been set to be fatal, when Context.verifyParameters() is called, or when there is another subsequent immediate error.

suppressAutoPrint()[source]

Suppress the automatic printing of the bound RSpec that normally happens when the program exits.

verifyParameters()[source]

If there have been calls to Context.parameterError, and/or to Context.parameterWarning (and Context.makeParameterWarningsFatal has been called, making warnings fatal), this function will spit out some nice JSON-formatted exception info on stderr

class DictNamespace[source]

A simple class that is similar to argparse.Namespace, but is also an iterable dictionary, and allows key/value deletion.

exception IllegalParameterDefaultError(val, param=None)[source]
exception IllegalParameterValueError(val, param=None)[source]
exception MissingParameterMemberError(param, memberName)[source]
class Multi(min=None, max=None, itemDefaultValue=None, multiValueTitle=None)[source]

When this class is added to a subclass of Parameter as the first multiply-inherited class, the subclass will accept lists as its values. The second multiply-inherited class specifies the member parameter type. We call this a multi-value parameter. Multi-value parameters have additional constraints (min/max member count).

Note that a defaultValue for a multi-value parameter is a list. Thus, multi-value parameters have a new field, the itemDefaultValue key, which is the default value of a new list member when unspecified. This allows the user to simply specify min/max/itemDefaultValue in lieu of the defaultValue, and an appropriate defaultValue of length min will be created by cloning the itemDefaultValue min times.

Given the “wrapping” nature of this class, it overrides every method in the Parameter class except for validate, because it effectively overrides all value parsing/checking and calls the second-level multiply-inherited class’s parse/check methods for member values.

property itemDefaultValue

Returns the new item default value. If a frontend can dynamically add member values to this Multi value parameter, this should be the value it autofills for the new member.

class MultiParameter(name, description, type, defaultValue, legalValues=None, longDescription=None, groupId=None, hide=False, prefix='emulab.net.parameter.', inputFieldHint=None, inputConstraints=None, min=None, max=None, itemDefaultValue=None, multiValueTitle=None)[source]
class MultiStructParameter(name, description, defaultValue=None, members=[], longDescription=None, groupId=None, hide=False, min=None, max=None, itemDefaultValue=None, multiValueTitle=None, prefix='emulab.net.parameter.', inputConstraints=None)[source]
validate()[source]

A wrapper that checks both the defaultValue and legalValues for type- and constraint-correctness.

exception MultipleRSpecError(val)[source]
exception NoRSpecError(val)[source]
class Parameter(name, description, type, defaultValue, legalValues=None, longDescription=None, inputFieldHint='', groupId=None, hide=False, prefix='emulab.net.parameter.', inputConstraints=None, _skipInitialChecks=False)[source]

A class containing the definition of a basic parameter where type is specified as a ParameterType field (e.g., not multi-valued, not a struct type). Do not instantiate this class directly; use the method wrappers in the Context class to declare parameters when possible.

Parameters must have a defaultValue. They may have a list of legalValues. All values in the latter must be type-correct, and the former must be both type-correct and a member of _legalValues. A legalValues list may be a flat list of type-correct values, or a list of 2-tuples, where the first element of each tuple is a type-correct value, and the second element is a display name for frontends.

property defaultValue

Return the default value of this parameter.

property legalValues

Returns None if there are no legal value restrictions. Otherwise, returns a list of legal values. (NB: self._legalValues itself may be either a list of strings, or a list of 2-tuples, where the actual value is the first element of the tuple, and the display hint is the second element.)

setDefaultValue(defaultValue)[source]

Sets this parameter’s default value, after invoking its _parseValue (type correctness) and _checkValue (constraint legality) methods.

setValue(value)[source]

Invoked by Context to bind a value to this parameter. This both parses the value and checks it for legality.

toParamdef()[source]

Converts this Parameter’s metadata to a JSON dict used by the portal frontend.

validate()[source]

A wrapper that checks both the defaultValue and legalValues for type- and constraint-correctness.

property value

Returns this parameter’s bound value, after values have been bound to this parameter’s portal Context object.

exception ParameterBindError(val, param=None)[source]
exception ParameterError(message, paramList, fixedValues={})[source]

A simple class to describe a parameter error. If you need to report an error with a user-specified parameter value to the Portal UI, please create (don’t throw) one of these error objects, and tell the Portal about it by calling Context.reportError.

class ParameterType[source]

Parameter types understood by Context.defineParameter().

AGGREGATE = 'aggregate'

URN specifying an Aggregate Manger

BANDWIDTH = 'bandwidth'

Floating-point number to be used for bandwidth

BASESTATION = 'basestation'

Base Stations

BOOLEAN = 'boolean'

True/False

FIXEDENDPOINT = 'fixedendpoint'

Fixed Endpoints

IMAGE = 'image'

URN specifying a particular image

INTEGER = 'integer'

Simple integer

LATENCY = 'latency'

Floating-point number to be used for latency

LOSSRATE = 'lossrate'

Floating-point number 0.0 <= N < 1.0

NODETYPE = 'nodetype'

String specifying a type of node

PUBKEY = 'pubkey'

An RSA public key.

SIZE = 'size'

Integer for size (eg. MB, GB, etc.)

STRING = 'string'

Any string

STRUCT = 'struct'

A StructParameter with member parameters; may be a JSON string that encodes a dict, or a raw dict.

exception ParameterWarning(message, paramList, fixedValues={})[source]

A simple class to describe a parameter warning. If you need to report an warning with a user-specified parameter value to the Portal UI, please create (don’t throw) one of these error objects, and tell the Portal about it by calling Context.reportWarning . The first time the Portal UI runs your geni-lib script with a user’s parameter values, it turns on the “warnings are fatal” mode (and then warnings are reported as errors). This gives you a chance to warn the user that they might be about to do something stupid, and/or suggest a set of modified values that will improve the situation. .

exception PortalError(message)[source]
class PortalJSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]
default(o)[source]

Implement this method in a subclass such that it returns a serializable object for o, or calls the base implementation (to raise a TypeError).

For example, to support arbitrary iterators, you could implement default like this:

def default(self, o):
    try:
        iterable = iter(o)
    except TypeError:
        pass
    else:
        return list(iterable)
    # Let the base class default method raise the TypeError
    return JSONEncoder.default(self, o)
class StructParameter(name, description, defaultValue=None, members=[], longDescription=None, groupId=None, hide=False, prefix='emulab.net.parameter.', inputConstraints=None, _skipInitialChecks=False)[source]
property defaultValue

Return the default value of this parameter.

property legalValues

Struct parameters do not have legal values; those must be set on each member parameter.

setValue(value)[source]

Invoked by Context to bind a value to this parameter. This both parses the value and checks it for legality.

toParamdef()[source]

Converts this Parameter’s metadata to a JSON dict used by the portal frontend.

validate()[source]

A wrapper that checks both the defaultValue and legalValues for type- and constraint-correctness.

context = <geni.portal.Context object>

Module-global Context object - most users of this module should simply use this rather than trying to create a new Context object

parseBool(b)[source]

Extract a bool from b as a string (any type), or by using bool().