Chalk home page
  1. Resolvers
  2. Tags

Tags allow you to scope requests within an environment. Both tags and environment need to match for a resolver to be a candidate to execute.

You might consider using tags, for example, to change out whether you want to use a sandbox environment for a vendor, or to bypass the vendor and return constant values in a staging environment.

Specifying tags

Tags can be either a string value, or a key-value pair. As a best practice (and fitting with recommendations from other services like Datadog), we recommend using key-value pairs, but the choice is yours.

There are two ways to specify tags on resolvers:

  • “key” - As a single scalar string.
  • “key:value” - As a string value representing a key-value pair.

Resolvers take one or many tags, all of which need to match for the resolver to run.

def single_tag(...) -> ...:

@online(tags=["key:value", "key2:value2"])
def many_tags(...) -> ...:

When tagged resolvers run

Like Environments, tags control when resolvers run based on the Online Context or Training Context matching the tags provided to the resolver decorator. Resolvers optionally take a keyword argument named tags that can take one of three types:

  • Unassigned (default) - The resolver will be a candidate to run for every set of tags.
  • String value - The resolver will run only if this tag is provided.
  • List of strings - The resolver will run in all of the specified tags match.

If your resolver is tagged only by a key (not a key-value pair), and the request context contains a key-value pair such that the resolver’s tag (a key only) matches they key of a key-value pair in the context, the resolver will be eligible to run. For example:

Resolver TagRequest ContextMatches?
api api Yes
api api:live Yes
[api:live, mock-phone] [api:live, mock-phone] Yes
[api:live, mock-phone] api:live No
api:live api No
api:fixture api:live No


Frequently, you’ll want to combine tags and Environments, as below. This span uses a constant value in staging when the tag api takes the value fixture, uses the sandboxed fraud vendor in staging when the tag api takes the value live, and uses the production fraud vendor in production.

@online(environment="staging", tags="api:fixture")
def fraud_score_fixture(email: -> UserFeatures.fraud_score:
    if email == "":
        return 100
    return 50

@online(environment="staging", tags="api:live")
def fraud_score_sandbox(email: -> UserFeatures.fraud_score:
    return api_vendor_sandbox.fraud_score(email, profile="dev")

def fraud_score_prod(email: -> UserFeatures.fraud_score:
    return api_vendor_live.fraud_score(email)