Service Connector Interface

Connectors allow Intents Agent definitions to operate with real cloud services such as Dialogflow, Lex or Azure Bot Services. Currently, only one stable connector is provided with this library, and this is for Dialogflow ES: intents.connectors.dialogflow_es.connector.

Note

Details about the Connector interface are only useful if you intend to develop your own Service Connector (please consider raising a pull request if this is the case). If you just need to use the included Dialogflow Connector you can jump to its documentation page right away: intents.connectors.dialogflow_es.connector

Connectors are used to operate with the cloud version of the Agent, and specifically to:

  • Export an intents.Agent in a format that is natively readable by the Service

  • Predict User messages and trigger intents on the Cloud Agent

  • Handle intent fulfillment requests by Service

Connector Base class

This is the client-facing part of the interface. you will subclass the Connector base class, and clients will operate on its instances.

class Connector(agent_cls, default_session=None, default_language=None)[source]

Connect the given Agent to a Prediction Service.

Parameters
  • agent_cls (AgentType) – The Agent to connect

  • default_session (Optional[str]) – A default session ID (conversation channel) for predictions. If None, Connector will generate a random string

  • default_language (Union[LanguageCode, str, None]) – A default language for predictions. If None, Connector will use the Agent’s firs defined language.

abstract export(destination)[source]

Export the connected Agent in a format that can be read and imported natively by the Prediction service. For instance, the Dialogflow service will produce a ZIP export that can be imported from the Dialogflow console.

Note that you can also directly upload the Agent with upload().

Parameters

destination (str) – destination path of the exported Agent

abstract fulfill(fulfillment_request)[source]

This method is responsible for handling requests coming from a fulfillment interface. We are at that point in the flow when an intent was triggered/predicted, and Service is calling the webhook service for fulfillment. Refer to intents.fulfillment for a more detailed explanation.

In this method, Connector interprets the body of the request, builds a FulfillmentContext object, builds the Intent object that is references in the request, and calls its fulfill() method.

This will produce a FulfillmentResult object, that Connector will translate into a Service-compatible response (a dictionary) and return to caller.

Parameters

fulfillment_request (FulfillmentRequest) – A raw fulfillment request, as it is sent by the Prediction service (typically via a standard REST webhook call)

Return type

dict

Returns

An object containing a response that Service can read

abstract predict(message, session=None, language=None)[source]

Predict the given User message in the given session using the given language. When session or language are None, predict will use the default values that are specified in __init__().

predict will return an instance of Prediction, representing the service response.

>>> from intents.connectors import DialogflowEsConnector
>>> from example_agent import ExampleAgent
>>> df = DialogflowEsConnector('/path/to/service-account.json', ExampleAgent)
>>> prediction = df.predict("Hi, my name is Guido")
>>> prediction.intent
UserNameGive(user_name='Guido')
>>> prediction.intent.user_name
"Guido"
>>> prediction.fulfillment_text
"Hi Guido, I'm Bot"
>>> prediction.confidence
0.86
Parameters
  • message (str) – The User message to predict

  • session (Optional[str]) – Any string identifying a conversation

  • language (Union[LanguageCode, str, None]) – A LanguageCode object, or a ISO 639-1 string (e.g. “en”)

Return type

Prediction

abstract trigger(intent, session=None, language=None)[source]

Trigger the given Intent in the given session using the given language. When session or language are None, predict will use the default values that are specified in __init__().

>>> from intents.connectors import DialogflowEsConnector
>>> from example_agent import ExampleAgent, smalltalk
>>> df = DialogflowEsConnector('/path/to/service-account.json', ExampleAgent)
>>> prediction = df.trigger(smalltalk.AgentNameGive(agent_name='Alice'))
>>> prediction.intent
AgentNameGive(agent_name='Alice')
>>> prediction.fulfillment_text
"Howdy Human, I'm Alice"
>>> prediction.confidence
1.0
Parameters
  • intent (Intent) – The Intent instance to trigger

  • session (Optional[str]) – Any string identifying a conversation

  • language (Union[LanguageCode, str, None]) – A LanguageCode object, or a ISO 639-1 string (e.g. “en”)

Return type

Prediction

abstract upload()[source]

Upload the connected Agent to the Prediction Service.

Entity Mappings

Entity Mappings are used to (de-)serialize entity types and values in the communication between a Connector and its Service. This is done when

  • Connector exports Agent to Service; here system entity names (e.g. Sys.Integer) must be converted to Service name (e.g. @sys.number-integer in Dialogflow)

  • Connector processes a Prediction or Fulfillment payload; in this case, not only a reverse lookup is needed, but it may be necessary to de-serialize an entity value as well. For innstance, ISO datetime strings mut be cast to Python datetime objects

  • Connector triggers an Intent on Service; here parameter names must be converted, and values must be serialized

The base class for mappings is EntityMapping. Two builtin convenience mappings are also available: StringEntityMapping, and PatchedEntityMapping.

It is convenient to collect Connector mappings in a ServiceEntityMapping dict, which implements some utility methods related to mapping collections.

Finally, here we also define deserialize_intent_parameters(), a helper that turns a dict of parameters in the Service format and converts it into a dict of Intents entities.

class EntityMapping[source]

An Entity Mapping is a (de-)serializer for predicted Entities.

Most of the times a Mapping is not needed as the Entity can be mapped directly to its type (e.g. “3” -> Number(3)). However, prediction services such as Dialogflow may define system entities of structured types; a notable example is Dialogflow’s sys.person entity, which is returned as {“name”: “John”} and therefore needs custom logic to be mapped to Person(“John”). This is modelled in intents.connectors.dialogflow_es.entities.PersonEntityMapping.

Another notable scenario is Date/Time objects. A mapping can be used to convert time strings from the Service format to python objects. For Dialogflow ES, this is modelled in intents.connectors.dialogflow_es.entities.DateTimeEntityMapping.

property entity_cls

This is the internal entity type that is being mapped.

>>> mapping = StringEntityMapping(Sys.Integer, 'sys.number-integer')
>>> mapping.entity_cls
Sys.Integer
Return type

Type[EntityMixin]

property service_name

This is the name of the Entity in the Prediction Service domain.

>>> mapping = StringEntityMapping(Sys.Integer, 'sys.number-integer')
>>> mapping.service_name
'sys.number-integer'
Return type

str

property supported_languages

It may happen that a Prediction Service only supports an Entity for a limited set of languages. For instance, Snips NLU only supports its snips/date entity in English.

This property is set to None when the mapping is valid for all the service-supported language. If support is restricted to a subset of them, it will contain the list of language codes. Export and prediction procedures must handle accordingly.

Return type

List[LanguageCode]

abstract from_service(service_data)[source]

De-serialize the Service representation of an Entity (typically the value that is returned at prediction time) to an instance of one of the internal Entity classes in intents.model.entities

>>> date_mapping.from_service("2021-07-11")
Sys.Date(2021, 7, 11)
Parameters

service_data (Any) – A parameter value, as it is returned by the Service in a prediction/trigger response

Return type

SystemEntityMixin

Returns

the parameter value, modelled as one of the System Entity classes

abstract to_service(entity)[source]

Serialize a System Entity instance into a Service representation (typically, to be sent as a parameter of a trigger request)

>>> date_mapping.to_service(Sys.Date(2021, 7, 11))
"2021-07-11"
Parameters

entity (SystemEntityMixin) – The System Entity to serialize

Return type

Any

Returns

The serialized Entity that can be sent to Service (e.g. in a trigger request)

class StringEntityMapping(entity_cls=None, service_name=None)[source]

This is a generic EntityMapping that reads values as they are sent by the prediction service (e.g. “3” -> Sys.Integer(“3”)), and serializes by simple string conversion (e.g. Sys.Integer(3) -> “3”). This is the most common case when dealing with entities.

The System Entity to use must be defined when instantiating the mapping, for instance:

>>> StringEntityMapping(Sys.Integer, "sys.number-integer")
Parameters
  • entity_cls (Optional[Type[EntityMixin]]) – One of the Sys.* entity classes

  • service_name (Optional[str]) – Name of the corresponding entity within the Prediction Service

from_service(service_data)[source]

De-serialize the Service representation of an Entity (typically the value that is returned at prediction time) to an instance of one of the internal Entity classes in intents.model.entities

>>> date_mapping.from_service("2021-07-11")
Sys.Date(2021, 7, 11)
Parameters

service_data (Any) – A parameter value, as it is returned by the Service in a prediction/trigger response

Return type

SystemEntityMixin

Returns

the parameter value, modelled as one of the System Entity classes

to_service(entity)[source]

Serialize a System Entity instance into a Service representation (typically, to be sent as a parameter of a trigger request)

>>> date_mapping.to_service(Sys.Date(2021, 7, 11))
"2021-07-11"
Parameters

entity (SystemEntityMixin) – The System Entity to serialize

Return type

Any

Returns

The serialized Entity that can be sent to Service (e.g. in a trigger request)

class PatchedEntityMapping(entity_cls=None, builtin_entity=None)[source]

Different Prediction Services support different entities. For instance, Sys.Color is native in Dialogflow, but is not supported in Snips. In some cases, we can patch missing system entities with custom ones; for instance, Sys.Color can be patched with builtin I_IntentsColor. PatchedEntityMapping can be use to define mappings for system entities that are patched with custom ones.

Connectors that use patched entities must define logic to handle PatchedEntityMapping in their export procedures.

By default, builtin_entity.name is used as Service entity name, and values are (de)serialized as simple strings. If a Connector have different required, it should define a custom subclass of PatchedEntityMapping.

Parameters
property service_name

This is the name of the Entity in the Prediction Service domain.

>>> mapping = StringEntityMapping(Sys.Integer, 'sys.number-integer')
>>> mapping.service_name
'sys.number-integer'
from_service(service_data)[source]

De-serialize the Service representation of an Entity (typically the value that is returned at prediction time) to an instance of one of the internal Entity classes in intents.model.entities

>>> date_mapping.from_service("2021-07-11")
Sys.Date(2021, 7, 11)
Parameters

service_data (Any) – A parameter value, as it is returned by the Service in a prediction/trigger response

Return type

SystemEntityMixin

Returns

the parameter value, modelled as one of the System Entity classes

to_service(entity)[source]

Serialize a System Entity instance into a Service representation (typically, to be sent as a parameter of a trigger request)

>>> date_mapping.to_service(Sys.Date(2021, 7, 11))
"2021-07-11"
Parameters

entity (SystemEntityMixin) – The System Entity to serialize

Return type

Any

Returns

The serialized Entity that can be sent to Service (e.g. in a trigger request)

class ServiceEntityMappings[source]

Models a collection of entity mappings, in the form of a dict where the key is a System entity class (i.e. inherits from SystemEntityMixin) and the value is a EntityMapping. In addition to a standard dict, these features are added:

  • Instantiate from a list of mappings with from_list()

  • Flexible lookup with ServiceEntityMapping.lookup()

lookup(entity_cls)[source]

Return the mapping in the dictionary that is associated with the given entity_cls. In addition to a simple mappings[entity_cls], this method also implements a fallback for Custom Entities. That is, when a Custom Entity is not in the mapping dict (typically they are not), retrieve return an on-the-fly mapping generated with custom_entity_mapping().

Parameters

entity_cls (Type[EntityMixin]) – The Entity class to lookup

Return type

EntityMapping

Returns

The mapping that refers to the given Entity class

Raises

KeyError – If no mapping exists that can be used for entity_cls

custom_entity_mapping(entity_cls)[source]

Generate an entity mapping on the fly for the given custom entity. This is needed because, while System entities are static, Custom ones need to be handled dynamically at run time.

By default, this returns a simple StringEntityMapping, where service_name is entity_cls.name. Connectors may override this method to implement custom behavior.

Parameters

entity_cls (Type[EntityMixin]) – A Custom Entity for which a mapping will be generated

Return type

EntityMapping

Returns

A mapping for the given Entity

service_name(entity_cls)[source]

Return the name of the given entity in the specific service; this can be the class name itself, or an EntityMapping lookup in the case of System Entities.

For instance, a Sys.Person Entity will need to be looked up in the mappings to find out its service name (sys.person in Dialogflow, AMAZON.Person in Alexa, and so on). A custom entity (e.g. PizzaType) will use its class name instead.

Parameters

entity_cls (Type[EntityMixin]) –

is_mapped(entity_cls, lang)[source]

Return False if no mapping is defined for the given entity. Also return False if a mapping exists, but the mapping defines supported_languages and the given language is not in the list.

Parameters
  • entity_cls (Type[EntityMixin]) – The Entity class to lookup

  • lang (LanguageCode) – The language that should be supported by the mapping

Return type

bool

classmethod from_list(mapping_list)[source]

Convenience method for building a mapping from a list, instead of specifying the whole dict. See Dialogflow’s entities module for an example.

Parameters

mapping_list (List[EntityMapping]) – The mappings that will be used to build the ServiceEntityMapping dict

Return type

ServiceEntityMappings

Returns

A ServiceEntityMapping with the given mappings

deserialize_intent_parameters(service_parameters, intent_cls, mappings)[source]

Cast parameters from Service format to Intents format according to the given schema. Typically this happens when a Connector has to turn prediction parameters into Intents entities.

Parameters
  • service_parameters (Dict[str, Any]) – The parameters dict, as it is returned by a Prediction Service

  • intent_cls (Type[Intent]) – The Intent parameters will be matched against

  • mappings (ServiceEntityMappings) – The Service Entity Mappings, to deserialize parameter values

Return type

Dict[str, EntityMixin]

Returns

A dictionary like service_parameters, but all the values are converted to native Intents Entity objects.

Prediction Base Class

class Prediction(intent, confidence, fulfillment_messages, fulfillment_text=None)[source]

One of the core uses of Service Connectors is to predict user utterances, or programmatically trigger intents. This class models the result of such predictions and triggers.

You will typically obtain Prediction objects from Connector methods predict() and trigger().

Parameters
  • intent (Intent) – An instance of the predicted Intent

  • confidence (float) – A confidence value on the service prediction

  • fulfillment_messages (IntentResponseDict) – A map of Intent Responses, as they were returned by the Service.

  • fulfillment_text (Optional[str]) – A plain-text version of the response

Fulfillment

class FulfillmentRequest(body, headers=<factory>)[source]

The purpose of this class is to uniform fulfillment request payloads, with respect to the protocol or framework they are sent with (REST, websocket, lambda, …)

Note that the actual parsing comes later, when a Connector receives the Request, and models it as a FulfillmentContext.

Also, it is not necessary to model a FulfillmentResponse counterpart: we can assume any fulfillment response can be modeled with a JSON-serializable dict.

Parameters
  • body (dict) – A dict representing the request body

  • headers (dict) – An optional dict containing the request headers, if present

class WebhookConfiguration(url, headers=<factory>)[source]

Specifies connection parameters for the Agent’s webhook. This is the endpoint that is called by services to fulfill an intent.

Parameters
  • url (str) – An URL to call for fulfillments. Services may require it to be HTTPS

  • headers (Dict[str, str]) – Headers to include in fulfillment requests. Not all services may support this