From 8878791415d9a3c6b2e80101e73804e4ed406fe4 Mon Sep 17 00:00:00 2001 From: Ludwik Trammer Date: Tue, 23 Apr 2024 13:59:41 +0200 Subject: [PATCH 1/2] docs(views): add documentation of freeform views --- docs/concepts/freeform_views.md | 10 +++++++ docs/concepts/iql.md | 5 ++-- docs/concepts/structured_views.md | 39 +++++++++++++++++++++++++++ docs/concepts/views.md | 40 ++++++++-------------------- docs/how-to/custom_freeform_views.md | 3 +++ docs/how-to/custom_views.md | 7 +++-- docs/how-to/pandas_views.md | 2 +- docs/how-to/sql_views.md | 4 +-- docs/quickstart/index.md | 2 +- docs/reference/views/index.md | 12 +++------ docs/reference/views/structured.md | 13 +++++++++ mkdocs.yml | 6 ++++- src/dbally/collection.py | 17 +++++++----- tests/unit/test_collection.py | 5 +++- 14 files changed, 109 insertions(+), 56 deletions(-) create mode 100644 docs/concepts/freeform_views.md create mode 100644 docs/concepts/structured_views.md create mode 100644 docs/how-to/custom_freeform_views.md create mode 100644 docs/reference/views/structured.md diff --git a/docs/concepts/freeform_views.md b/docs/concepts/freeform_views.md new file mode 100644 index 00000000..7f62e6ba --- /dev/null +++ b/docs/concepts/freeform_views.md @@ -0,0 +1,10 @@ +# Concept: Freeform Views + +Freeform views are a type of [view](views.md) that provides a way for developers using db-ally to define what they need from the LLM without requiring a fixed response structure. This flexibility is beneficial when the data structure is unknown beforehand or when potential queries are too diverse to be covered by a structured view. Though freeform views offer more flexibility than structured views, they are less predictable, efficient, and secure, and may be more challenging to integrate with other systems. For these reasons, we recommend using [structured views](./structured_views.md) when possible. + +Unlike structured views, which define a response format and a set of operations the LLM may use in response to natural language queries, freeform views only have one task - to respond directly to natural language queries with data from the datasource. They accomplish this by implementing the [`ask`][dbally.views.base.BaseView] method. This method takes a natural language query as input and returns a response. The method also has access to the LLM model (via the `llm_client` attribute), which is typically used to retrieve the correct data from the source (for example, by generating a source-specific query string). To learn more about implementing freeform views, refer to the [How to: Custom Freeform Views](../how-to/custom_freeform_views.md) guide. + +## Security + +!!! warning + When using freeform views, the LLM typically gets raw access to the data source and can execute arbitrary operations on it using the query language of the data source (e.g., SQL). This can be powerful but also necessitates that the developer be extremely cautious about securing the data source outside of db-ally. For instance, in the case of Relational Databases, the developer should ensure that the database user used by db-ally has read-only access to the database, and that the database does not contain any sensitive data that shouldn't be exposed to the LLM. \ No newline at end of file diff --git a/docs/concepts/iql.md b/docs/concepts/iql.md index 403ded3e..c4496aca 100644 --- a/docs/concepts/iql.md +++ b/docs/concepts/iql.md @@ -1,6 +1,6 @@ # Concept: IQL -Intermediate Query Language (IQL) is a simple language that serves as an abstraction layer between natural language and data source-specific query syntax, such as SQL. In db-ally, LLM utilizes IQL to express complex queries in a simplified way. +Intermediate Query Language (IQL) is a simple language that serves as an abstraction layer between natural language and data source-specific query syntax, such as SQL. With db-ally's [structured views](./structured_views.md), LLM utilizes IQL to express complex queries in a simplified way. For instance, an LLM might generate an IQL query like this when asked "Find me French candidates suitable for a senior data scientist position": @@ -8,6 +8,5 @@ For instance, an LLM might generate an IQL query like this when asked "Find me F from_country('France') AND senior_data_scientist_position() ``` -The capabilities made available to the AI model via IQL differ between projects. Developers control these by defining [Views](views.md). db-ally automatically exposes special methods defined in views, known as "filters", via IQL. For instance, the expression above suggests that the specific project contains a view that includes the `from_country` and `senior_data_scientist_position` methods (and possibly others that the LLM did not choose to use for this particular question). Additionally, the LLM can use Boolean operators (`and`,`or`, `not`) to combine individual filters into more complex expressions. +The capabilities made available to the AI model via IQL differ between projects. Developers control these by defining special [Views](structured_views.md). db-ally automatically exposes special methods defined in structured views, known as "filters", via IQL. For instance, the expression above suggests that the specific project contains a view that includes the `from_country` and `senior_data_scientist_position` methods (and possibly others that the LLM did not choose to use for this particular question). Additionally, the LLM can use Boolean operators (`and`,`or`, `not`) to combine individual filters into more complex expressions. -IQL is at the heart of db-ally. By providing a layer of abstraction between the LLM and the data source, it significantly contributes to the primary benefits of db-ally: consistency, security, efficiency, and portability. diff --git a/docs/concepts/structured_views.md b/docs/concepts/structured_views.md new file mode 100644 index 00000000..334a4c3e --- /dev/null +++ b/docs/concepts/structured_views.md @@ -0,0 +1,39 @@ +# Concept: Structured Views + +Structured views are a type of [view](../concepts/views.md), which provide a way for developers using db-ally to define what they need from the LLM, including: + +* The desired data structure, such as the specific fields to include from the data source. +* A set of operations the LLM may employ in response to natural language queries (currently only “filters” are supported, with more to come) + +Given different natural language queries, a db-ally view will produce different responses while maintaining a consistent data structure. This consistency offers a reliable interface for integration - the code consuming responses from a particular structured view knows what data structure to expect and can utilize this knowledge when displaying or processing the data. This feature of db-ally makes it stand out in terms of reliability and stability compared to standard text-to-SQL approaches. + +Each structured view can contain one or more “filters”, which the LLM may decide to choose and apply to the extracted data so that it meets the criteria specified in the natural language query. Given such a query, LLM chooses which filters to use, provides arguments to the filters, and connects the filters with Boolean operators. The LLM expresses these filter combinations using a special language called [IQL](iql.md), in which the defined view filters provide a layer of abstraction between the LLM and the raw syntax used to query the data source (e.g., SQL). + +!!! example + For instance, this is a simple [view that uses SQLAlchemy](../how-to/sql_views.md) to select data from specific columns in a SQL database. It contains a single filter, that the LLM may optionally use to control which table rows to fetch: + + ```python + class CandidateView(SqlAlchemyBaseView): + """ + A view for retrieving candidates from the database. + """ + + def get_select(self): + """ + Defines which columns to select + """ + return sqlalchemy.select(Candidate.id, Candidate.name, Candidate.country) + + @decorators.view_filter() + def from_country(self, country: str): + """ + Filter candidates from a specific country. + """ + return Candidate.country == country + ``` + +In addition to structured views, db-ally also provides [freeform views](freeform_views.md), which are more flexible and can be used to create views that do not require a fixed data structure. Freeform views come in handy when the data structure is not predefined or when the scope of potential queries is too vast to be addressed by a structured view. Conversely, structured views are more predictable, efficient, secure, and easier to integrate with other systems. Therefore, we recommend using structured views where possible. To read about the advantages and disadvantages of both kinds of views, refer to [Concept: Views](views.md). + +A project can implement several structured views, each tailored to different output formats and filters to suit various use cases. It can also combine structured views with freeform views to allow a more flexible interface for users. The LLM selects the most suitable view that best matches the specific natural language query. For more information, you consider reading our article on [Collections](collections.md). + +See the [Quickstart](../quickstart/index.md) guide for a complete example of how to define and use structured views. \ No newline at end of file diff --git a/docs/concepts/views.md b/docs/concepts/views.md index 34dd7c49..bd813be7 100644 --- a/docs/concepts/views.md +++ b/docs/concepts/views.md @@ -1,37 +1,19 @@ # Concept: Views -Views provide a way for developers using db-ally to define what they need from the LLM, including: +Views are a core concept in db-ally. They represent a way to define what you need from the LLM and connect it to the data source. The library provides two types of views: -* The desired data structure, such as the specific fields to include from the data source. -* A set of operations the LLM may employ in response to natural language queries (currently only “filters” are supported, with more to come) +* [Structured views](structured_views.md) *(recommended)* - these define a desired data structure and a set of operations that the LLM may use in response to natural language queries. +* [Freeform views](freeform_views.md) - these provide a more flexible way to define views, without a specific data structure or predefined operations. -Given different natural language queries, a db-ally view will produce different responses while maintaining a consistent data structure. This consistency offers a reliable interface for integration - the code consuming responses from a particular view knows what data structure to expect and can utilize this knowledge when displaying or processing the data. This feature of db-ally makes it stand out in terms of reliability and stability compared to standard text-to-SQL approaches. +Structured views are built on top of [IQL](iql.md), a simple language that acts as an abstraction layer between natural language and data source-specific query syntax, such as SQL. IQL allows the LLM to express complex queries in a more straightforward manner. In contrast, freeform views operate directly on the raw data source, using the data source's query language. -Each view can contain one or more “filters”, which the LLM may decide to choose and apply to the extracted data so that it meets the criteria specified in the natural language query. Given such a query, LLM chooses which filters to use, provides arguments to the filters, and connects the filters with Boolean operators. The LLM expresses these filter combinations using a special language called [IQL](iql.md), in which the defined view filters provide a layer of abstraction between the LLM and the raw syntax used to query the data source (e.g., SQL). +We consider **structured views** to be at the heart of db-ally. These enable the library's core benefits (consistency, security, efficiency, and portability), and provide a reliable interface for integration. Structured views are especially useful for applications with precise requirements in behavior or data format. For this reason, we recommend using structured views whenever possible. -!!! example - For instance, this is a simple view that uses SQLAlchemy to select data from specific columns in a SQL database. It contains a single filter, that the LLM may optionally use to control which table rows to fetch: +Here are the differences between structured and freeform views, in terms of the core benefits of db-ally: - ```python - class CandidateView(SqlAlchemyBaseView): - """ - A view for retrieving candidates from the database. - """ +* **Consistency**: Structured views ensure predictable output formats, while freeform views offer more flexibility and can define views that do not require a fixed data structure. The former is easier to integrate with other systems and more predictable, while the latter provides more flexibility. +* **Security**: Structured views limit data source operations to those predefined by developers, whereas freeform views often allow the LLM to execute arbitrary operations on the data source. The former approach is considerably more secure (including protection against SQL injection attacks), whilst the latter approach is more flexible but requires developers to ensure the security of data sources outside of db-ally. +* **Efficiency**: Structured views provide [a layer of abstraction](iql.md) between the model and the data, which enables the LLM to focus on essential aspects, improving performance. Complex operations from the data source perspective can appear simple to the LLM. Conversely, freeform views can operate on the raw data source, which can be powerful but may also make it more challenging for the LLM to deliver good performance. +* **Portability**: Both structured and freeform views are typically defined in terms of a specific data source type and can be integrated with various database technologies and other data sources. However, freeform views integrate easier with data sources that already use a query language which the LLM can generate (like SQL), while structured views aren't similarly limited since they come with their query language (IQL). - def get_select(self): - """ - Defines which columns to select - """ - return sqlalchemy.select(Candidate.id, Candidate.name, Candidate.country) - - @decorators.view_filter() - def from_country(self, country: str): - """ - Filter candidates from a specific country. - """ - return Candidate.country == country - ``` - -A project might implement multiple views, each tailored to different output formats and filters for various use cases. The LLM selects the appropriate view which best corresponds to the specific natural language query. For further details, consider reading our article on [Collections](collections.md). - -See the [Quickstart](../quickstart/index.md) guide for a complete example of how to define and use views. +A project might implement multiple views, of both types, each customised for different use cases. The LLM selects the most appropriate view corresponding to the specific natural language query. For further details, consider reading our article on [Collections](collections.md). \ No newline at end of file diff --git a/docs/how-to/custom_freeform_views.md b/docs/how-to/custom_freeform_views.md new file mode 100644 index 00000000..ebe7317a --- /dev/null +++ b/docs/how-to/custom_freeform_views.md @@ -0,0 +1,3 @@ +# How-To: Create custom Freeform Views + +TODO \ No newline at end of file diff --git a/docs/how-to/custom_views.md b/docs/how-to/custom_views.md index b6078d70..a82e94e4 100644 --- a/docs/how-to/custom_views.md +++ b/docs/how-to/custom_views.md @@ -3,7 +3,7 @@ !!! note This is an advanced topic. If you're looking to create a view that retrieves data from an SQL database, please refer to the [SQL Views](sql_views.md) guide instead. -In this guide, we'll show you how to create views that connect to custom data sources. This could be useful if you need to retrieve data from a REST API, a NoSQL database, or any other data source not supported by the built-in base views. +In this guide, we'll show you how to create [structured views](../concepts/structured_views.md) that connect to custom data sources. This could be useful if you need to retrieve data from a REST API, a NoSQL database, or any other data source not supported by the built-in base views. # Summary Firstly, we will create a custom base view called `FilteredIterableBaseView` that retrieves data from a Python iterable and allows it to be filtered. It forms the base that implements data source-specific logic and lets other views inherit from it in order to define filters for specific use cases (similar to how `SqlAlchemyBaseView` is a base view provided by db-ally). @@ -54,13 +54,16 @@ class CandidateView(FilteredIterableBaseView): Lastly, we will illustrate how to use the `CandidatesView` like any other view in db-ally. We will create an instance of the view, add it to a collection, and start querying it. ## Types of Custom Views -There are two main ways to create custom views: +There are two main ways to create custom structured views: * By subclassing the `MethodsBaseView`: This is the most common method. These views expect filters to be defined as class methods and help manage them. All the built-in db-ally views use this method. * By subclassing the `BaseStructuredView` directly: This is a more low-level method. It makes no assumptions about how filters are defined and managed. This may be useful if you want to create a view that doesn't fit the standard db-ally view pattern, like when the list of available filters is dynamic or comes from an external source. In these cases, you'll need to create the entire filter management logic yourself by implementing the `list_filters` and `apply_filters` methods. If you're not sure which method to choose, we recommend starting with the `MethodsBaseView`. It's simpler and easier to use, and you can switch to the `BaseStructuredView` later if you find you need more control over filter management. For this guide, we'll focus on the `MethodsBaseView`. +!!! note + Both are methods of creating [structured views](../concepts/structured_views.md). If you're looking to create a [freeform view](../concepts/freeform_views.md), refer to the [Freeform Views](custom_freeform_views.md) guide instead. + ## The Example Throughout the guide, we'll use an example of creating a custom base view called `FilteredIterableBaseView`. To keep things simple, the "data source" it uses is a list defined in Python. The goal is to demonstrate how to create a custom view and define filters for it. In most real-world scenarios, data would usually come from an external source, like a REST API or a database. diff --git a/docs/how-to/pandas_views.md b/docs/how-to/pandas_views.md index 7db4d192..8c233c29 100644 --- a/docs/how-to/pandas_views.md +++ b/docs/how-to/pandas_views.md @@ -1,6 +1,6 @@ # How-To: Use Pandas DataFrames with db-ally -In this guide, you will learn how to write [views](../concepts/views.md) that use [Pandas](https://pandas.pydata.org/) DataFrames as their data source. You will understand how to define such a view, create filters that operate on the DataFrame, and register it while providing it with the source DataFrame. +In this guide, you will learn how to write [structured views](../concepts/structured_views.md) that use [Pandas](https://pandas.pydata.org/) DataFrames as their data source. You will understand how to define such a view, create filters that operate on the DataFrame, and register it while providing it with the source DataFrame. The example used in this guide is a DataFrame containing information about candidates. The DataFrame includes columns such as `id`, `name`, `country`, `years_of_experience`. This is the same use case as the one in the [Quickstart](../quickstart/index.md) and [Custom Views](./custom_views.md) guides. Please feel free to compare the different approaches. diff --git a/docs/how-to/sql_views.md b/docs/how-to/sql_views.md index 61c3343b..05731521 100644 --- a/docs/how-to/sql_views.md +++ b/docs/how-to/sql_views.md @@ -1,11 +1,11 @@ # How-To: Use SQL databases with db-ally -db-ally is a Python library that allows you to use natural language to query various data sources, including SQL databases. This guide will show you how to set up a db-ally view to query a SQL database using SQLAlchemy. The guide will work with [any database that SQLAlchemy supports](https://docs.sqlalchemy.org/en/20/dialects/), including SQLite, PostgreSQL, MySQL, Oracle, MS-SQL, Firebird, Sybase, and others. +db-ally is a Python library that allows you to use natural language to query various data sources, including SQL databases. This guide will show you how to set up a [structured view](../concepts/structured_views.md) to query a SQL database using SQLAlchemy. The guide will work with [any database that SQLAlchemy supports](https://docs.sqlalchemy.org/en/20/dialects/), including SQLite, PostgreSQL, MySQL, Oracle, MS-SQL, Firebird, Sybase, and others. ## Views The majority of the db-ally's codebase is independent of any particular kind of data source. The part that is specific to a data source is the view. A [view](../concepts/views.md) is a class that defines how to interact with a data source. It contains methods that define how to retrieve data from the data source and how to filter the data in response to natural language queries. -There are several methods for creating a view that connects to a SQL database, including [creating a custom view from scratch](./custom_views.md). However, in most cases the easiest will be to use the [`SqlAlchemyBaseView`][dbally.SqlAlchemyBaseView] class provided by db-ally. This class is designed to work with [SQLAlchemy](https://www.sqlalchemy.org/), a popular SQL toolkit and Object-Relational Mapping (ORM) library for Python. To define your view, you will need to produce a class that inherits from `SqlAlchemyBaseView`and implement the `get_select` method, which returns a [SQLAlchemy `Select`](https://docs.sqlalchemy.org/en/20/core/selectable.html#sqlalchemy.sql.expression.Select) object: +There are several methods for creating a view that connects to a SQL database, including [creating a custom view from scratch](./custom_views.md). However, in most cases the easiest will be to use the [`SqlAlchemyBaseView`][dbally.SqlAlchemyBaseView] class provided by db-ally. This tutorial is designed to work with [SQLAlchemy](https://www.sqlalchemy.org/), a popular SQL toolkit and Object-Relational Mapping (ORM) library for Python. To define your view, you will need to produce a class that inherits from `SqlAlchemyBaseView`and implement the `get_select` method, which returns a [SQLAlchemy `Select`](https://docs.sqlalchemy.org/en/20/core/selectable.html#sqlalchemy.sql.expression.Select) object: ```python from dbally import SqlAlchemyBaseView diff --git a/docs/quickstart/index.md b/docs/quickstart/index.md index 1096f02d..1a08f663 100644 --- a/docs/quickstart/index.md +++ b/docs/quickstart/index.md @@ -52,7 +52,7 @@ Candidate = Base.classes.candidates ## View Definition -To use db-ally, define the views you want to use. A [view](../concepts/views.md) is a class that specifies what to select from the database and includes methods that the AI model can use to filter rows. These methods are known as "filters". +To use db-ally, define the views you want to use. A [structured view](../concepts/structured_views.md) is a class that specifies what to select from the database and includes methods that the AI model can use to filter rows. These methods are known as "filters". ```python from dbally import decorators, SqlAlchemyBaseView diff --git a/docs/reference/views/index.md b/docs/reference/views/index.md index 4e6910e3..88068c48 100644 --- a/docs/reference/views/index.md +++ b/docs/reference/views/index.md @@ -1,15 +1,9 @@ # Base View classes !!! tip - * To understand the general idea better, visit [Views concept page](../../concepts/views.md). - * To learn how to support custom data sources, visit [How-to: create your custom view page](../../how-to/custom_views.md) + * To understand the general idea better, visit [Concept: Views](../../concepts/views.md) and [Concept: Freeform Views](../../concepts/freeform_views.md) + * To learn about structured views, which in most cases are the recommended way to define views, see the reference for the [`BaseStructuredView`][dbally.views.structured.BaseStructuredView] class -::: dbally.views.structured.BaseStructuredView - -::: dbally.views.exposed_functions.ExposedFunction - -::: dbally.views.exposed_functions.MethodParamWithTyping - -::: dbally.views.methods_base.MethodsBaseView +::: dbally.views.base.BaseView ::: dbally.data_models.execution_result.ViewExecutionResult diff --git a/docs/reference/views/structured.md b/docs/reference/views/structured.md new file mode 100644 index 00000000..d840c347 --- /dev/null +++ b/docs/reference/views/structured.md @@ -0,0 +1,13 @@ +# Structured View classes + +!!! tip + * To understand the general idea better, visit [Concept: Structured Views](../../concepts/structured_views.md) + * To learn how to support custom data sources, visit [How-to: create your custom view page](../../how-to/custom_views.md) + +::: dbally.views.structured.BaseStructuredView + +::: dbally.views.exposed_functions.ExposedFunction + +::: dbally.views.exposed_functions.MethodParamWithTyping + +::: dbally.views.methods_base.MethodsBaseView diff --git a/mkdocs.yml b/mkdocs.yml index abd95262..bedcd3b1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -9,9 +9,11 @@ nav: - Tutorials: - tutorials.md - Concepts: - - concepts/iql.md - concepts/views.md + - concepts/structured_views.md + - concepts/freeform_views.md - concepts/collections.md + - concepts/iql.md - concepts/similarity_indexes.md - concepts/nl_responder.md - How-to: @@ -19,6 +21,7 @@ nav: - how-to/sql_views.md - how-to/pandas_views.md - how-to/custom_views.md + - how-to/custom_freeform_views.md - Using similarity indexes: - how-to/use_custom_similarity_fetcher.md - how-to/use_custom_similarity_store.md @@ -31,6 +34,7 @@ nav: - reference/collection.md - Views: - reference/views/index.md + - reference/views/structured.md - reference/views/databases.md - reference/views/dataframe.md - IQL: diff --git a/src/dbally/collection.py b/src/dbally/collection.py index e5560bce..c4c008a0 100644 --- a/src/dbally/collection.py +++ b/src/dbally/collection.py @@ -13,6 +13,7 @@ from dbally.similarity.index import AbstractSimilarityIndex from dbally.utils.errors import NoViewFoundError from dbally.view_selection.base import ViewSelector +from dbally.views.base import BaseView from dbally.views.structured import BaseStructuredView @@ -69,21 +70,21 @@ def __init__( """ self.name = name self.n_retries = n_retries - self._views: Dict[str, Callable[[], BaseStructuredView]] = {} - self._builders: Dict[str, Callable[[], BaseStructuredView]] = {} + self._views: Dict[str, Callable[[], BaseView]] = {} + self._builders: Dict[str, Callable[[], BaseView]] = {} self._view_selector = view_selector self._nl_responder = nl_responder self._event_handlers = event_handlers self._llm_client = llm_client - T = TypeVar("T", bound=BaseStructuredView) + T = TypeVar("T", bound=BaseView) def add(self, view: Type[T], builder: Optional[Callable[[], T]] = None, name: Optional[str] = None) -> None: """ Register new [View](views/index.md) that will be available to query via the collection. Args: - view: A class inherithing from BaseStructuredView. Object of this type will be initialized during\ + view: A class inherithing from BaseView. Object of this type will be initialized during\ query execution. We expect Class instead of object, as otherwise Views must have been implemented\ stateless, which would be cumbersome. builder: Optional factory function that will be used to create the View instance. Use it when you\ @@ -126,7 +127,7 @@ def build_dogs_df_view(): self._views[name] = view self._builders[name] = builder - def get(self, name: str) -> BaseStructuredView: + def get(self, name: str) -> BaseView: """ Returns an instance of the view with the given name @@ -229,7 +230,7 @@ async def ask(self, question: str, dry_run: bool = False, return_natural_respons def get_similarity_indexes(self) -> Dict[AbstractSimilarityIndex, List[Tuple[str, str, str]]]: """ - List all similarity indexes from all views in the collection. + List all similarity indexes from all structured views in the collection. Returns: Dictionary with similarity indexes as keys and values containing lists of places where they are used @@ -238,6 +239,8 @@ def get_similarity_indexes(self) -> Dict[AbstractSimilarityIndex, List[Tuple[str indexes: Dict[AbstractSimilarityIndex, List[Tuple[str, str, str]]] = {} for view_name in self._views: view = self.get(view_name) + if not isinstance(view, BaseStructuredView): + continue filters = view.list_filters() for filter_ in filters: for param in filter_.parameters: @@ -247,7 +250,7 @@ def get_similarity_indexes(self) -> Dict[AbstractSimilarityIndex, List[Tuple[str async def update_similarity_indexes(self) -> None: """ - Update all similarity indexes from all views in the collection. + Update all similarity indexes from all structured views in the collection. Raises: IndexUpdateError: if updating any of the indexes fails. The exception provides `failed_indexes` attribute, diff --git a/tests/unit/test_collection.py b/tests/unit/test_collection.py index 18777e00..4ce99a20 100644 --- a/tests/unit/test_collection.py +++ b/tests/unit/test_collection.py @@ -12,6 +12,7 @@ from dbally.iql._exceptions import IQLError from dbally.utils.errors import NoViewFoundError from dbally.views.exposed_functions import ExposedFunction, MethodParamWithTyping +from dbally.views.structured import BaseStructuredView from tests.unit.mocks import MockIQLGenerator, MockLLMClient, MockSimilarityIndex, MockViewBase, MockViewSelector @@ -290,7 +291,9 @@ async def test_ask_feedback_loop(collection_feedback: Collection) -> None: ] with patch("dbally.iql._query.IQLQuery.parse") as mock_iql_query: mock_iql_query.side_effect = errors - iql_generator = collection_feedback.get("ViewWithMockGenerator").get_iql_generator(llm_client=MockLLMClient()) + view = collection_feedback.get("ViewWithMockGenerator") + assert isinstance(view, BaseStructuredView) + iql_generator = view.get_iql_generator(llm_client=MockLLMClient()) await collection_feedback.ask("Mock question") From ea8f61e4bdc46d800e946ec347cf8e27a84a9ef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Hordy=C5=84ski?= Date: Thu, 25 Apr 2024 11:58:04 +0200 Subject: [PATCH 2/2] Remove not finished doc from nav --- mkdocs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index bedcd3b1..d0fa3dcd 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -21,7 +21,6 @@ nav: - how-to/sql_views.md - how-to/pandas_views.md - how-to/custom_views.md - - how-to/custom_freeform_views.md - Using similarity indexes: - how-to/use_custom_similarity_fetcher.md - how-to/use_custom_similarity_store.md