Skip to content

Python API Release Notes

Stay updated with the latest changes and improvements in our Python API.

0.8.37

June 2, 2025 10:58 PM UTC

  • Fixed a bug with the rai init CLI command that caused it to fail when saving the configuration file with the error [Errno 2] No such file or directory: ''.

0.8.36

May 29, 2025 7:01 PM UTC

  • Fixed a bug in stored procedure exports that caused procedures with DATETIME columns in their result set to return empty results when called.

0.8.35

May 20, 2025 12:51 PM UTC

  • Added the data_freshness_mins configuration key, supported in both raiconfig.toml and Config objects.

    This key sets the maximum allowed staleness (in minutes) for Snowflake table data used by the model. If the data is older, the corresponding data stream is synced on the next query, with a spinner shown in notebooks and REPLs while the new data is prepared for the model.

  • Fixed a typo in the UninitializedPropertyException error message. The word “rename” was misspelled as “ranamed.”

0.8.34

May 16, 2025 9:41 PM UTC

  • Fixed a bug in the imports:list CLI command that failed to report quarantined streams in certain cases. The command now correctly displays quarantined streams in the output.

  • Fixed a bug when using relationalai in a Snowflake notebook that failed to fall back to the configured Snowflake role if no role was specified in current Snowflake session.

0.8.32

May 12, 2025 12:26 PM UTC

  • Fixed a bug in the Uninitialized property error message that would display the same property name multiple times if it was used in multiple places in the program. The error message now shows the property name only once.

  • Updated the click dependency for the CLI to version <=8.1.8 to avoid compatibility issues. To make sure you have the correct version of click installed, reinstall the relationalai library with the following command:

    Terminal window
    python -m pip install --upgrade --force-reinstall --upgrade-strategy eager relationalai

0.8.30

May 6, 2025 11:52 AM UTC

  • Columns in source Snowflake tables or views with names that begin with an underscore (_) are now supported. The properties generated by these columns are prefixed with col. For example, if your source table as a column named _id, the generated property is named col_id`.

    If you select a property that begins with an underscore in a query, a warning is raised to inform you that the column was renamed.

  • Fixed a bug with configuration in Snowflake notebooks that caused default values to be used even if specific values were overwritten with save_config().

0.8.29

May 1, 2025 2:18 PM UTC

  • Fixed a bug with the progress spinners shown in notebooks and the terminal that caused RAI engine status updates to be hidden. The spinners now correctly show the status of the configured RAI engine.

  • Fixed a bug with properties automatically created from columns of Snowflake tables or views that caused the column name to be imported incorrectly if the name contained special characters.

0.8.28

April 29, 2025 1:11 PM UTC

  • Improved support for Snowflake notebooks. When using a Snowflake notebook, the Model constructor now automatically picks up your Snowflake session so that you don’t need to explicitly provide those values or manually get the session and pass it to the constructor:

    # NEW
    import relationalai as rai
    # The session is automatically picked up from the Snowflake notebook, so the
    # following creates a model using the current session and the default RAI
    # configuration values.
    model = rai.Model("MyModel")

    Previously, you needed to import the snowflake.snowpark package and manually get the session:

    # OLD
    import relationalai as rai
    from snowflake.snowpark.context import get_active_session
    session = get_active_session()
    model = rai.Model("MyModel", connection=session)
  • Fixed a bug in exported stored procedures that could cause source data to be unavailable to the stored procedure.

  • Fixed a bug that caused properties automatically created from Snowflake tables or views to be multi-valued instead of single-valued.

0.8.27

April 25, 2025 2:46 PM UTC

  • Improved the error message that sometimes appears when a RAI program is executed against an engine that is outdated. The error message used to suggest that the user run the api.update_libraries() SQL command, which is deprecated. Now, the error message suggests passing use_package_manager=True to the Model constructor to automatically update the libraries used by the model.

    Note that use_package_manager is set to True by default, so this situation should only occur in practice if you’ve explicitly set it to False in the past.

0.8.26

April 23, 2025 6:28 PM UTC

  • Changed our package dependencies to ensure the snowflake-snowpark-python has a minimum version of 1.30.0 in order to avoid a thread-safety issue that could potentially cause queries to return the wrong results.

    To upgrade your package and ensure that you have not only the latest version of relationalai but also a compatible version of snowflake-snowpark-python, run the following command:

    Terminal window
    pip install --upgrade --force-reinstall --upgrade-strategy eager relationalai8 ```

0.8.21

April 15, 2025 11:30 AM UTC

  • Fixed a typo in the SnowflakeImportMissingException error message that incorrectly suggested using the rai imports:create CLI command, which doesn’t exist. The error now correctly suggest using the rai imports:stream command.

  • Minor improvements to performance and stability.

0.8.20

April 10, 2025 3:38 PM UTC

  • Added the ability to set the name of an exported stored procedure by passing a fully-qualified name to the Model.export() decorator.

    For example:

    # Export a stored procedure name `my_db.my_schema.my_procedure`.
    @model.export('my_db.my_schema.my_procedure')
    def foo():
    # Your procedure code here
    pass
    # When the decorator argument only specifies the db and schema, the procedure
    # name is set to the function name, so the following exports a stored procedure
    # named `my_db.my_schema.foo`.
    @model.export('my_db.my_schema')
    def foo():
    # Your procedure code here
    pass
  • Fixed a bug that sometimes cause UninitializedPropertyException errors in exported stored procedures for properties with names that begin with graphlib.

  • Fixed a bug that sometimes caused rai init to fail generate a raiconfig.toml file with appropriate default values.

0.8.19

April 4, 2025 7:25 PM UTC

  • Improved error messages in the RAI CLI when configuration keys are missing. Previously, some commands would fail with the error trying to auto-create the engine and we failed or Failed to connect to DB. Now, the error message tells you which required configuration keys are missing.

0.8.18

April 3, 2025 5:23 PM UTC

  • Fixed a bug that caused Uninitialized property errors when using Snowflake tables or views with primary and foreign key constraints in their schema as the source of a Type object.

0.8.14

March 27, 2025 9:21 PM UTC

  • Added support for Snowflake tables and views whose names contain double quotes when passing the fully-qualified name to the Type constructor’s source parameter. For example, the following code creates a Type object with entities sourced from a table named my_db.my_schema."my table":

    MyType = Type("MyType", source='my_db.my_schema."my table"')

0.8.13

March 26, 2025 9:09 PM UTC

  • Improved the error message that sometimes appears when a query cannot be decrypted because the cryptography library is not installed. Previously, the error message was:

    library `cryptography.hazmat` missing; please install

    Now, the error message is:

    Please open the navigation-bar dropdown labeled *Packages* and select `cryptography` under the *Anaconda Packages* section, and then re-run your query.
  • Fixed a bug that caused some queries to fail with the error AttributeError: Row object has no attribute data_type.

  • Other minor bug fixes.

  • Upgraded JavaScript dependencies of the debugger to address security vulnerabilities.

0.8.11

March 22, 2025 12:30 AM UTC

  • Improved the error message displayed when a property is used as both a single-valued and multi-valued property.

    Previously, the error message was:

    Trying to use a property 'property_name' as both singular and multi-valued.

    Now, the error message is:

    Trying to use a property 'property_name' as both singular and multi-valued. This often happens when multiple types have a property with the same name, but one is single-valued and the other is multi-valued. See https://relational.ai/build/guides/core-concepts#setting-object-properties for more information.
  • Fixed a bug that caused an error in some cases when a Type was queried prior to being used in any rule.

0.8.9

March 19, 2025 3:14 PM UTC

  • Added a new days_to_int() function to the std.dates module that converts a period of days to an integer. This is useful when you need to convert the difference of two dates to an integer so that you can do arithmetic with it:

    import relationalai as rai
    from relationalai.std.dates import date, days_to_int

0.8.8

March 19, 2025 12:16 PM UTC

  • Made major performance improvements to startup time for applications that have many source tables and/or views in Snowflake. In some cases, the startup time can be reduced by as much as 99%.
  • Fixed a correctness issue involving multi-valued properties that didn’t get filtered properly when referenced indirectly, such as with InstanceProperty.choose(). This could cause incorrect values to be included in query results.

0.8.6

March 6, 2025 10:48 PM UTC

  • Unpinned the cryptography dependency version to allow for more flexibility in the versions of cryptography that can be used with the RAI Python API.
  • Fixed a bug that prevented change tracking from being enabled on source table or view in Snowflake even when ensure_change_tracking was set to True in the Model constructor.

0.8.4

March 4, 2025 6:07 PM UTC

  • Fixed a bug that generated InvalidLoop warnings in Jupyter Notebooks that suggest the user add dynamic=True to their model.query() call, even though dynamic=True was already present. The warnings are no longer generated.

0.8.3

February 28, 2025 6:15 PM UTC

  • Minor performance improvements related to aggregations.
  • Fixed a bug that prevented properties with decimal numeric values from being used in graph visualizations. For example, using a property with a decimal value as an edge label would cause the visualization to fail with the error TypeError: Object of type Decimal is not JSON serializable. Now, properties with decimal values are serialized as floats before being used in the visualization.

  • Fixed a bug that prevented errors and warning from being displayed with calling the Graph.fetch() and Graph.visualize() methods. Now, errors and warnings are displayed as expected.

  • Fixed a bug that allowed SQL stored procedures created with the Model.export() decorator to be executed using the CDC engine. Now, these procedures can only be executed using user engines. Refer to the Engine Selection section of the Model.export() documentation for more information on which engines are used exported procedures.

0.8.2

February 20, 2025 3:23 PM UTC

  • Removed the requirement to specify return value type hints in functions wrapped with the Model.export() decorator. This simplifies creating stored procedures with a large number of output columns.

    For example:

    # Old syntax:
    @model.export("sandbox.public")
    def get_adults_by_age(age: int) -> Tuple[str, int]: # <-- Return type hints
    adult = Adult(age=age)
    return adult.name, adult.age
    # New syntax:
    @model.export("sandbox.public")
    def get_adults_by_age(age: int) # <-- No return type hints
    adult = Adult(age=age)
    return adult.name, adult.age
  • Removed the engine creation step from the rai init command. This change simplifies the initialization process by removing an unnecessary step, since engines are automatically created for each user when they run their first query.

  • Improved error messages for queries that get aborted, either by a user cancelling the transaction or from some other issue. The error message is formatted more clearly and includes the reason that the transaction was aborted.

0.8.0

February 4, 2025 4:09 AM UTC

  • The .louvain() method now raises a DirectedGraphNotSupported exception instead of a DirectedGraphNotApplicable exception when called from a directed graph.
  • Made improvements to the RAI debugger:

    • Rules with two or more unrelated variables are now flagged with a “Cross product” warning. Although cross products may be intentional, accidental cross products can lead to unexpected results and performance issues.
    • Detailed metrics are more accurately reported. Previously, some compilation time was reported as “Other.”
  • Made significant improvements to general query performance.

  • Improved the error message for the .eigenvector_centrality() method when called from a directed graph. The message now suggests using .pagerank() instead, which is supported for directed graphs.

  • Introduced an experimental solver library for optimization workloads. This library is not yet documented and is subject to frequent and unannounced API changes. If you would like to try out this feature, please contact customer support at support@relational.ai.

  • Fixed a bug that silently removed edges added to a directed graph that did not explicitly specify a weight property. Now, edges without the weight property are assigned the default_weight value specified in the Graph constructor.

0.7.3

January 13, 2025 9:37 PM UTC

  • You may use the new rai engines:suspend CLI command to manually suspend an engine from the RAI CLI. For example, the following suspends an engine named my_engine:

    Terminal window
    rai engines:suspend --name my_engine

    See Engine Suspension for more information.

  • Version information is now displayed in the RAI CLI help menu next to the welcome message:

    Terminal window
    $ rai
    --------------------------------------------------
    Welcome to RelationalAI (0.7.3)
    rai [options] command
    --profile - which config profile to use (default: default)
    init - Initialize a new project
    version - Print version info
    debugger - Open the RAI debugger
    ...

    Additionally, messages about new versions of the RAI Python API are displayed in help for all commands whenever a new version is available.

0.7.2

January 10, 2025 8:37 PM UTC

  • Added an option to the interactive rai init CLI command to specify the engine size when configuring your RAI engine. Prior to this release, the engine size was automatically set to the default value specified by the engine_size key in your raiconfig.toml file, or HIGHMEM_X64_S if the key was missing or you do not have a raiconfig.toml file. Now, the configured default value is selected but can specify a different engine size during initialization.

  • Added a new wait_for_stream_sync configuration key to the raiconfig.toml file that allows you to specify whether to wait for a data stream to synchronize before executing a query. The default value is true, which means that queries will wait for change tracking data to be processed before executing. If you set the value to false, the query will execute immediately but the results may not reflect the most recent changes to the source data.

  • Made several improvements to the RAI debugger:

    • Added support for loading debug.jsonl files exported during one RAI debugger session into a new debugger session by dragging and dropping the file into the debugger UI.

    • Added a settings option to strip sensitive data, such as result set samples, from exported data. This is turned on by default and can be disabled using the toggle switch in the settings menu by clicking on the gear icon in the top right-hand corner of the debugger UI.

    • Improved logging output when exporting a debug.jsonl file to enable better support when sharing the file with RAI.

  • Fixed a bug that caused a bug that caused transaction profile information in the RAI debugger to be displayed incorrectly.

0.7.1

December 19, 2024 10:24 PM UTC

  • Improved the error message when creating a stream using rai imports:stream when the model specified in the --model parameter does not exist. The error message now includes instructions for creating the model:

    Terminal window
    --- Model 'MyModel' not found ------------------------------
    The model 'MyModel' does not exist. You can create it by
    running a program containing the following:
    model = relationalai.Model("MyModel")
    -------------------------------------------------------------
  • Fixed a bug where rai imports:delete would report Error deleting import: engine is suspended even though the import was successfully deleted.

0.7.0

December 16, 2024 10:25 PM UTC

  • You may now resume suspended engines from the RAI CLI using the new rai engines:resume command. For example, the following resumes an engine named my_engine:

    Terminal window
    rai engines:resume --name my_engine
  • You may now specify the --auto_suspend_mins option when creating an engine with the rai engines:create CLI command. For example, the following creates an engine named my_engine that auto-suspends after 30 minutes of inactivity:

    Terminal window
    rai engines:create --name my_engine --size HIGHMEM_X64_S --auto_suspend_mins 30

    Note that the --auto_suspend_mins parameter is optional and defaults to 60 minutes. If your raiconfig.toml file contains an auto_suspend_mins key, the value of that key will be used as the default.

  • Error reporting for queries with the format="snowpark" option has been improved. All errors are now reported. Previously, some errors were suppressed.

  • Error messages for multi-factor authentication issues have been improved to provide more context, such as when a connection fails due to Duo security settings.

  • A new experimental module has been added that contains experimental features:

    • The experimental.inspect.watch() function may be used to do “print debugging” of expressions in a rule or query. For example:

      import relationalai as rai
      from relationalai.std import aggregates
      from relationalai.experimental.inspect import watch
      model = rai.Model("MyModel")
      Person = model.Type("Person")
      Adult = model.Type("Adult")
      with model.rule():
      Person.add(id=1).set(name="Jane", age=12)
      Person.add(id=2).set(name="John", age=21)
      with model.rule():
      person = Person()
      person.age >= 18
      # Print "is adult" with the person's name and age
      # when the rule is evaluated.
      watch("is adult", person, person.name, person.age)
      person.set(Adult)
      with model.query() as select:
      adult = Adult()
      num_adults = aggregates.count(adult)
      response = select(num_adults)
      print(response.results)

      The above program produces the following output:

      v1 v2 v3 v4
      0 is adult g4rDjPY1HHWkEikWQXw+3Q John 21
      result
      0 1

      Note that a query that triggers the rule containing the watch() function must be executed in order to see the output.

    • The experimental.paths module contains functions and classes for finding and working with paths in a graph. If you would like to try out this feature, please contact support at support@relational.ai.

    Documentation for features in experimental is coming soon.

  • The implementation of Model.export() has changed to allow it to be used inside of a function call. Previously, it could only be used as a top-level statement. This is a breaking change because the new implementation does not allow functions decorated with @export() to contain multiple return statements.
  • Fixed a bug that prevented you from using names of aggregation functions, like count, min, or max, as property names for entities in a model.

  • Fixed a bug that caused an engine’s auto_suspend_mins setting to be reset to 60 minutes after being auto-resumed.

  • Fixed a bug that made it impossible to export a SQL stored procedure if the query produced a column with only NULL values.

  • Fixed several bugs in the RAI debugger:

    • Fixed a bug that occasionally caused ConnectionResetError: Cannot write to closing transport errors.

    • Fixed a bug that caused the wrong Python code to be displayed when viewing a model’s rules.

    • Fixed a bug that prevented profiling stats from updating while a query is executing.

0.6.2

December 4, 2024 1:52 PM UTC

  • Fixes a bug that caused a SQL compilation error the first time a Snowflake table or view was used as a source in a model.

0.6.1

December 3, 2024 5:25 PM UTC

  • The save_config() function now returns None instead of a string with the full TOML file contents. This prevents sensitive information from being displayed in notebook and REPL outputs.

  • You will now see a warning message when initializing a model if an engine with the same name as the engine configuration key exists but has a different size than the one specified by the engine_size key.

    To silence this warning, you may do one of the following:

    • Remove the engine_size configuration key from your configuration.
    • Change engine_size to match the size of the existing engine.
    • Delete the existing engine and re-run your program.
  • The operation for fetching query results from the RAI Native App is now automatically retried on failure due to a transient error.

  • The imports:list CLI command now displays the status Not Available instead of throwing an error if an import’s STATUS field is null.

0.6.0

November 15, 2024 9:08 PM UTC

  • Snowflake Notebooks on Container Runtime are now supported! Container Notebooks offer a more flexible environment than Warehouse Notebooks:

    • You can install the relationalai package using pip install relationalai instead of uploading the package as a ZIP file. This requires enabling an external access integration for PyPI, and lets you install other third-party packages, as well. ZIP file uploads are still supported if you do not want to enable external access to PyPI.

    • You do not need to enable external access integration for downloading query results to the notebook, like you do for Warehouse Notebooks.

  • Data streams are now automatically created for you on Snowflake tables and views passed to the source parameter of the model.Type() constructor. Existing data streams will be recreated the first time you query a model using 0.6.0. See Migrating Models to 0.6.0 for more information.

  • You can set the new ensure_change_tracking configuration key to automatically enable change tracking on tables or views passed to the model.Type() constructor’s source parameter. The default value is False, which means that table and view owners must manually enable change tracking on their objects.

  • Engines auto-created by the Python API are configured by default to suspend after 60 minutes of inactivity. You can override this default by specifying the auto_suspend_mins configuration key in your raiconfig.toml file. Suspended engines are automatically resumed when Python queries are executed. See Engine Suspension for more information on suspended engines.

  • A convenience function save_config() has been added for creating a raiconfig.toml file from a notebook environment.

  • The Graph.visualize() function now throws an UnsupportedVisualizationError if called in an environment, like a Snowflake notebook, that does not support visualization.

  • Fixes a bug that caused an UninitializedPropertyException to be thrown when a type that has never been added to is queried.

  • Fixes a bug that displayed the message Failed to connect to ws://0.0.0.0:8080/ws/program. Running with debug sink disabled. when the RAI debugger is not running.

  • Several methods of the graphs.Compute class have been changed or removed:

    • .is_triangle() no longer returns an Expression object that produces True or False values. Instead, it filters arguments for combinations of three nodes that form a triangle. This behavior is consistent with how other functions, like .is_reachable(), work.

    • .louvain() now throws a DirectedGraphNotApplicable error if called from a directed graph.

    • The default values for the max_levels and max_sweeps parameters of the .louvain() and .infomap() methods have been changed:

      • max_levels has changed from 4 to 1.
      • max_sweeps has changed from 8 to 20.
    • You may now call the following methods from a weighted graph:

      Previously, these returned empty results for weighted graphs. Because they now support weighted graphs, the following methods have been removed:

      • .weighted_cosine_similarity()
      • .weighted_degree_centrality()
      • .weighted_distance()
      • .weighted_jaccard_similarity()
    • Methods for computing degree statistics have been removed:

      • .avg_degree()
      • .avg_indegree()
      • .avg_outdegree()
      • .max_degree()
      • .max_indegree()
      • .max_outdegree()
      • .min_degree()
      • .min_indegree()
      • .min_outdegree()

      You can compute these statistics using the .degree() method and an aggregation function:

      from relationalai.std import aggregates
      def avg_degree(graph):
      node = graph.Node()
      degree = graph.compute.degree(node)
      return aggregates.avg(degree)
  • Internal node hashes for graphs are now stable. Algorithms sensitive to node order will now produce consistent results across different runs.

  • All output fields for the rai imports:setup CLI command are now displayed in snake_case. Previously, some were displayed in camelCase while others were displayed in snake_case.

  • The --pool parameter for the rai engines:create CLI command has been removed. Engine compute pools are fully managed by the RAI Native App.

The first time you query an existing model after upgrading to 0.6.0, data streams used by the model will be recreated. New data streams appear in the api.data_streams view with a RAI_DATABASE column containing the name pyrel_root_db.

Once the new data streams are created, you can safely delete the old data streams using the api.delete_data_stream() procedure by passing your model’s name and the fully-qualified name of the table or view associated with the old data stream.

CALL relationalai.api.delete_data_stream('my_model', '<db>.<schema>.<table_or_view>');