Skip to main content

A Python package to assist with developing services conforming to the Soul Machines Skill REST API.

Project description

smskillsdk (Python)

The Skills Python SDK package contains data types for the session and execute endpoints specified within the Skills REST API, along with a range of utility functions for working with the memory data structure.

Installation

This package is intended for use with Python 3.8 and above.

pip install smskillsdk

Usage

Accessing request/response models

The request/response models are implemented with Pydantic, a library which assists with validation and type-checking.

from smskillsdk.models.api import (
    SessionRequest,
    SessionResponse,
    ExecuteRequest,
    ExecuteResponse
)

Sub-models used within these request and response models can also be imported using

from smskillsdk.models.api import (
    Output,
    Intent,
    Memory,
    Variables
)

In general, a developer should implement separate handler functions for the session and execute endpoints which takes a SessionRequest or ExecuteRequest as an argument and returns a SessionResponse or ExecuteResponse respectively. These objects can be serialized to JSON and returned within the HTTP response body. An example implementation of a handler function for generating an ExecuteResponse and a route method is shown below.

# execute endpoint handler containing response generation logic
def execute_handler(request: ExecuteRequest) -> ExecuteResponse:

    # response generation logic here

    variables = Variables(public={ "card": { ... }})

    output = Output(
        text="",
        variables=variables
    )

    response = ExecuteResponse(
        output=output,
        memory=[],
        endConversation=True,
    )

    return response

# route method (using FastAPI syntax)
@app.post("/execute", status_code=status.HTTP_200_OK, response_model=ExecuteResponse, response_model_exclude_unset=True)
def execute(request: ExecuteRequest):
    return execute_handler(request)

Deserializing requests

Python dictionary objects can be deserialized into models.

raw_request = {
    "key": value,
    ...
}

request = ExecuteRequest(**raw_request)

Pydantic will throw a ValidationError if any of the keys or value types does not match the expected keys and values.

Serializing responses

Pydantic models can be converted into JSON strings or dictionary objects.

request = ExecuteRequest(**{'text': 1, 'projectId': '111', 'sessionId': '123', 'memory': []})

json_str = request.json()
dict_obj = request.dict()

Working with memory

The memory field within the request and response models of the session/execute endpoints can be used to persist state between conversation turns and share information between skills within a single session.

The data structure is comprised of an array of Memory objects

class Memory(BaseModel):
    name: str
    value: Any
    session_id: Optional[str]
    scope: Optional[MemoryScope] = None

where the name field acts as a key. The optional session_id field can be used to differentiate between objects having the same name value, while the optional scope field can be used to control whether objects are shared between skills or remain private to a single skill (the default scope is MemoryScope.PRIVATE). Setting scope: MemoryScope.PUBLIC will mean that this particular memory object will be viewable and editable by all skills within a particular session.

Note that memory objects with the same name but different session ID/scope will be treated as unique.

We offer a range of utility functions to work with the memory data structure which can be imported from smskillsdk.utils.memory

serialize_memory(data: dict, session_id: Union[str, None] = None, scope: MemoryScope = MemoryScope.PRIVATE) -> List[Memory]

Converts a Python dict into a list of Memory objects with an optional session ID and scope.

Arguments:

  • data: dict: A Python dictionary to be converted; keys should be strings
  • session_id: str: An optional session ID to be assigned to each Memory object
  • scope: MemoryScope: An optional scope to determine if the memory objects should be able to be shared with other skills within the session (default: MemoryScope.PRIVATE)

Returns:

  • List[Memory]: A list of Memory objects

deserialize_memory(memories: List[Memory], session_id: Union[str, None] = None, scope: Union[MemoryScope, None] = None) -> Dict[str, Any]

Converts a list of Memory objects into a Python dict, filtered using an optional session ID or scope value. If there are multiple valid memory objects with the same name, the value closest to the end of the memories list will be returned.

Arguments:

  • memories: List[Memory]: A list of Memory objects to be converted
  • session_id: str: If provided, will only deserialize Memory objects with a matching session ID
  • scope: MemoryScope: If provided, will only deserialize memory objects with a matching scope (otherwise all memory objects will be treated as valid)

Returns:

  • Dict[str, Any]

set_memory_value(memories: List[Memory], key: str, value: Any, session_id: Union[str, None] = None, scope: MemoryScope = MemoryScope.PRIVATE) -> None

Sets a value in a list of Memory objects corresponding to a key and optional session ID or scope. If an object with a matching key/session ID/scope exists, its value will be overwritten.

Arguments:

  • memories: List[Memory]: The list of Memory objects which will be operated on
  • key: str: The key to search for
  • value: Any: The value to set
  • session_id: str: If provided, only Memory objects with a matching session ID will be considered; if none are found, a new memory object with a session ID will be created
  • scope: MemoryScope: If provided, only memory objects with a matching scope will be considered (defaults to MemoryScope.PRIVATE)

Returns:

  • No return value, the list of Memory objects is modified in-place

get_memory_value(memories: List[Memory], key: str, session_id: Union[str, None] = None, scope: Union[MemoryScope, None] = None) -> Tuple[bool, Any]

Retrieves a value from a list of Memory objects corresponding to a key and optional session ID or scope value.

Arguments:

  • memories: List[Memory]: The list of Memory objects to be searched
  • key: str: The key to search for
  • session_id: str: If provided, only Memory objects with a matching session ID will be considered
  • scope: MemoryScope: If provided, only memory objects with a matching scope will be considered (otherwise all objects will be considered)

Returns:

  • Tuple[bool, Any]: A flag indicating whether the key/value pair was found, and the corresponding value; this can be unpacked as shown below
found, value = getMemoryValue(memories, "key", "session_id")

Common session memory values

We have defined two memory objects which can be used to share information in a common format between skills:

class UserIdentity(BaseModel):
    firstName: Optional[str] = None
    lastName: Optional[str] = None
    preferredName: Optional[str] = None
    id: Optional[str] = None

class UserLocation(BaseModel):
    city: Optional[str] = None
    country: Optional[str] = None

Users may define their own objects to work across their skills, or to expose information to other skills. These values can be set and retrieved from a memory array using the following helper functions:

  • set_user_identity(memories: List[Memory], *, first_name: Optional[str] = None, last_name: Optional[str] = None, preferred_name: Optional[str] = None, id: Optional[str] = None) -> None
  • get_user_identity(memories: List[Memory]) -> Optional[UserIdentity]
  • set_user_location(memories: List[Memory], *, city: Optional[str] = None, country: Optional[str] = None) -> None
  • get_user_location(memories: List[Memory]) -> Optional[UserLocation]

The classes and helper functions can be accessed from the smskillsdk.utils.memory_values namespace.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

smskillsdk-0.2.0.tar.gz (19.8 kB view details)

Uploaded Source

Built Distribution

smskillsdk-0.2.0-py3-none-any.whl (14.0 kB view details)

Uploaded Python 3

File details

Details for the file smskillsdk-0.2.0.tar.gz.

File metadata

  • Download URL: smskillsdk-0.2.0.tar.gz
  • Upload date:
  • Size: 19.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/34.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.9 tqdm/4.64.0 importlib-metadata/4.11.3 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.9.12

File hashes

Hashes for smskillsdk-0.2.0.tar.gz
Algorithm Hash digest
SHA256 9e14d377460c4695d7586b16027ea9c0526dba26ca01a19f87809bd5b46205c6
MD5 af7812328a31a27be6c2d5e3e4f7c65d
BLAKE2b-256 0e4c937915250a20619e8c8639adff15ce2e46d77cdf81fd6451b92e7f558b7a

See more details on using hashes here.

File details

Details for the file smskillsdk-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: smskillsdk-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 14.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/34.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.9 tqdm/4.64.0 importlib-metadata/4.11.3 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.9.12

File hashes

Hashes for smskillsdk-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 eff65c1679cc7416b655065544397fd0b82842d7410baea587d3e399afed10dc
MD5 9c0b110097ad06b14fc0243ddd8763c9
BLAKE2b-256 6414be5c6a9d1956c61606f85f3d997a6535aa26fd8df4d1dff4cb5b8e650dcf

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page