Reducers

Reducers are an SDK feature that "reduce" event input to a single value for use in a Flow.

Overview

Reducers run at specific points in the flow defined by the Sym processor, and provide critical context for Flow execution.

ReducerRequiredFunction
get_approversyesThe only required reducer. Accepts an Event with a user and a target, and returns either a single User-like object, or a list of User-like objects.
get_identitynoNormally, Sym attempts to auto-discover users' identities in third-party services you integrate with based on the user's email address. If this isn't possible for whatever reason, this reducer can be used to construct the user's identity instead.

Accepts an Event, a service type, the service's external ID, and a User object, and returns either a string or None. If it returns None, the normal auto-discovery is still performed.

Examples

get_approvers

from sym.sdk.annotations import reducer
from sym.sdk.integrations import pagerduty, okta, slack

@reducer 
def get_approvers(event):
    """Returns a set of approvers, given a user and a target."""
   
    if pagerduty.is_on_call(event.user, schedule_name="prod_on_call_schedule"):
        # This is a self-approval in a DM
        return slack.user(event.user)

    if event.payload.fields["urgency"] == "High":
        # This is a self-approval in a channel
        return slack.channel("#break-glass", allow_self=True)

    on_call_mgrs = okta.users_in_group(group_id="00g12345689")
    # This would create a group DM for on-call managers
    return slack.group(on_call_mgrs)

get_identity

from sym.sdk.annotations import reducer
from sym.sdk.integrations import okta


@reducer
def get_identity(event, service_type, external_id, user):
    """For a given combination of service and user, returns an identifier for
    that user in the service; or, return None to perform automated identity
    discovery in the service."""
  
    if service_type == "aws_iam":
        # For AWS IAM, construct the user's ARN based on the external ID (for
        # AWS IAM, this is the AWS account ID) and the username portion of the
        # user's email
        return f"arn:aws:iam::{external_id}:user/{user.email.split('@')[0]}"
    elif service_type == "okta":
        # For Okta, we need to hard-code the IDs for some users because their
        # emails in Slack don't match their Okta emails.
        email_to_okta_uid = {
            "[email protected]": "00u12345678",
            "[email protected]": "00u9abcdefg",
            "[email protected]": "00uhijklmno"
        }
        
        # For all other users, return None to indicate that we want to perform
        # auto-discovery of the user's identity as normal
        return email_to_okta_uid.get(user.email, None)
      
    return None # For all other services, perform normal auto-discovery