SQL Plugin
Technical References
Class Reference:
smarter.apps.plugin.plugin.sql.ApiPluginDjango ORM Model:
smarter.apps.plugin.models.PluginDataApi
A PLugin that uses a remote SQL database server to retrieve its return data
Note
This is a complex AI resource that exists within the following class hierarchy
Smarter Secret: The authentication credential for the remote SQL database connection.
Smarter SQL Connection: The complete connection configuration to the remote SQL database server (host, port, secret, ssh key, username, etc.).
Smarter SQL Plugin: The plugin that defines the SQL query and it’s parameters to run against the remote SQL database server.
Smarter Chatbot: The prompting resource (Chatbot, Agent, Workflow unit, etcetera) that includes the SQL Plugin:
apiVersion: smarter.sh/v1
kind: Secret
metadata:
description: |
An example secret manifest. This is a real credential used for authenticating to
the Smarter Remote SQL test database. This is a public-access test database
used for development and testing purposes only. Do not use this credential
for production purposes. Password value is the same as the user.
See the annotations below for connection details.
name: smarter_test_user
version: 1.1.0
tags:
- example
- test
- stackademy
annotations:
- smarter.sh/test-db/host: sql.lawrencemcdaniel.com
- smarter.sh/test-db/port: "3306"
- smarter.sh/test-db/db: smarter_test_db
- smarter.sh/test-db/user: smarter_test_user
- smarter.sh/test-db/pwd: smarter_test_user
- smarter.sh/test-db/access: anyone can access this test database
spec:
config:
description: smarter_test_user password. Password value is the same as the user.
value: smarter_test_user
apiVersion: smarter.sh/v1
kind: SqlConnection
metadata:
description: Sql database connection pwd for smarter_test_db at sql.lawrencemcdaniel.com:3306
name: smarter_test_db
tags:
- test
- sample
- smarter
annotations:
- smarter.sh/smarter-test-db/owner: smarter-test-user
- smarter.sh/smarter-test-db/creator: QA Team
- smarter.sh/smarter-test-db/purpose: unit testing
- smarter.sh/smarter-test-db/release-date: 2024-06-15
- smarter.sh/smarter-test-db/backward-compatibility: true
version: 0.1.0
spec:
connection:
authenticationMethod: tcpip
database: smarter_test_db
dbEngine: django.db.backends.mysql
username: smarter_test_user
hostname: sql.lawrencemcdaniel.com
maxOverflow: 10
password: smarter_test_user
poolSize: 5
port: 3306
timeout: 30
useSsl: false
apiVersion: smarter.sh/v1
kind: SqlPlugin
metadata:
description: Online course catalogue inquiries for fictional Stackademy University that only offers computer science degrees programs.
name: stackademy_sql
pluginClass: sql
version: 0.1.0
tags:
- db
- sql
- database
annotations:
- smarter.sh/stackademy-sql/display-name: Stackademy SQL
- smarter.sh/stackademy-sql/icon: https://example.com/stackademy-sql-icon.png
- smarter.sh/stackademy-sql/documentation-url: https://docs.stackademy.com/sql
- smarter.sh/stackademy-sql/contact-email: no-reply@example.com
spec:
selector:
directive: always
prompt:
provider: openai
systemRole: >
You are a helpful student advisor at the fictional Stackademy University that only offers computer science
degrees programs. Whenever possible you should defer to the tool calls provided for additional information
about the courses offered by Stackademy University. Questions unrelated to the courses or Stackademy University
should be answered with "I am sorry, but I can only provide information about the courses offered by Stackademy University."
model: gpt-4o-mini
temperature: 0.5
maxTokens: 2048
connection: smarter_test_db
sqlData:
description: >
returns up to 10 rows of course detail data, filtered by the maximum cost a student is willing
to pay for a course and the area of specialization.
limit: 10
sqlQuery: SELECT c.course_code, c.course_name, c.description, c.cost, prerequisite.course_code AS prerequisite_course_code, prerequisite.course_name AS prerequisite_course_name
FROM courses c
LEFT JOIN courses prerequisite ON c.prerequisite_id = prerequisite.course_id
WHERE ((c.description LIKE CONCAT('%', {description}, '%')) OR ({description} IS NULL))
AND (c.cost <= {max_cost} OR {max_cost} IS NULL)
ORDER BY c.prerequisite_id;
parameters:
- description: the maximum cost that a student is willing to pay for a course.
enum: null
name: max_cost
required: false
type: number
- description: areas of specialization for courses in the catalogue.
enum:
- AI
- mobile
- web
- database
- network
- neural networks
name: description
required: false
type: string
testValues:
- name: description
value: AI
- name: max_cost
value: 500
apiVersion: smarter.sh/v1
kind: Chatbot
metadata:
name: stackademy_sql
description: Stackademy University course catalogue inquiries using the Stackademy SQL plugin.
version: 1.0.0
tags:
- stackademy
- sql
- chatbot
annotations:
- smarter.sh/chatbot/stackademy-sql/creator: QA Team
- smarter.sh/chatbot/stackademy-sql/purpose: chatbot for Stackademy course catalogue inquiries
- smarter.sh/chatbot/stackademy-sql/release-date: 2024-06-15
- smarter.sh/chatbot/stackademy-sql/backward-compatibility: true
- smarter.sh/chatbot/stackademy-sql/note: |
Uses SQL plugin to answer course catalogue questions.
Very fast and accurate when the database is well-structured.
Leverages cache for improved performance.
spec:
config:
deployed: false
provider: openai
defaultModel: gpt-4o-mini
defaultSystemRole: >
You are a helpful assistant. When given the opportunity to utilize
function calling, you should always do so. This will allow you to
provide the best possible responses to the user. DO NOT GUESS. IF
YOU DON'T KNOW THE ANSWER, RESPOND THAT YOU DON'T KNOW.
defaultTemperature: 0.5
defaultMaxTokens: 1024
appName: Stackademy SQL Chatbot
appAssistant: Stanley
appWelcomeMessage: Welcome to Stackademy SQL Chatbot! How can I help you today?
appExamplePrompts:
- "Do you offer any courses on AI?"
- "My budget is $1,000. What courses can I take?"
- "I want to study programming. What do you suggest?"
appPlaceholder: "Ask me anything about Stackademy courses..."
appInfoUrl: https://stackademy.edu/online-courses
plugins:
- stackademy_sql
functions: []
- exception smarter.apps.plugin.plugin.sql.SmarterSqlPluginError(message='')[source]
Bases:
SmarterPluginErrorBase class for all SQL plugin errors.
- __init__(message='')
- add_note(object, /)
Exception.add_note(note) – add a note to the exception
- args
- property get_formatted_err_message
- with_traceback(object, /)
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
- class smarter.apps.plugin.plugin.sql.SqlPlugin(*args, manifest=None, **kwargs)[source]
Bases:
PluginBaseImplements a plugin that executes SQL queries on a remote SQL database server to retrieve data.
This class provides the logic for integrating SQL-based plugins into the Smarter platform. It supports manifest-driven configuration, parameter validation, and secure query execution. The plugin can be instantiated from either a manifest (Pydantic model) or an existing Django ORM instance.
Key Features:
Accepts plugin configuration via manifest or ORM model.
Validates and recasts parameter definitions to conform to OpenAI function calling schema.
Interpolates user-provided arguments into SQL queries, with basic escaping for safety.
Executes queries using a remote SQL connection and returns results in JSON format.
Handles errors related to configuration, connection, and query execution.
Provides example manifest generation for testing and documentation.
Usage:
Instantiate with a manifest or ORM model.
Use tool_call_fetch_plugin_response() to execute SQL queries with arguments from OpenAI tool calls.
Use plugin_data_django_model to convert manifest data to a Django ORM-compatible dictionary.
Use example_manifest() to generate a sample manifest for this plugin type.
Note
SQL queries are interpolated using simple string replacement; ensure queries are safe and parameterized.
The maximum query length is limited to prevent excessive database load.
Logging is controlled via feature switches and log level settings.
See also
OpenAI Function Calling: https://platform.openai.com/docs/guides/function-calling?api-mode=chat
Smarter Plugin Manifest Documentation
- SAMPluginType
alias of
SAMSqlPlugin
- __init__(*args, manifest=None, **kwargs)[source]
Initialize a PluginBase instance.
Key features:
Lazy instantiation of class properties.
Supports multiple initialization methods including manifest, database model, and YAML/JSON.
Integrates with Django ORM for plugin metadata management.
Utilizes Pydantic models for manifest validation and serialization.
Provides hooks for plugin selection and prompt customization.
Ensures plugin readiness and validation before use.
Sends signals upon plugin creation or update.
This constructor supports several ways to create a plugin object:
Manifest-based initialization:
Pass a Pydantic model instance via the
manifestargument. This is the preferred method and is typically used when loading plugins from a manifest broker.Database model initialization:
Provide a Django model plugin ID via
plugin_idor aPluginMetainstance viaplugin_metato load an existing plugin from the database.YAML/JSON manifest initialization:
Supply a YAML or JSON string (or dictionary) via the
dataargument to create a plugin from a manifest representation.
See
./data/sample-plugins/everlasting-gobstopper.yamlfor an example manifest.The constructor sets up internal state, initializes plugin properties, and triggers plugin creation or update logic as needed. It also sends signals when the plugin is ready.
- Parameters:
user_profile (Optional[UserProfile]) – The user profile associated with the plugin.
selected (bool) – Whether the plugin is initially selected.
api_version (Optional[str]) – The API version for the plugin manifest.
manifest (Optional[SAMPluginCommon]) – A Pydantic model representing the plugin manifest.
plugin_id (Optional[int]) – The Django ORM plugin ID.
plugin_meta (Optional[PluginMeta]) – The Django ORM PluginMeta instance.
data (Union[dict[str, Any], str, None]) – YAML/JSON manifest as a string or dictionary.
name (Optional[str]) – The name of the plugin.
kwargs – Additional keyword arguments.
- property account: Account | None
Returns the account for the current user. Handle lazy instantiation from user or user_profile.
- Returns:
The account for the current user.
- Return type:
Account or None
- property account_number: str | None
A helper function to get the account number from the account.
- Returns:
The account number for the current account.
- Return type:
str or None
- property accountmixin_ready_state: str
Returns a string representation of the AccountMixin ready state.
- Returns:
String representation of the AccountMixin ready state.
- Return type:
- property amnesty_urls: list[str]
Returns a list of URLs that are exempt from certain checks.
This is a placeholder and should be overridden in subclasses.
- property api_version: str
Return the api version of the plugin.
- Returns:
The api version of the plugin.
- Return type:
- Raises:
SAMValidationError – If the api version is not valid.
See also
smarter.common.api.SmarterApiVersions
SMARTER_API_MANIFEST_COMPATIBILITY
- authenticate(api_token)
Authenticate the user using the provided API token. The api_token will have been generated by the SmarterTokenAuthentication class and passed by the caller in the Authorization header of the request.
Example
Authorization: Token <api_token>
- cache_invalidations()
Invalidate cached properties related to the plugin.
This method is used to clear any cached data associated with the plugin instance, such as cached Django ORM model instances or serializers. It ensures that subsequent accesses to these properties will fetch fresh data from the database or re-instantiate serializers as needed.
The following properties are invalidated:
user_profileplugin_metaplugin_selectorplugin_promptplugin_data
- Return type:
- camel_to_snake(data)
Converts camelCase strings, dictionary keys, or lists of such, to snake_case format.
- Parameters:
data (str, dict, or list) – The input to convert. Can be a string, a dictionary (with camelCase keys), or a list containing strings or dictionaries.
- Returns:
The converted data in snake_case format. Returns a string, dictionary, or list, matching the input type.
- Return type:
Note
For dictionaries, only keys are converted. Values are preserved as-is, except for nested dictionaries, which are also converted.
Spaces in keys are replaced with underscores.
Multiple consecutive underscores are collapsed into a single underscore.
Nested dictionaries and lists are processed recursively.
Warning
If the input is not a string, dictionary, or list, a
SmarterValueErroris raised.Example usage:
from smarter.common.utils import camel_to_snake # Convert a string print(camel_to_snake("userName")) # Output: user_name # Convert a dictionary data = { "userName": "alice", "userProfile": { "firstName": "Alice", "lastName": "Smith" } } print(camel_to_snake(data)) # Output: {'user_name': 'alice', 'user_profile': {'first_name': 'Alice', 'last_name': 'Smith'}} # Convert a list of strings print(camel_to_snake(["firstName", "lastName"])) # Output: ['first_name', 'last_name']
- clone(new_name=None)
Clone a plugin.
- Parameters:
new_name (Optional[str]) – The new name for the cloned plugin. If None, a name will be generated.
- Returns:
The id of the cloned plugin if successful, False otherwise.
- Return type:
Optional[int]
- Raises:
SmarterPluginError – If the plugin is not ready.
- create()[source]
Create the plugin in the database.
This method handles the creation of the SQL plugin in the database by invoking the superclass’s create method. It ensures that all necessary data is properly initialized and stored according to the plugin’s configuration.
Note
This method currently does not implement any additional logic beyond calling the superclass’s create method.
- Returns:
None
- Return type:
None
- property custom_tool: dict[str, Any]
Return the plugin tool definition for OpenAI function calling.
See the OpenAI documentation: https://platform.openai.com/docs/assistants/tools/function-calling/quickstart
Example:
tools = [ { "type": "function", "function": { "name": "get_current_temperature", "description": "Get the current temperature for a specific location", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city and state, e.g., San Francisco, CA" }, "unit": { "type": "string", "enum": ["Celsius", "Fahrenheit"], "description": "The temperature unit to use. Infer this from the user's location." } }, "required": ["location", "unit"] } } } ]
See also
smarter.lib.openai.enum.OpenAIToolCallsmarter.lib.openai.enum.OpenAIToolTypes
- customize_prompt(messages)
Modify the system prompt based on the plugin object.
- property data: dict | None
Return the plugin as a dictionary.
- Returns:
The plugin as a dictionary if ready, None otherwise.
- Return type:
Optional[dict]
- data_to_dict(data)
Converts data to a dictionary, handling different types of input.
This method accepts either a dictionary or a string. If a string is provided, it will attempt to parse it as JSON first, and if that fails, as YAML. If parsing fails or the data type is unsupported, a SmarterValueError is raised.
- delete()
Delete a plugin.
- Returns:
True if the plugin was deleted successfully, False otherwise.
- Return type:
- Raises:
SmarterPluginError – If the plugin is not ready.
- classmethod example_manifest(kwargs=None)[source]
Use Pydantic models to generate an example manifest for SqlPlugin.
This class method creates a sample manifest dictionary for the SqlPlugin, illustrating the required structure and fields. The example manifest includes metadata, specification, and SQL query details, demonstrating how to configure the plugin for use within the Smarter platform.
- Parameters:
kwargs (
Optional[dict]) – Optional dictionary of additional fields to include in the manifest.- Returns:
A dictionary representing the example manifest for the SqlPlugin.
- Return type:
See Also:
smarter.lib.manifest.enum.SAMKeyssmarter.lib.manifest.enum.SAMMetadataKeyssmarter.apps.plugin.manifest.models.sql_plugin.model.SAMSqlPluginsmarter.apps.plugin.manifest.models.common.plugin.enum.SAMPluginCommonMetadataClassValuessmarter.apps.plugin.manifest.models.common.plugin.enum.SAMPluginCommonSpecSelectorKeyDirectiveValuessmarter.apps.plugin.manifest.models.common.plugin.enum.SAMPluginCommonSpecPromptKeys
- property formatted_class_name: str
Returns the class name in a formatted string along with the name of this mixin.
- property formatted_pluginbase_class_name: str
Return the formatted class name for logging.
- Returns:
The formatted class name.
- Return type:
- property formatted_state_not_ready: str
Returns the not-ready state formatted for logging.
- Returns:
The formatted not-ready state as a string.
- Return type:
- property formatted_state_ready: str
Returns the readiness state formatted for logging.
- Returns:
The formatted readiness state as a string.
- Return type:
- property function_calling_identifier: str
Return the function calling plugin.
- Returns:
The function calling plugin identifier.
- Return type:
- Raises:
SmarterPluginError – If the plugin is not ready.
- property function_parameters: dict[str, Any] | None
Fetch the function parameters from the Django model. Return the function parameters in a dictionary formatted according to the OpenAI function calling schema.
- property id: int | None
Return the Django ORM PluginMeta id.
- Returns:
The id of the plugin.
- Return type:
Optional[int]
- property is_accountmixin_ready: bool
Returns True if the AccountMixin is ready to be used. This is a convenience property that checks if the account and user are initialized. AccountMixin is considered ready if: - self.user is an instance of User - self.user_profile is an instance of UserProfile - self.account is an instance of Account
- Returns:
True if the AccountMixin is ready to be used.
- Return type:
- property is_authenticated: bool
Returns True if the user is authenticated and is associated with an Account.
- is_valid_yaml(data)
Validate a yaml string.
- property kind: str
Returns the kind identifier for this plugin.
This property provides the canonical string used to distinguish the plugin type within the Smarter platform. The value is derived from the plugin manifest constant and is used for registration, serialization, and manifest validation.
The kind is typically referenced in plugin manifests and API payloads to ensure the correct plugin logic is invoked for SQL-based plugins.
- Returns:
The string identifier representing the plugin kind.
- Return type:
- Example:
>>> plugin = SqlPlugin() >>> plugin.kind 'sql'
- log_account_mixin_ready_status()
Logs the ready status of the AccountMixin.
- property manifest: SAMSqlPlugin | None
Retrieve the manifest for this plugin as a Pydantic model.
This property returns the plugin’s manifest, which contains the configuration and specification for the SQL plugin in the form of a validated Pydantic model. If the manifest is not already set and the plugin is ready, it will be constructed from the current plugin data using the appropriate Pydantic model class.
The manifest is essential for validating plugin configuration, generating OpenAI-compatible schemas, and ensuring the plugin operates with the correct parameters and metadata.
- Returns:
The manifest as a
SAMSqlPluginPydantic model instance, orNoneif unavailable.- Return type:
Optional[SAMSqlPlugin]
Note
If the manifest is not present but the plugin is ready, this property will attempt to reconstruct the manifest from the plugin’s JSON representation.
- Example:
>>> plugin = SqlPlugin() >>> manifest = plugin.manifest >>> print(manifest.spec.sqlData.sql_query) SELECT * FROM auth_user WHERE username = '{username}';
- mask_string(string='', mask_char='*', mask_length=4, string_length=8)
Masks a string for secure logging.
This utility function masks all but the last unmasked_chars characters of the input string, replacing them with asterisks. It is useful for logging sensitive information like API keys or passwords.
- property metadata_class: str | None
Return the metadata class, PluginMeta.plugin_class
- Returns:
The metadata class name.
- Return type:
Optional[str]
See also:
smarter.apps.plugin.models.PluginMeta
- property name: str | None
Return the name of the plugin.
- Returns:
The name of the plugin.
- Return type:
Optional[str]
- Raises:
SmarterPluginError – If the PluginMeta is not of the expected type.
- classmethod parameter_factory(name, data_type, description, enum=None, required=False, default=None)
Factory method to create a parameter dictionary for the SQL plugin.
- Parameters:
name (str) – The name of the parameter.
data_type (str) – The data type of the parameter.
description (str) – The description of the parameter.
enum (Optional[list]) – An optional list of enumerated values for the parameter.
required (Optional[bool]) – Whether the parameter is required. Default is False.
default (Optional[Any]) – The default value of the parameter. Default is None.
- Returns:
A dictionary representing the parameter.
- Return type:
- pascal_to_snake(name)
Converts a PascalCase string to pascal_case snake_case format.
- Parameters:
name (str) – The PascalCase string to convert.
- Returns:
The converted string in snake_case format.
- Return type:
Note
Spaces in the input string are replaced with underscores.
Multiple consecutive underscores are collapsed into a single underscore.
Example usage:
from smarter.common.utils import pascal_to_snake print(pascal_to_snake("UserProfile")) # Output: user_profile print(pascal_to_snake("FirstName LastName")) # Output: first_name_last_name
- property plugin_data: PluginDataSql | None
Return the plugin data as a Django ORM instance.
This property provides access to the plugin’s data in the form of a Django ORM model instance. It handles multiple scenarios for retrieving or constructing the plugin data:
If the plugin data has already been set, it is returned directly.
If both a manifest and plugin metadata are present, the plugin data is constructed from the manifest and metadata.
If only plugin metadata is present, the plugin data is retrieved from the database using the metadata.
If neither is available, the property returns
None.
This logic ensures that the plugin data is always consistent with the current manifest and database state, supporting both creation and update workflows.
- Returns:
The plugin data as a
PluginDataSqlDjango ORM instance, orNoneif unavailable.- Return type:
Optional[PluginDataSql]
- Raises:
PluginDataSql.DoesNotExist – If the plugin metadata is present but no corresponding database entry exists.
Note
This property does not create new database entries; it only retrieves or constructs plugin data based on existing manifest and metadata.
- Example:
>>> plugin = SqlPlugin() >>> data = plugin.plugin_data >>> print(data.sql_query) SELECT * FROM auth_user WHERE username = '{username}';
- property plugin_data_class: Type[PluginDataSql]
Return the Django ORM model class used for plugin data.
This property provides the class reference for the Django model that stores SQL plugin data in the Smarter platform. It is useful for type checking, serialization, and for constructing new instances of plugin data objects.
The returned class can be used to create, query, or update plugin data records in the database. This is especially relevant when integrating with Django’s ORM or when performing migrations and schema validation.
- Returns:
The Django ORM model class for SQL plugin data.
- Return type:
Type[PluginDataSql]
- Example:
>>> plugin = SqlPlugin() >>> model_cls = plugin.plugin_data_class >>> isinstance(model_cls(), PluginDataSql) True
- property plugin_data_django_model: dict[str, Any] | None
Transform the Pydantic model to the PluginDataSql Django ORM model and return the plugin data definition as a JSON object.
See the OpenAI documentation: https://platform.openai.com/docs/guides/function-calling?api-mode=chat
The Pydantic ‘Parameters’ model is not directly compatible with OpenAI’s function calling schema, and our Django ORM model expects a dictionary format for the parameters. This method converts the Pydantic model to a dictionary suitable for creating a Django ORM model instance.
- Raises:
SmarterSqlPluginError – If the plugin manifest or SQL data is missing or invalid.
SmarterConfigurationError – If the parameters are not in the expected format.
- Returns:
A dictionary representing the PluginDataSql Django ORM model.
- Return type:
Example of a correctly formatted dictionary:
{ "properties": { "location": { "type": "string", "description": "The city and state, e.g., San Francisco, CA" }, "unit": { "type": "string", "enum": ["Celsius", "Fahrenheit"], "description": "The temperature unit to use. Infer this from the user's location." } }, "required": ["location", "unit"] }
Example of a Pydantic model:
[ { "name": "max_cost", "type": "float", "description": "the maximum cost that a student is willing to pay for a course.", "required": False, "enum": None, "default": None }, { "name": "description", "type": "string", "description": "areas of specialization for courses in the catalogue.", "required": False, "enum": ["AI", "mobile", "web", "database", "network", "neural networks"], "default": None } ]
spec: selector: directive: search_terms searchTerms: - admin - Smarter platform - admin account prompt: provider: openai systemRole: > You are a helpful assistant for Smarter platform. You can provide information about the admin account of the Smarter platform. model: gpt-4o-mini temperature: 0.0 maxTokens: 256 connection: test_sql_connection sqlData: sqlQuery: > SELECT * FROM auth_user WHERE username = '{username}'; parameters: - name: username type: string description: The username to query. required: true default: admin - name: unit type: string enum: - Celsius - Fahrenheit description: The temperature unit to use. required: false default: Celsius testValues: - name: username value: admin - name: unit value: Celsius limit: 10
- property plugin_data_serializer: PluginSqlSerializer | None
Return the serializer instance for plugin data.
This property provides a serializer object for the SQL plugin’s data, allowing conversion between Django ORM model instances and JSON-compatible representations. The serializer is used for validating, serializing, and deserializing plugin data, especially when preparing data for API responses or manifest generation.
If the serializer has not yet been instantiated, it will be created using the current plugin data. This ensures that the serializer always reflects the latest state of the plugin’s data.
- Returns:
An instance of
PluginSqlSerializerfor the plugin data, orNoneif plugin data is unavailable.- Return type:
Optional[PluginSqlSerializer]
- Example:
>>> plugin = SqlPlugin() >>> serializer = plugin.plugin_data_serializer >>> print(serializer.data) {'sql_query': "SELECT * FROM auth_user WHERE username = '{username}';", ...}
- property plugin_data_serializer_class: Type[PluginSqlSerializer]
Return the serializer class used for SQL plugin data.
This property provides the class reference for the serializer that is responsible for converting SQL plugin data between Django ORM model instances and JSON-compatible representations. The serializer class is essential for validation, serialization, and deserialization of plugin data, especially when integrating with APIs or generating manifests.
Use this property when you need to instantiate a new serializer for SQL plugin data, perform type checks, or access serializer-specific methods and attributes.
- Returns:
The serializer class for SQL plugin data.
- Return type:
Type[PluginSqlSerializer]
- Example:
>>> plugin = SqlPlugin() >>> serializer_cls = plugin.plugin_data_serializer_class >>> serializer = serializer_cls(plugin.plugin_data) >>> isinstance(serializer, PluginSqlSerializer) True
- property plugin_meta: PluginMeta | None
Return the plugin meta.
- Returns:
The plugin meta.
- Return type:
Optional[PluginMeta]
Note
This property will attempt to load the PluginMeta from the database if it has not already been set and if the UserProfile and manifest are available.
- property plugin_meta_django_model: dict[str, Any] | None
Return a dict for loading the plugin meta Django ORM model.
- property plugin_meta_serializer: PluginMetaSerializer | None
Return the plugin meta serializer.
- Returns:
The plugin meta serializer.
- Return type:
Optional[PluginMetaSerializer]
- property plugin_prompt: PluginPrompt | None
Return the plugin prompt.
- Returns:
The plugin prompt.
- Return type:
- Raises:
SmarterPluginError – If the PluginPrompt does not exist.
- property plugin_prompt_django_model: dict[str, Any] | None
Return the plugin prompt definition as a json object that can be used to load the Django ORM model.
- property plugin_prompt_serializer: PluginPromptSerializer | None
Return the plugin prompt serializer.
- Returns:
The plugin prompt serializer.
- Return type:
Optional[PluginPromptSerializer]
- property plugin_selector: PluginSelector | None
Return the plugin selector.
- Returns:
The plugin selector.
- Return type:
Optional[PluginSelector]
- property plugin_selector_django_model: dict[str, Any] | None
Return the plugin selector definition as a json object.
- property plugin_selector_history: QuerySet | None
Return the plugin selector history serializer.
- Returns:
The plugin selector history queryset.
- Return type:
Optional[QuerySet]
- property plugin_selector_serializer: PluginSelectorSerializer | None
Return the plugin selector serializer.
- Returns:
The plugin selector serializer.
- Return type:
Optional[PluginSelectorSerializer]
- property ready: bool
Return whether the plugin is ready.
- Returns:
True if the plugin is ready, False otherwise.
- Return type:
- Raises:
SmarterPluginError – If the UserProfile is not set or if any of the plugin components are not of the expected type.
- refresh()
Refresh the plugin.
- Returns:
True if the plugin is ready after refresh, False otherwise.
- Return type:
- reinitialize_plugin()
Reset all plugin-related properties to
None.This method is used to clear the internal state of the plugin instance, including all cached references to Django ORM models, serializers, and other plugin-specific objects. It is typically called during initialization or when reloading a plugin to ensure that no stale data remains.
The following attributes are reset:
_plugin_meta: The plugin metadata model instance._plugin_selector: The plugin selector model instance._plugin_prompt: The plugin prompt model instance._plugin_selector_history: The queryset for selector history._plugin_data: The plugin data model instance._plugin_prompt_serializer: The serializer for the plugin prompt._plugin_selector_serializer: The serializer for the plugin selector._plugin_meta_serializer: The serializer for the plugin metadata.
This ensures that subsequent operations on the plugin will re-fetch or re-create these objects as needed, avoiding issues with outdated or invalid references.
- rfc1034_compliant_str(val)
Generates a RFC 1034-compliant name string suitable for use as a DNS label or resource identifier.
- Parameters:
val (str) – The input string to convert to RFC 1034-compliant format.
- Returns:
A string that is: - lower case - contains only alphanumeric characters and hyphens - starts and ends with an alphanumeric character - has a maximum length of 63 characters
- Return type:
- Raises:
SmarterValueError – If the input is not a string or is empty after conversion.
Note
Underscores in the input are replaced with hyphens.
Invalid characters (anything other than a-z, 0-9, or ‘-’) are removed.
Leading and trailing hyphens are stripped.
The result is truncated to 63 characters if necessary.
Warning
This function is intended for generating DNS-safe names. It does not guarantee uniqueness or suitability for all RFC 1034 use cases.
Example usage:
from smarter.common.utils import rfc1034_compliant_str # Basic usage print(rfc1034_compliant_str("My_ChatBot_2025")) # Output: my-chatbot-2025 # With special characters print(rfc1034_compliant_str("My@Bot!_Name")) # Output: my-bot-name # With long input long_name = "ThisIsAReallyLongChatBotNameThatShouldBeTruncatedToSixtyThreeCharacters_Extra" print(rfc1034_compliant_str(long_name)) # Output: thisisareallylongchatbotnamethatshouldbetruncatedtosixtythreecharacters
- rfc1034_compliant_to_snake(val)
Converts a RFC 1034-compliant name (typically used for DNS labels or resource identifiers) to a more human-readable
snake_casename.This function is useful for translating machine-friendly names (which use hyphens as word separators) into Pythonic identifiers (which use underscores).
- Parameters:
val (str) – The RFC 1034-compliant name to convert. This should be a string containing only lowercase letters, numbers, and hyphens.
- Returns:
The converted name in
snake_caseformat, with hyphens replaced by underscores.- Return type:
- Raises:
SmarterValueError – If the input is not a string.
Note
Only hyphens are replaced; other characters are preserved.
The function does not validate that the input is strictly RFC 1034-compliant. It assumes the input is already sanitized.
Warning
This function does not handle conversion of other non-alphanumeric characters. If the input contains characters other than hyphens, underscores, letters, or numbers, they will remain unchanged.
Example usage:
from smarter.common.utils import rfc1034_compliant_to_snake # Basic conversion print(rfc1034_compliant_to_snake("my-chatbot-2025")) # Output: my_chatbot_2025 # Input with no hyphens print(rfc1034_compliant_to_snake("simplelabel")) # Output: simplelabel # Input with multiple hyphens print(rfc1034_compliant_to_snake("this-is-a-test-label")) # Output: this_is_a_test_label # Input with invalid type try: rfc1034_compliant_to_snake(12345) except SmarterValueError as e: print(e) # Output: Could not convert RFC 1034 compliant name from <class 'int'>
- save()
Save a plugin.
- Returns:
True if the plugin was saved successfully, False otherwise.
- Return type:
- Raises:
SmarterPluginError – If the plugin meta, selector, prompt, or data is not set or is not the correct instance.
- selected(user, input_text=None, messages=None)
Determine whether the plugin should be selected for a given user and input context.
This method evaluates plugin selection logic based on the plugin’s selector directive, search terms, and optionally provided input text or message history. It supports both direct text matching and message-based matching, using the plugin’s configured search terms.
Selection is performed as follows:
If the plugin selector directive is set to
ALWAYS, the plugin is automatically selected.If
input_textis provided, the method checks if any search term matches the input using the NLP utilitydoes_refer_to. If a match is found, the plugin is selected and a signal is sent.If
messagesare provided, the method iterates through user messages and checks for matches against the search terms. If a match is found, the plugin is selected and a signal is sent.
Signals:
plugin_selectedis sent when the plugin is selected via either input text or messages.
- Parameters:
- Returns:
True if the plugin is selected, False otherwise.
- Return type:
Note
This method requires the plugin to be ready. If the plugin is not ready, it will return False. The method also updates the internal
_selectedstate when a match is found.
- smarter_build_absolute_uri(request)
Attempts to get the absolute URI from a request object.
This utility function tries to retrieve the request URL from any valid child class of
django.http.HttpRequest. It is especially useful in unit tests or scenarios where the request object may not implementbuild_absolute_uri().- Parameters:
request (Optional[HttpRequest]) – The request object.
- Returns:
The absolute request URL.
- Return type:
Optional[str]
- Raises:
SmarterValueError – If the URI cannot be built from the request.
- snake_to_camel(data, convert_values=False)
Converts snake_case strings, dictionary keys, or lists of such, to camelCase format.
- Parameters:
- Returns:
The converted data in camelCase format. Returns a string, dictionary, or list, matching the input type.
- Return type:
Note
For dictionaries, only keys are converted by default. If
convert_valuesis set, string values are also converted.Nested dictionaries and lists are processed recursively.
Warning
If the input is not a string, dictionary, or list, a
SmarterValueErroris raised.Example usage:
from smarter.common.utils import snake_to_camel # Convert a string print(snake_to_camel("user_name")) # Output: userName # Convert a dictionary data = { "user_name": "alice", "user_profile": { "first_name": "Alice", "last_name": "Smith" } } print(snake_to_camel(data)) # Output: {'userName': 'alice', 'userProfile': {'firstName': 'Alice', 'lastName': 'Smith'}} # Convert a list of strings print(snake_to_camel(["first_name", "last_name"])) # Output: ['firstName', 'lastName'] # Convert values as well data = {"user_name": "first_name"} print(snake_to_camel(data, convert_values=True)) # Output: {'userName': 'firstName'}
- sorted_dict(data)
Returns a new dictionary with keys sorted.
- to_json(version='v1')[source]
Serialize the SqlPlugin instance to a JSON-compatible dictionary suitable for Pydantic import.
This method transforms the plugin’s internal state, including its manifest and data, into a dictionary format that can be used to instantiate a Pydantic model. This is primarily used for rendering a plugin manifest for the Smarter API, enabling interoperability between Django ORM models and Pydantic schemas.
The output includes all relevant plugin fields, with the SQL data section populated from the plugin’s serializer. This ensures that the manifest is complete and conforms to the expected schema for API consumption or further validation.
- Parameters:
version (str) – The API version to use for serialization. Only “v1” is supported.
- Returns:
A dictionary representing the plugin in JSON format, or
Noneif the plugin is not ready.- Return type:
- Raises:
SmarterPluginError – If the plugin is not ready, the data is not a valid JSON object, or an unsupported version is specified.
- Note:
The returned dictionary is structured for compatibility with Pydantic models and the Smarter API manifest specification. The SQL data is injected from the plugin’s serializer to ensure accurate representation.
- Example:
>>> plugin = SqlPlugin() >>> manifest_json = plugin.to_json() >>> print(manifest_json["spec"]["sqlData"]["sql_query"]) SELECT * FROM auth_user WHERE username = '{username}';
- tool_call_fetch_plugin_response(function_args)[source]
Fetch information from a Plugin object in response to an OpenAI API tool call.
This method processes the arguments received from an OpenAI function call, interpolates them into the SQL query, executes the query, and returns the result.
See the OpenAI documentation: https://platform.openai.com/docs/assistants/tools/function-calling/quickstart
Example tool call payload:
"tool_calls": [ { "id": "call_1Ucn2R5WmBh7TtoE197SsP3p", "function": { "arguments": "{"description":"AI"}", # these are the function_args "name": "smarter_plugin_0000004468" }, "type": "function" } ]
- Parameters:
function_args (
Union[dict[str,Any],list]) – Arguments for the function call, as a dict, list, or JSON string.- Return type:
- Returns:
The result of the SQL query as a string, or an empty string if no results.
- Raises:
SmarterSqlPluginError – If plugin data or SQL connection is invalid, or arguments are malformed.
- property unformatted_class_name: str
Returns the raw class name without formatting.
- Returns:
The unformatted class name as a string.
- Return type:
This is useful for logging or serialization where the plain class name is needed.
- update()
Update a plugin.
- Returns:
True if the plugin was updated successfully, False otherwise.
- Return type:
- Raises:
SmarterPluginError – If the plugin manifest is not set or the plugin does not exist.
- property user: AnonymousUser | User | None
Returns the user for the current user. Handle lazy instantiation from user_profile or account.
- Returns:
The user for the current user.
- Return type:
User or None
- property user_profile: UserProfile | None
Returns the user_profile for the current user. Handle lazy instantiation from user or account.
- Returns:
The user_profile for the current user.
- Return type:
UserProfile or None
- property yaml: str
Return the plugin as a yaml string.
- Returns:
The plugin as a yaml string.
- Return type:
- Raises:
SmarterPluginError – If the plugin is not ready.
- yaml_to_json(yaml_string)
Convert a yaml string to a dictionary.
- Parameters:
yaml_string (str) – The yaml string to convert.
- Returns:
The converted dictionary.
- Return type:
- Raises:
SmarterPluginError – If the yaml string is not valid.