Taxonomy

View as Markdown

Taxonomy

Taxonomy organizes content in a stack into hierarchical terms that you can tag entries with. Use this class to

  • list the taxonomies published in a stack
  • read one taxonomy by its UID
  • filter entries by the terms they carry

| Name | Type | Description |

| --- | --- | --- |

| taxonomy_uid | str | UID of the taxonomy. |

Omit taxonomy_uid to get a TaxonomyQuery: call find() alone to list taxonomies, or chain a filter before find() to filter entries. Pass it to get a Taxonomy for reading one taxonomy by UID.

above

above matches entries tagged with the ancestors of a term, excluding the term itself.

NameTypeDescription
field (required)str

Taxonomy field path to match against.

Default: Not applicable
term_uid (required)str

UID of the term whose ancestors to match.

Default: Not applicable
levelsint

How many hierarchy levels above the term to include.

Default: 10

The same query, for chaining.

Validation

  • There is no client-side validation. above accepts an empty string for either text argument, and a negative or non-integer levels, and stores each one as given.
  • Omitting field or term_uid raises TypeError immediately, because both are positional parameters with no default. Omitting levels is valid and applies the SDK default of 10.
  • Errors that do occur come from the find() call that follows, not from above().
    • find() raises an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection (for example, a term UID that does not exist) returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. above records the condition {"$above": term_uid, "levels": levels} under the field path and makes no request.
  • The match excludes the named term. An entry tagged only with paris does not match above('taxonomies.regions', 'paris'). Use the equal_and_above method to include it.
  • A root term has no ancestors, so above on a root term matches nothing. The API returns an empty entry list rather than an error.
  • Calling above twice on the same field replaces the first condition. Use the or_ method to combine two hierarchy conditions on one field.
  • Chaining this filter routes the following find to GET /taxonomies/entries, so find returns entries rather than taxonomies.

Example

Basic usage: match the ancestors of a term

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().above('taxonomies.regions', 'paris').find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('matched', len(result.get('entries', [])), 'entries')

All parameters: match the immediate parent only

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # levels=1 stops at the direct parent of 'paris'.
    result = stack.taxonomy().above('taxonomies.regions', 'paris', levels=1).find()
except Exception as error:
    print('Request failed:', error)

Edge case: an empty result from a root term

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # 'world' sits at the root, so nothing is above it. This returns no entries
    # and no error, which is easy to mistake for a broken query.
    result = stack.taxonomy().above('taxonomies.regions', 'world').find()
    print('entries:', len(result.get('entries', [])))
except Exception as error:
    print('Request failed:', error)

and_

and_ matches entries satisfying all of the given conditions.

NameTypeDescription
conds (required)dict

Condition dictionaries, passed as separate arguments.

Default: Not applicable

The same query, for chaining.

Validation

  • There is no client-side validation. and_ accepts any object as a condition, including a value that is not a dictionary, and stores it as given.
  • Calling and_() with no arguments is valid and stores an empty condition list. The API then receives {"$and": []}.
  • Errors that do occur come from the find() call that follows, not from and_().
    • find() raises an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection (for example, a malformed condition) returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. and_ collects its arguments into a list and records them under the single $and key. It makes no request.
  • Pass each condition as a separate argument, not as one list. See How filters combine on the Taxonomy class page. and_([cond_a, cond_b]) produces the nested structure {"$and": [[cond_a, cond_b]]}.
  • Calling and_ twice replaces the whole condition set, because both calls own the same $and key.
  • Chaining two separate filter methods already behaves as a conjunction, because the API combines the stored field conditions. Use and_ when you need two conditions on the same field, which a repeated filter method cannot express.
  • and_ and or_ own different keys, so you can chain both on one query.

Example

Basic usage: require two taxonomy conditions together

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().and_(
        {'taxonomies.regions': {'$in': ['europe']}},
        {'taxonomies.products': {'$in': ['laptops']}}
    ).find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('matched', len(result.get('entries', [])), 'entries')

Combining both logical filters on one query

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # $and and $or are separate keys, so both conditions reach the API.
    result = stack.taxonomy() \
        .and_({'taxonomies.regions': {'$exists': True}}) \
        .or_(
            {'taxonomies.products': {'$in': ['laptops']}},
            {'taxonomies.products': {'$in': ['tablets']}}
        ) \
        .find()
except Exception as error:
    print('Request failed:', error)

Edge case: a second call discards the first condition set

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Only the products condition survives.
    result = stack.taxonomy() \
        .and_({'taxonomies.regions': {'$in': ['europe']}}) \
        .and_({'taxonomies.products': {'$in': ['laptops']}}) \
        .find()

    # Pass both conditions to a single call instead.
    correct = stack.taxonomy().and_(
        {'taxonomies.regions': {'$in': ['europe']}},
        {'taxonomies.products': {'$in': ['laptops']}}
    ).find()
except Exception as error:
    print('Request failed:', error)

below

below matches entries tagged with the descendants of a term, excluding the term itself.

NameTypeDescription
field (required)str

Taxonomy field path to match against.

Default: Not applicable
term_uid (required)str

UID of the term whose descendants to match.

Default: Not applicable
levelsint

How many hierarchy levels below the term to include.

Default: 10

The same query, for chaining.

Validation

  • There is no client-side validation. below accepts an empty string for either text argument, and a negative or non-integer levels, and stores each one as given.
  • Omitting field or term_uid raises TypeError immediately, because both are positional parameters with no default. Omitting levels is valid and applies the SDK default of 10.
  • Errors that do occur come from the find() call that follows, not from below().
    • find() raises an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection (for example, a term UID that does not exist) returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. below records the condition {"$below": term_uid, "levels": levels} under the field path and makes no request.
  • The match excludes the named term. An entry tagged only with europe does not match below('taxonomies.regions', 'europe'). Use the equal_and_below method to include it.
  • The SDK always sends levels, even when you omit the argument, because the default lives in the method signature rather than at the API.
  • Calling below twice on the same field replaces the first condition. Use the or_ method to combine two hierarchy conditions on one field.
  • Chaining this filter routes the following find to GET /taxonomies/entries, so find returns entries rather than taxonomies.

Example

Basic usage: match the descendants of a term

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().below('taxonomies.regions', 'europe').find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('matched', len(result.get('entries', [])), 'entries')

All parameters: match direct children only

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # levels=1 stops at the immediate children of 'europe'.
    result = stack.taxonomy().below('taxonomies.regions', 'europe', levels=1).find()
except Exception as error:
    print('Request failed:', error)

Edge case: entries tagged with the parent term are missing

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # An entry tagged 'europe' and nothing else does not appear here.
    descendants = stack.taxonomy().below('taxonomies.regions', 'europe').find()

    # Switch filters to include it.
    inclusive = stack.taxonomy().equal_and_below('taxonomies.regions', 'europe').find()
except Exception as error:
    print('Request failed:', error)

equal_and_above

equal_and_above matches entries tagged with a term or with any of its ancestors.

NameTypeDescription
field (required)str

Taxonomy field path to match against.

Default: Not applicable
term_uid (required)str

UID of the term at the bottom of the range.

Default: Not applicable
levelsint

How many hierarchy levels above the term to include.

Default: 10

The same query, for chaining.

Validation

  • There is no client-side validation. equal_and_above accepts an empty string for either text argument, and a negative or non-integer levels, and stores each one as given.
  • Omitting field or term_uid raises TypeError immediately, because both are positional parameters with no default. Omitting levels is valid and applies the SDK default of 10.
  • Errors that do occur come from the find() call that follows, not from equal_and_above().
    • find() raises an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection (for example, a term UID that does not exist) returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. equal_and_above records the condition {"$eq_above": term_uid, "levels": levels} under the field path and makes no request.
  • The match includes the named term itself. Use the above method to exclude it.
  • Ancestor matching traverses toward the root, so a deep taxonomy needs fewer levels than a descendant search covering the same tree. Each term has one path to the root.
  • Calling equal_and_above twice on the same field replaces the first condition. Use the or_ method to combine two hierarchy conditions on one field.
  • Chaining this filter routes the following find to GET /taxonomies/entries, so find returns entries rather than taxonomies.

Example

Basic usage: match a term and its ancestors

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().equal_and_above('taxonomies.regions', 'paris').find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('matched', len(result.get('entries', [])), 'entries')

All parameters: match the term and one level up

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Matches 'paris' and its immediate parent, for example 'france'.
    result = stack.taxonomy().equal_and_above(
        'taxonomies.regions', 'paris', levels=1
    ).find()
except Exception as error:
    print('Request failed:', error)

equal_and_below

equal_and_below matches entries tagged with a term or with any of its descendants.

NameTypeDescription
field (required)str

Taxonomy field path to match against.

Default: Not applicable
term_uid (required)str

UID of the term at the top of the range.

Default: Not applicable
levelsint

How many hierarchy levels below the term to include.

Default: 10

The same query, for chaining.

Validation

  • There is no client-side validation. equal_and_below accepts an empty string for either text argument, and a negative or non-integer levels, and stores each one as given.
  • Omitting field or term_uid raises TypeError immediately, because both are positional parameters with no default. Omitting levels is valid and applies the SDK default of 10.
  • Errors that do occur come from the find() call that follows, not from equal_and_below().
    • find() raises an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection (for example, a term UID that does not exist) returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. equal_and_below records the condition {"$eq_below": term_uid, "levels": levels} under the field path and makes no request.
  • The match includes the named term itself. Use the below method to exclude it.
  • The SDK always sends levels, even when you omit the argument, because the default lives in the method signature rather than at the API. A query that omits it therefore caps the search at ten levels below the term.
  • Calling equal_and_below twice on the same field replaces the first condition. Use the or_ method to combine two hierarchy conditions on one field.
  • Chaining this filter routes the following find to GET /taxonomies/entries, so find returns entries rather than taxonomies.

Example

Basic usage: match a term and everything under it

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().equal_and_below('taxonomies.regions', 'europe').find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('matched', len(result.get('entries', [])), 'entries')

All parameters: limit the search to two levels below the term

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Matches 'europe', its children, and its grandchildren. Nothing deeper.
    result = stack.taxonomy().equal_and_below(
        'taxonomies.regions', 'europe', levels=2
    ).find()
except Exception as error:
    print('Request failed:', error)

Edge case: the default depth silently caps a deep hierarchy

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # A taxonomy deeper than ten levels loses its deepest terms here,
    # because the SDK sends levels=10 whenever you omit the argument.
    capped = stack.taxonomy().equal_and_below('taxonomies.regions', 'world').find()

    # Raise levels explicitly to reach the whole tree.
    full = stack.taxonomy().equal_and_below(
        'taxonomies.regions', 'world', levels=50
    ).find()
except Exception as error:
    print('Request failed:', error)

exists

exists matches entries that carry a value in the given taxonomy field.

NameTypeDescription
field (required)str

Taxonomy field path that must hold a value.

Default: Not applicable

The same query, for chaining.

Validation

  • There is no client-side validation. exists accepts an empty string as the field and stores it as given.
  • Omitting the argument raises TypeError immediately, because field is a positional parameter with no default.
  • Errors that do occur come from the find() call that follows, not from exists().
    • find() raises an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection (for example, a field path that names no taxonomy) returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. exists records the condition {"$exists": True} under the field path and makes no request.
  • The condition is always True. There is no parameter for matching entries that lack the field. Use the or_ method with an explicit {"$exists": False} condition dictionary for the inverse.
  • Chaining exists routes the following find to GET /taxonomies/entries, so find returns entries rather than taxonomies.
  • Calling exists twice on the same field is a no-op the second time, because both calls write the identical condition to the same key.

Limitations

  • Does not distinguish an empty term list from an absent field. Filter the returned entries in your own code when that difference matters.

Example

Basic usage: match every entry tagged in one taxonomy

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().exists('taxonomies.regions').find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('tagged entries:', len(result.get('entries', [])))

Inverse condition: match entries that lack the field

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # exists always sends True, so build the negative condition by hand.
    result = stack.taxonomy().or_(
        {'taxonomies.regions': {'$exists': False}}
    ).find()
except Exception as error:
    print('Request failed:', error)

fetch

fetch retrieves one published taxonomy by its UID.

The requested taxonomy.

Validation

  • fetch validates nothing itself. The UID check happens earlier, in the constructor.
  • stack.taxonomy('') never reaches this method. The empty string is falsy, so stack.taxonomy returns a TaxonomyQuery, which has no fetch, and the call raises AttributeError. See the Warning on the Taxonomy class page.
  • Constructing Taxonomy directly with an empty or None UID raises KeyError with the message "Invalid key or value. Provide valid values and try again." because the SDK cannot build the taxonomy URL without an identifier.
  • fetch raises an exception only for network failures (timeout, DNS error, dropped connection). The exception type is RequestError.
    • An API-level rejection, including a UID that names no taxonomy, returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Calls GET /taxonomies/{taxonomy_uid} and makes one HTTP request per call.
  • Returns the contents of the taxonomy key on success, not the response envelope around it.
  • Falls back to the whole response body when the taxonomy key is absent, which is what happens on an API rejection. That is why an error body still reaches you with its error key intact.
  • Sends whatever locale, include_fallback, include_branch, and param recorded on the instance. Calling fetch twice on one instance repeats the same request.

Limitations

  • Does not return the taxonomy's terms. Use the term method to reach them.

Example

Basic usage: read one taxonomy by UID

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy('regions').fetch()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print(result['uid'], result['name'])

All modifiers: locale, fallback, branch, and an extra parameter

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy('regions') \
        .locale('fr-fr') \
        .include_fallback() \
        .include_branch() \
        .param('include_count', 'true') \
        .fetch()
    print('branch:', result.get('_branch'))
except Exception as error:
    print('Request failed:', error)

Error handling: an unknown UID does not raise

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy('no_such_taxonomy').fetch()
except Exception as error:
    print('Request failed:', error)
else:
    # A missing taxonomy arrives as an ordinary return value, not an exception.
    if 'error' in result:
        print('code:', result.get('error_code'), 'message:', result.get('error_message'))

Edge case: an empty UID returns the wrong object

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

taxonomy_uid = ''

try:
    result = stack.taxonomy(taxonomy_uid).fetch()
except AttributeError as error:
    # Fires because the empty string returned a TaxonomyQuery, which has no fetch.
    print('Guard the UID before calling fetch:', error)

find

find lists the published taxonomies in a stack, or returns the entries matching a chained filter.

NameTypeDescription
paramsdict

Extra query parameters merged into the request.

Default: None

The published taxonomies, or the entries matching the chained filter.

Validation

  • Passing a non-dictionary as params fails on the taxonomy-list path, where find passes it to dict.update. A non-zero integer raises TypeError, and a non-empty string or a list of wrong-length items raises ValueError. On the entry-filter path it raises AttributeError from items instead.
  • Passing None for params is valid and is the default. find skips the merge entirely.
  • find never validates the chained filter or the pagination values. It serializes whatever the query holds and sends it.
  • find raises an exception only for network failures (timeout, DNS error, dropped connection). The exception type is RequestError.
    • An API-level rejection returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Which endpoint find calls depends on whether you chain a filter. See One method, two endpoints on the Taxonomy class page.
    • No filter chained: GET /taxonomies, returning {'taxonomies': [...]} plus count when you chain include_count.
    • Any filter chained: GET /taxonomies/entries, returning the matching entries.
  • One call makes one HTTP request. The SDK does not iterate pages.
  • params reaches the two paths differently.
    • On the taxonomy-list path the SDK merges params into the stored query parameters, so a key that collides with limit, skip, or include_count overwrites it.
    • On the entry-filter path the SDK appends params to the URL as raw key=value pairs without encoding them. Encode any value containing a reserved character before passing it.
  • find sends the environment parameter on the entry-filter path only. The list path relies on the environment header that Stack supplies.

Limitations

  • Does not return every taxonomy when you omit limit. The API applies its own page size. Chain the include_count method and compare count against the length of the returned list to detect a truncated page.
  • Does not accept pagination on the entry-filter path. Chaining a filter makes find drop skip, limit, and include_count.

Example

Basic usage: list the published taxonomies

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        for taxonomy in result.get('taxonomies', []):
            print(taxonomy['uid'], taxonomy['name'])

All parameters: pass an extra query parameter alongside pagination

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # params is merged into the stored query parameters on the list path.
    result = stack.taxonomy().skip(10).limit(10).include_count().find(
        params={'locale': 'fr-fr'}
    )
    print('total:', result.get('count'))
except Exception as error:
    print('Request failed:', error)

Filtering: return entries instead of taxonomies

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Chaining in_ routes find to GET /taxonomies/entries.
    result = stack.taxonomy().in_('taxonomies.regions', ['europe']).find()
except Exception as error:
    print('Request failed:', error)

Edge case: a chained filter drops the pagination values

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # limit(5) applies here.
    capped = stack.taxonomy().limit(5).find()

    # limit(5) is silently ignored here, because the filter changes the endpoint.
    # Use Query.limit on a content type query to cap entry results instead.
    entries = stack.taxonomy().limit(5).exists('taxonomies.regions').find()
except Exception as error:
    print('Request failed:', error)

in_

in_ matches entries tagged with any of the given terms.

NameTypeDescription
field (required)str

Taxonomy field path to match against.

Default: Not applicable
terms (required)list

Term UIDs that satisfy the condition.

Default: Not applicable

The same query, for chaining.

Validation

  • There is no client-side validation. in_ accepts an empty string as the field, an empty list, and a non-list value for terms, and stores each one as given.
  • Omitting either argument raises TypeError immediately, because both are positional parameters with no default.
  • Errors that do occur come from the find() call that follows, not from in_().
    • find() raises an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection (for example, a field path that names no taxonomy) returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. in_ records the condition {"$in": terms} under the field path and makes no request.
  • Chaining in_ routes the following find to GET /taxonomies/entries, so find returns entries rather than taxonomies. See One method, two endpoints on the Taxonomy class page.
  • The field path takes the form taxonomies.<TAXONOMY_UID>. It names the taxonomy field on the entry, not the term.
  • Calling in_ twice on the same field replaces the first condition. Use the or_ method to combine two conditions on one field.
  • The type annotation names TaxonomyFilter as the return type, but in_ returns the same instance you called it on. Calling it on stack.taxonomy() therefore returns a TaxonomyQuery.

Example

Basic usage: match entries tagged with either of two terms

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().in_('taxonomies.regions', ['europe', 'asia']).find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('matched', len(result.get('entries', [])), 'entries')

Edge case: a second call on the same field replaces the first

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Only the second condition survives, so this matches 'asia' alone.
    overwritten = stack.taxonomy() \
        .in_('taxonomies.regions', ['europe']) \
        .in_('taxonomies.regions', ['asia']) \
        .find()

    # Pass both terms in one list instead.
    correct = stack.taxonomy().in_('taxonomies.regions', ['europe', 'asia']).find()
except Exception as error:
    print('Request failed:', error)

include_branch

include_branch adds the _branch field to the taxonomy in the response.

The same taxonomy, for chaining.

Validation

  • There is nothing to validate. include_branch takes no arguments and cannot fail.
  • Errors that do occur come from the fetch() call that follows, not from include_branch().
    • fetch() raises an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. Sets include_branch=true as a string and makes no request. fetch sends the flag on that call.
  • The flag reports which branch served the taxonomy. It does not select one. Pass branch to Stack to choose the branch a request targets.
  • A stack with no branches enabled returns no _branch field even with the flag set, so read the key defensively.

Example

Basic usage: confirm which branch served the taxonomy

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy('regions').include_branch().fetch()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('served from branch:', result.get('_branch', 'branches not enabled'))

Selecting a branch, which this method does not do

import contentstack

stack = contentstack.Stack(
    '<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>', branch='release-2'
)

try:
    # branch on Stack picks the branch. include_branch only reports it back.
    result = stack.taxonomy('regions').include_branch().fetch()
    print('requested release-2, served:', result.get('_branch'))
except Exception as error:
    print('Request failed:', error)

include_count

include_count adds the total number of published taxonomies to the response.

The same query, for chaining.

Validation

  • There is nothing to validate. include_count takes no arguments and cannot fail.
  • Errors that do occur come from the find() call that follows, not from include_count().
    • find() raises an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. Sets include_count=true as a string and makes no request. find sends the flag on that call.
  • The count key holds the total number of published taxonomies in the stack, not the number returned in this page. Compare it against the length of the taxonomies list to find out whether more remain.
  • Chaining a filter such as in_ silently drops the flag, so the entry-filter response carries no count.

Example

Basic usage: detect a truncated taxonomy list

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().limit(10).include_count().find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        returned = len(result.get('taxonomies', []))
        total = result.get('count', 0)
        print(f'showing {returned} of {total}')
        if returned < total:
            print('more pages remain, raise skip to read them')

Edge case: no count on the entry-filter path

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # The filter routes find to GET /taxonomies/entries, which ignores the flag.
    result = stack.taxonomy().include_count().in_('taxonomies.colors', ['red']).find()

    # count is absent here, so the default guards against a KeyError.
    print('count key present:', 'count' in result)
except Exception as error:
    print('Request failed:', error)

include_fallback

include_fallback returns an earlier locale in the hierarchy when the taxonomy has no localization in the requested one.

The same taxonomy, for chaining.

Validation

  • There is nothing to validate. include_fallback takes no arguments and cannot fail.
  • Errors that do occur come from the fetch() call that follows, not from include_fallback().
    • fetch() raises an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. Sets include_fallback=true as a string and makes no request. fetch sends the flag on that call.
  • The flag alone changes nothing. Chain the locale method as well, because the fallback only applies when the requested locale differs from the master locale.
  • The API resolves the fallback, not the SDK. It returns the nearest earlier locale in the hierarchy that holds a published version.
  • The response does not report whether a fallback happened. Compare the returned locale against the one you asked for when that difference matters.

Example

Basic usage: accept an earlier locale when the French version is missing

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy('regions').locale('fr-fr').include_fallback().fetch()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('name:', result.get('name'))

Edge case: detect a fallback

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

requested = 'fr-fr'

try:
    result = stack.taxonomy('regions').locale(requested).include_fallback().fetch()

    # The response carries the locale it actually served, so compare the two.
    served = result.get('locale')
    if served and served != requested:
        print(f'no {requested} version, served {served} instead')
except Exception as error:
    print('Request failed:', error)

limit

limit caps the number of taxonomies the response contains.

NameTypeDescription
limit (required)int

Maximum number of taxonomies to return.

Default: Not applicable

The same query, for chaining.

Validation

  • There is no client-side validation. The SDK stores and sends a negative or non-integer value as given.
  • Omitting the argument raises TypeError immediately, because limit is a positional parameter with no default.
  • Errors that do occur come from the find() call that follows, not from limit().
    • find() raises an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection (for example, an invalid limit value) returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. Sets the limit query parameter and makes no request. find sends the value on that call.
  • Omitting limit does not return every taxonomy. The API applies its own page size instead. See Pagination on the Taxonomy class page for how to detect a truncated list and page through the rest.
  • Calling limit twice replaces the first value. The SDK stores it under a single key.
  • Chaining a filter such as in_ silently drops the limit.

Example

Basic usage: return at most ten taxonomies

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().limit(10).find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('returned', len(result.get('taxonomies', [])), 'taxonomies')

Edge case: chaining a filter ignores the limit

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # This lists at most 5 taxonomies.
    capped = stack.taxonomy().limit(5).find()

    # This returns entries, and the limit below has no effect.
    # Use Query.limit on a content type query to cap entry results instead.
    entries = stack.taxonomy().limit(5).in_('taxonomies.colors', ['red']).find()
except Exception as error:
    print('Request failed:', error)

locale

locale sets the language the API returns the taxonomy in.

NameTypeDescription
locale (required)str

Locale code to request, for example fr-fr.

Default: Not applicable

The same taxonomy, for chaining.

Validation

  • There is no client-side validation. locale accepts an empty string or a code that names no locale and stores it as given.
  • Omitting the argument raises TypeError immediately, because locale is a positional parameter with no default.
  • Errors that do occur come from the fetch() call that follows, not from locale().
    • fetch() raises an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. locale sets the locale query parameter and makes no request. fetch sends the value on that call.
  • The SDK sets no default. Omitting locale sends no locale parameter, and the API returns the stack's master locale.
  • Calling locale twice replaces the first value. The SDK stores it under a single key.
  • A taxonomy that has no localization in the requested locale comes back empty unless you also chain the include_fallback method.
  • Taxonomy.locale and Term.locale are separate methods on separate objects. Setting the locale on the taxonomy does not carry it down to a term you reach through the term method.

Example

Basic usage: read a taxonomy in French

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy('regions').locale('fr-fr').fetch()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('localized name:', result.get('name'))

Edge case: the locale does not carry down to terms

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    taxonomy = stack.taxonomy('regions').locale('fr-fr')

    # This term request has no locale, so it returns the master locale.
    term = taxonomy.term('paris').fetch()

    # Set the locale again on the term to get the French version.
    localized_term = stack.taxonomy('regions').term('paris').locale('fr-fr').fetch()
except Exception as error:
    print('Request failed:', error)

or_

or_ matches entries satisfying any one of the given conditions.

NameTypeDescription
conds (required)dict

Condition dictionaries, passed as separate arguments.

Default: Not applicable

The same query, for chaining.

Validation

  • There is no client-side validation. or_ accepts any object as a condition, including a value that is not a dictionary, and stores it as given.
  • Calling or_() with no arguments is valid and stores an empty condition list. The API then receives {"$or": []}, which matches nothing rather than everything.
  • Errors that do occur come from the find() call that follows, not from or_().
    • find() raises an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection (for example, a malformed condition) returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. or_ collects its arguments into a list and records them under the single $or key. It makes no request.
  • Pass each condition as a separate argument, not as one list. See How filters combine on the Taxonomy class page. or_([cond_a, cond_b]) produces the nested structure {"$or": [[cond_a, cond_b]]}.
  • Calling or_ twice replaces the whole condition set, because both calls own the same $or key.
  • Chaining or_ routes the following find to GET /taxonomies/entries, so find returns entries rather than taxonomies.
  • Write the condition dictionaries in the Delivery API taxonomy query syntax. or_ does not build them for you, so an operator such as $in or $eq_below appears verbatim in the dictionary you pass.

Example

Basic usage: match entries in either of two taxonomies

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().or_(
        {'taxonomies.regions': {'$in': ['europe']}},
        {'taxonomies.products': {'$in': ['laptops']}}
    ).find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('matched', len(result.get('entries', [])), 'entries')

Two conditions on one field, which a repeated filter cannot express

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Two in_ calls on one field would collide. or_ keeps both conditions.
    result = stack.taxonomy().or_(
        {'taxonomies.regions': {'$eq_below': 'europe', 'levels': 2}},
        {'taxonomies.regions': {'$in': ['antarctica']}}
    ).find()
except Exception as error:
    print('Request failed:', error)

Error handling: a list instead of separate arguments

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

conditions = [
    {'taxonomies.regions': {'$in': ['europe']}},
    {'taxonomies.products': {'$in': ['laptops']}}
]

try:
    # Unpack the list. Passing `conditions` directly nests it one level too deep.
    result = stack.taxonomy().or_(*conditions).find()
    if 'error' in result:
        print('Delivery API error:', result['error'])
except Exception as error:
    print('Request failed:', error)

param

param adds an arbitrary query parameter to the request.

NameTypeDescription
key (required)str

Query parameter name to send.

Default: Not applicable
value (required)Any

Value for that query parameter.

Default: Not applicable

The same object, for chaining.

Validation

  • Passing None as either argument raises KeyError with the message "Invalid key or value arguments. Provide valid values and try again." A null key or value would produce a malformed query string. This is the only method on this class that rejects its own arguments.
  • The raise happens on the call itself, not on the terminal call that follows. Wrap param in its own try when the key or value comes from user input.
  • An empty string passes the check. None is the only rejected value, so param('', '') stores a parameter with no name.
  • Omitting either argument raises TypeError immediately, because both are positional parameters with no default.
  • Any remaining errors come from the terminal call, find() on a TaxonomyQuery or fetch() on a Taxonomy.
    • Those calls raise an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. param records the pair in the query parameters and makes no request.
  • This is the only method available on both objects stack.taxonomy() can return. Everything else belongs to one branch or the other.
  • The key shares one namespace with the dedicated modifiers. param('limit', 5) and limit(5) write to the same place, so whichever call comes last wins.
  • Use param to reach a Delivery API query parameter the SDK exposes no method for. Prefer the dedicated method when one exists, because it documents the intent.
  • On a TaxonomyQuery, chaining a filter routes find to the entry endpoint, which never reads these stored parameters, so find drops them along with the pagination values.
  • The SDK encodes the parameters before sending them, so a value containing a space or an ampersand needs no encoding from you.

Example

Basic usage: send a query parameter the SDK has no method for

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().param('include_terms_count', 'true').find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('taxonomies:', len(result.get('taxonomies', [])))

All parameters: both arguments on a single-taxonomy fetch

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # param works the same on the Taxonomy branch, where fetch is terminal.
    result = stack.taxonomy('regions').param('locale', 'fr-fr').fetch()
    print('name:', result.get('name'))
except Exception as error:
    print('Request failed:', error)

Error handling: a null key raises at the call site

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

user_supplied_key = None

try:
    result = stack.taxonomy().param(user_supplied_key, 'true').find()
except KeyError as error:
    # Fires on param itself, before any request goes out.
    print('Invalid query parameter:', error)

Edge case: a dedicated method and param collide

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Both write the 'limit' key, so the later call wins and this sends limit=5.
    result = stack.taxonomy().limit(10).param('limit', 5).find()
except Exception as error:
    print('Request failed:', error)

skip

skip omits a number of taxonomies from the start of the response.

NameTypeDescription
skip (required)int

Number of taxonomies to omit from the start.

Default: Not applicable

The same query, for chaining.

Validation

  • There is no client-side validation. The SDK stores and sends a negative or non-integer value as given.
  • Omitting the argument raises TypeError immediately, because skip is a positional parameter with no default.
  • Errors that do occur come from the find() call that follows, not from skip().
    • find() raises an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. Sets the skip query parameter and makes no request. find sends the value on that call.
  • The SDK sets no default. Omitting skip sends no skip parameter, and the API starts from the first taxonomy.
  • Calling skip twice replaces the first value. The SDK stores it under a single key.
  • Chaining a filter such as in_ silently drops the offset.
  • Pair skip with limit to page through the full list. The SDK does not page automatically.

Example

Basic usage: read the second page of ten taxonomies

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().skip(10).limit(10).find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('page 2 holds', len(result.get('taxonomies', [])), 'taxonomies')

Pagination: read every page in order

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

page_size = 10
offset = 0

try:
    while True:
        result = stack.taxonomy().skip(offset).limit(page_size).include_count().find()
        batch = result.get('taxonomies', [])
        for taxonomy in batch:
            print(taxonomy['uid'])
        offset += page_size
        # count is the total, not the page length, so compare against the offset.
        if offset >= result.get('count', 0):
            break
except Exception as error:
    print('Request failed:', error)

term

term moves down from a taxonomy to its terms.

NameTypeDescription
term_uidstr

UID of one term. Omit it to reach all terms.

Default: None

A single term, or a query across the taxonomy's terms.

Validation

  • term itself validates nothing. It tests term_uid for truthiness and hands the value to the object it builds.
  • Passing a non-empty UID builds a Term, whose constructor raises KeyError only when the UID is falsy. That branch is unreachable through this method.
  • term('') is not the same as term('<TERM_UID>'). The empty string is falsy, so it takes the no-UID branch and returns a TermQuery. Calling fetch on that object raises AttributeError, and calling find returns every term instead of the one you meant.
  • Errors that do occur come from the terminal call on the returned object, fetch() or find(), not from term().
    • Those calls raise an exception only for network failures (timeout, DNS error, dropped connection).
    • An API-level rejection returns as a normal result with an error key. It does not raise an exception.
    • Check the result for an error key even inside a try block.

Additional Resource Refer to Delivery API Errors for the full error code list.

Behavior

  • Client-side only. term constructs an object and makes no request.
  • Which class you get back decides which methods are available.
    • term('<TERM_UID>') returns a Term, which reads one term (fetch) and traverses the hierarchy (ancestors, descendants, locales).
    • term() returns a TermQuery, which lists the taxonomy's terms (find) with pagination and locale modifiers.
  • The new object carries none of the taxonomy's chained modifiers. Locale, fallback, and branch settings made on the taxonomy do not reach the term, so set them again on the returned object.
  • The taxonomy UID is the only state that carries over. term reads it from the instance to build the term URL.

Example

Basic usage: read one term by UID

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy('regions').term('paris').fetch()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print(result['uid'], result['name'])

No UID: list every term in the taxonomy

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Omitting the UID returns a TermQuery, so the terminal call is find.
    result = stack.taxonomy('regions').term().locale('en-us').depth(3).limit(50).find()
    for term in result.get('terms', []):
        print(term['uid'])
except Exception as error:
    print('Request failed:', error)

Edge case: an empty UID returns the wrong object

import contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

term_uid = ''

try:
    result = stack.taxonomy('regions').term(term_uid).fetch()
except AttributeError as error:
    # Fires because the empty string returned a TermQuery, which has no fetch.
    print('Guard the term UID before calling fetch:', error)