Types#

Semantic Type#

qiime2.plugin.SemanticType(name, field_names=None, field_members=None, variant_of=None)[source]#

Create a new semantic type.

Parameters:
  • name (str) – The name of the semantic type: this should match the variable to which the semantic type is assigned.

  • field_names (str, iterable of str, optional) – Name(s) of the fields where member types can be placed. This makes the type a composite type, meaning that fields must be provided to produce realized semantic types. These names will define ad-hoc variant types accessible as name.field[field_names member].

  • field_members (mapping, optional) – A mapping of strings in field_names to one or more semantic types which are known to be members of the field (the variant type).

  • variant_of (VariantField, iterable of VariantField, optional) – Define the semantic type to be a member of one or more variant types allowing it to be placed in the respective fields defined by those variant types.

Returns:

There are several (private) types which may be returned, but anything returned by this factory will cause is_semantic_type to return True.

Return type:

A Semantic Type

Predicates#

class qiime2.plugin.Properties(*include, exclude=())[source]#

A one or more semantic properties to add to an existing type.

Semantic properties make an existing semantic type “smaller” than it would otherwise be. If a union causes types to become larger, then a property is the conceptual opposite. Either can be used to the same effect, it just depends on what the most natural “starting point” is for the base types (i.e. are the base types small and then union-ed, or are they broad and then subsequently narrowed as needed?)

Parameters:
  • *include (str) – Properties that are true. A property is only a subtype of another property if they match. This means that a subtype (with a set of properties X) of an expression (with properties Y) must have properties such that X >= Y. As a consequence, each additional property narrows the type further.

  • exclude (tuple[str]) – Treated as an inverse of include. The absence of a property is not sufficient for an excluded property to match. Excluded properties must be explicitly defined on the type. As a consequence, this field is rarely if ever used. It may be deprecated in the future.

Examples

>>> from qiime2.plugin import Properties

Properties must match:

>>> Properties('a') <= Properties('a')
True

An empty property is larger than a defined one:

>>> # semantic type expressions have implicit empty properties so
>>> # there is no need to ever provide an empty property directly
>>> Properties('a') <= Properties()
True

The more properties there are, the narrower the type is:

>>> Properties('a', 'b', 'c') <= Properties('a', 'b')
True
>>> Properties('a', 'b', 'c') <= Properties('a', 'c')
True
>>> Properties('a', 'b', 'c') <= Properties('b', 'c')
True
>>> Properties('a', 'b', 'c') <= Properties('a')
True

Order does not matter:

>>> Properties('a', 'b') <= Properties('a', 'b')
True
>>> Properties('a', 'b') <= Properties('b', 'a')
True

Visualization type#

qiime2.plugin.Visualization#

The type of a QIIME 2 Visualization.

This is not a semantic type as it represents a terminal/non-composable output.

An output with this type provides no assurances about the structure of the data as it is meant for human interpretation.

Examples

>>> from qiime2.plugin import Visualization
>>> Visualization
Visualization

Primitive types#

These are types that all QIIME 2 interfaces will recognize and generate user affordances for.

Basic types#

qiime2.plugin.Bool#

A boolean value (True/False). It can use the predicate Choices (but this is only interesting when using TypeMap)

Examples

>>> from qiime2.plugin import Bool, Choices

Normal values:

>>> True in Bool
True
>>> False in Bool
True

Constrained (for TypeMap):

>>> False in Bool % Choices(False)
True
>>> True in Bool % Choices(False)
False
qiime2.plugin.Str#

A string of Unicode characters (i.e. text). It can use the predicate Choices to create strict enumeration.

Examples

>>> from qiime2.plugin import Str, Choices

Arbitrary string:

>>> "Hello World" in Str
True

Enumeration of options:

>>> "apple" in Str % Choices("apple", "orange", "banana")
True
>>> "airplane" in Str % Choices("apple", "orange", "banana")
False

Warning

Do not use Str for filepaths. Not all interfaces have a consistent (or user-navigable) representation of a filesystem. Data should be represented as an artifact which will have a SemanticType() and allows the interface to store (and manipulate) your data as it sees fit.

qiime2.plugin.Int#

An integer without any particular bounds. It can use the predicates Range, Start(), and End()

Examples

>>> from qiime2.plugin import Int, Range, Start, End

No bounds on the value:

>>> -2 in Int
True

Integers between 0 (inclusive) and 5 (exclusive):

>>> 0 in Int % Range(0, 5)
True
>>> 5 in Int % Range(0, 5)
False

Same as above:

>>> 0 in Int % (Start(0) & End(5))
True
>>> 5 in Int % (Start(0) & End(5))
False
qiime2.plugin.Float#

A 64 bit floating point number. It can use the predicates Range, Start(), and End()

Examples

>>> from qiime2.plugin import Float, Range, Start, End

No bounds on the value:

>>> -0.2 in Float
True

Proportion between 0 (exclusive) and 1 (inclusive):

>>> 0.0 in Float % Range(0, 1, inclusive_start=False, inclusive_end=True)
False
>>> 1.0 in Float % Range(0, 1, inclusive_start=False, inclusive_end=True)
True

Same as above:

>>> 0.0 in Float % (Start(0, inclusive=False) & End(1, inclusive=True))
False
>>> 1.0 in Float % (Start(0, inclusive=False) & End(1, inclusive=True))
True
qiime2.plugin.Threads#

The number of logical threads to use (OS threads/CPUs/Cores).

Valid inputs are an integer that is non-negative or the string "auto". 0 and "auto" will indicate that the number of logical threads should be dictated by system resources.

It does not support any predicate expressions.

Examples

>>> from qiime2.plugin import Threads

Positive integer for the number of logical threads to use:

>>> 12 in Threads
True

Zero/auto to let the system decide:

>>> 0 in Threads
True
>>> "auto" in Threads
True
qiime2.plugin.Jobs#

The number of jobs to submit as an integer that is greater than zero (exclusive).

It does not support any predicate expressions.

Examples

>>> from qiime2.plugin import Jobs

Positive integer for the number of jobs to use:

>>> 20 in Jobs
True

Zero is not a valid value:

>>> 0 in Jobs
False

Predicates#

class qiime2.plugin.Choices(*choices)[source]#

A predicate which defines a set of allowable values.

Can be used with Str and Bool.

Parameters:

*choices (Any) – The legal values for the base type to use. Any value outside of this enumeration will be considered outside of the domain of the base type.

Examples

>>> from qiime2.plugin import Str, Choices
>>> "apple" in Str % Choices("apple", "orange", "banana")
True
>>> "airplane" in Str % Choices("apple", "orange", "banana")
False
class qiime2.plugin.Range([start, ]end, inclusive_start=True, inclusive_end=False)[source]#

A predicate which defines a contiguous range of allowable values.

Can be used with Int and Float.

Parameters:
  • [start] (number) – When provided as the first argument, the value will be the start of the range. Will be None (meaning negative infinity) when not provided.

  • end (number) – The end of the range (when provided as the first or second argument). Will be None (meaning positive infinity) when not provided.

  • inclusive_start (bool) – If the start is a part of the range.

  • inclusive_end (bool) – If the end is a part of the range.

Examples

>>> from qiime2.plugin import Float, Range

A simple proportion without 100%:

>>> 0.0 in Float % Range(0, 1)
True
>>> 0.999 in Float % Range(0, 1)
True
>>> 1.0 in Float % Range(0, 1)
False

A non-negative value:

>>> -1.0 in Float % Range(0, None)
False
>>> 0.0 in Float % Range(0, None)
True
>>> 1.0 in Float % Range(0, None)
True

Multiple discontinuous ranges:

>>> 0.0 in Float % (Range(0.1, 1, inclusive_end=True)
...                 | Range(10, 100, inclusive_end=True))
False
>>> 3.4 in Float % (Range(0.1, 1, inclusive_end=True)
...                 | Range(10, 100, inclusive_end=True))
False
>>> 1.0 in Float % (Range(0.1, 1, inclusive_end=True)
...                 | Range(10, 100, inclusive_end=True))
True
>>> 100.0 in Float % (Range(0.1, 1, inclusive_end=True)
...                   | Range(10, 100, inclusive_end=True))
True

Intersecting ranges (how Start() and End() work):

>>> Range(0, None) & Range(None, 10)
Range(0, 10)

See also

Start, End

qiime2.plugin.Start(start, inclusive=True)[source]#

Shorthand to generate a Range

The end of the resulting range is None (infinity).

Parameters:
  • start (number) – The start of the range

  • inclusive (bool) – Whether the start is a part of the range

Examples

>>> from qiime2.plugin import Start
>>> Start(0)
Range(0, None)

See also

Range

qiime2.plugin.End(end, inclusive=False)[source]#

Shorthand to generate a Range

The start of the resulting range is None (negative infinity).

Parameters:
  • end (number) – The end of the range

  • inclusive (bool) – Whether the end is a part of the range

Examples

>>> from qiime2.plugin import End
>>> End(100)
Range(None, 100)

See also

Range

Metadata#

These primitive types represent tabular metadata, where unique identifiers can be associated with columns. Typically these are used to represent per-sample or per-feature metadata. But there is nothing special about those axes.

qiime2.plugin.Metadata#

Tabular metadata where unique identifiers can be associated with columns.

This is the type that represents qiime2.Metadata.

Examples

>>> import pandas as pd
>>> import qiime2
>>> from qiime2.plugin import Metadata

Note the distinct module paths:

>>> md = qiime2.Metadata(pd.DataFrame([{'num':1, 'cat': 'a'}],
...                                   index=pd.Series(['s1'], name='id')))
>>> md in Metadata
True
qiime2.plugin.MetadataColumn = MetadataColumn[Categorical | Numeric]#

A column of a qiime2.Metadata.

Has two variants: Categorical and Numeric.

Examples

>>> import pandas as pd
>>> import qiime2
>>> from qiime2.plugin import Metadata, Categorical, Numeric
>>> md = qiime2.Metadata(pd.DataFrame([{'num':1, 'cat': 'a'}],
...                                   index=pd.Series(['s1'], name='id')))
>>> md
Metadata
--------
1 ID x 2 columns
num: ColumnProperties(type='numeric', missing_scheme='blank')
cat: ColumnProperties(type='categorical', missing_scheme='blank')
...

Categorical column:

>>> md.get_column('cat') in MetadataColumn[Categorical]
True
>>> md.get_column('num') in MetadataColumn[Categorical]
False

Numeric column:

>>> md.get_column('num') in MetadataColumn[Numeric]
True
>>> md.get_column('cat') in MetadataColumn[Numeric]
False

Any column:

>>> md.get_column('cat') in MetadataColumn[Categorical | Numeric]
True
>>> md.get_column('num') in MetadataColumn[Categorical | Numeric]
True
qiime2.plugin.Categorical#

The categorical variant for MetadataColumn.

Has no meaning unless used within MetadataColumn.

qiime2.plugin.Numeric#

The Numeric variant for MetadataColumn.

Has no meaning unless used within MetadataColumn.

Collections#

Collections may be used with Semantic, Visualization, and basic Primitive types.

qiime2.plugin.Set = Set[{type}]#

Deprecated - use List or Collection instead

A set of unique elements without a defined order except when used with a semantic type, in which case, the views are provided to the plugin as a list.

qiime2.plugin.List = List[{type}]#

An alias for a Collection with numeric auto-incrementing keys.

Examples

>>> from qiime2.plugin import List, Str

A regular list:

>>> ['a', 'b', 'c'] in List[Str]
True

A collection is also compatible:

>>> {'arbitrary_key': 'a'} in List[Str]
True
qiime2.plugin.Collection = Collection[{type}]#

An ordered set of key-value pairs. Compatible with lists and dictionaries.

The keys of a collection are always strings, and the values are defined by the variant provided to the type-field.

Whenever a list is provided, it will be coerced into a dictionary with auto-incrementing integer keys.

Examples

>>> from qiime2.plugin import Collection, Str

A regular dictionary:

>>> {'key1': 'a', 'key2': 'b'} in Collection[Str]
True

A list:

>>> ['a', 'b'] in Collection[Str]
True

Dependent Types#

class qiime2.plugin.TypeMap(mapping)[source]#

A table of input types which match to output types.

The TypeMap is best thought of as a table in which QIIME 2 is trying to find a row that matches the user’s input. Once found, the row-wise search is terminated and the outputs of that row are bound to the outputs of the action.

So if a TypeMap looked like this:

T_paramA, T_paramB, T_out = TypeMap({
    (Bool % Choices(True) , InputTypeA): ResultTypeA
    (Bool % Choices(False), InputTypeA): ResultTypeB
    (Bool % Choices(False), InputTypeB): ResultTypeB
})

It could be thought of as this table:

Parameter A

Parameter B

Result

True

InputTypeA

ResultTypeA

False

InputTypeA

ResultTypeB

False

InputTypeB

ResultTypeB

Where if the user provides True to Parameter A, they MUST provide InputTypeA to Parameter B, and will receive ResultTypeA. Otherwise, they may pass False to Parameter A, and provide either InputTypeA or InputTypeB, but will now receive ResultTypeB.

Note that when Parameter B is given InputTypeB, Parameter A must be False as there is no row in which True is simultaneously possible. (Or equivalently, if True is given for Parameter A, then Parameter B must be fixed to InputTypeA.)

This can be used to constrain dependent input parameters to a more limited domain than they would otherwise possess if they were treated independently.

If a TypeMap is used exclusively to constrain inputs but does not impact the output in any way, then the convention is to use Visualization to indicate a “nonsense” output and that final type variable is ignored (an unbound output variable has no effect so Visualization distinguishes the intention from an accidental omission).

It is also possible to define multiple outputs which are dependent on inputs, so long as the value of the dictionary is a tuple. This will result in additional type variables to be used in the output registration.

Parameters:

mapping (dict[tuple[type expressions], tuple[type expressions]]) – A tuple is not strictly required, so long as there are input and outputs which are enforced by the syntax of a dictionary. In the event a given input tuple’s domain overlaps another input tuple, the overlap must be a subset and the smaller branch must come first. Otherwise, the output resolution would be ambiguous (this rule is enforced when the TypeMap is constructed).

Returns:

The type variables should be unpacked from the TypeMap and the number will correspond to the number of “columns” in the TypeMap.

Return type:

iterable of TypeVarExp

class qiime2.plugin.TypeMatch(listing)[source]#

A trivial TypeMap such that every entry maps to itself.

A TypeMatch which looked like this:

T = TypeMatch([Foo, Bar, Baz])

Is essentially the same as:

T_in, T_out = TypeMap({
    Foo: Foo,
    Bar: Bar,
    Baz: Baz
})

Except that T doubles as both T_in and T_out.

Parameters:

listing (list[type fragments]) – A list of type fragments (usually variants). The behavior is similar to a union, but will cause the output type to be the same as the input type.

Returns:

A type variable that can be used as a plugin’s input and output. The output type will then be the same as the input type.

Return type:

TypeVarExp

Examples

>>> from qiime2.plugin import TypeMatch
>>> from qiime2.core.testing.type import Foo, Bar, Baz, C1
>>> T = TypeMatch([Foo, Bar, Baz])
>>> C1[Foo] <= C1[T]
True
>>> C1[Bar] <= C1[T]
True
>>> C1[Baz] <= C1[T]
True

See also

TypeMap