diff --git a/Makefile b/Makefile deleted file mode 100644 index d670073..0000000 --- a/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= poetry run sphinx-build -SOURCEDIR = ./docsource -BUILDDIR = ./docs/_build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Build the docs -build-docs-local: - poetry run sphinx-apidoc ./src/sql_mock -o "$(SOURCEDIR)" - @$(SPHINXBUILD) -M html "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -build-docs-github: - @make build-docs-local - @cp -a docs/_build/html/. ./docs - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - - diff --git a/README.md b/README.md index 8496aec..1f878d3 100644 --- a/README.md +++ b/README.md @@ -8,17 +8,25 @@ The primary purpose of this library is to simplify the testing of SQL data models and queries by allowing users to mock input data and create tests for various scenarios. It provides a consistent and convenient way to test the execution of your query without the need to process a massive amount of data. -# Documentation - -A full documentation can be found [on the documentation page](https://deeplcom.github.io/sql-mock/) - -The library currently supports the following databases. -* BigQuery -* Clickhouse -* Redshift -* Snowflake - -## Installation +## Documentation + +* [Installation](#installation) +* [Quickstart](#quickstart) +* Basic usage + * [Create table mocks](/docs/defining_table_mocks.md) + * [Specifying default values](/docs/default_values.md) + * [Specifying the query to test](/docs/your_sql_query_to_test.md) + * [Result assertions](/docs/result_assertion.md) +* System specific usage + * [Use with BigQuery](/docs/bigquery.md) + * [Use with Clickhouse](/docs/clickhouse.md) + * [Use with Redshift](/docs/redshift.md) + * [Use with Snowflake](/docs/snowflake.md) + * [Use with dbt](/docs/dbt.md) + +You can find some examples in the [examples folder](https://github.com/DeepLcom/sql-mock/tree/main/examples). + +### Installation The library can be installed from [PyPI](https://pypi.org/project/sql-mock/) using pip: @@ -42,11 +50,105 @@ If you need to modify this source code, install the dependencies using poetry: poetry install --all-extras ``` +#### Recommended Setup for Pytest + +If you are using pytest, make sure to add a `conftest.py` file to the root of your project. +In the file add the following lines: + +```python +import pytest +pytest.register_assert_rewrite('sql_mock') +``` + +This allows you to get a rich comparison when using the `.assert_equal` method on the table mock instances. + +We also recommend using [pytest-icdiff](https://github.com/hjwp/pytest-icdiff) for better visibility on diffs of failed tests. + +### Quickstart + +Before diving into specific database scenarios, let's start with a simplified example of how SQL Mock works behind the scenes. + +1. You have an original SQL query, for instance: + + ```sql + -- path/to/query_for_result_table.sql + SELECT id FROM data.table1 + ``` + +2. Using SQL Mock, you define table mocks. You can use the built-in column types provided by SQL Mock. Available column types include `Int`, `String`, `Date`, and more. Each database type has their own column types. Define your tables by subclassing a mock table class that fits your database (e.g. `BigQueryTableMock`) and specifying the column types along with default values. In our example we use the `ClickHouseTableMock` class + + ```python + from sql_mock.clickhouse import column_mocks as col + from sql_mock.clickhouse.table_mocks import ClickHouseTableMock + from sql_mock.table_mocks import table_meta + + @table_meta(table_ref='data.table1') + class Table(ClickHouseTableMock): + id = col.Int(default=1) + name = col.String(default='Peter') + + @table_meta(table_ref='data.result_table', query_path='path/to/query_for_result_table.sql') + class ResultTable(ClickHouseTableMock): + id = col.Int(default=1) + ``` + +3. **Creating mock data:** Define mock data for your tables using dictionaries. Each dictionary represents a row in the table, with keys corresponding to column names. Table column keys that don't get a value will use the default. + + ```python + user_data = [ + {}, # This will use the defaults for both id and name + {'id': 2, 'name': 'Martin'}, + {'id': 3}, # This will use defaults for the name + ] + + input_table_mock = Table.from_dicts(user_data) + ``` + +4. **Getting results for a table mock:** Use the `from_mocks` method of the table mock object to generate mock query results based on your mock data. + + ```python + res = ResultTable.from_mocks(input_data=[input_table_mock]) + ``` + +5. Behind the scene SQL Mock replaces table references (e.g. `data.table1`) in your query with Common Table Expressions (CTEs) filled with dummy data. It can roughly be compared to something like this: + + ```sql + WITH data__table1 AS ( + -- Mocked inputs + SELECT + cast('1' AS 'String') AS id, + cast('Peter' AS 'String') AS name + UNION ALL + SELECT + cast('2' AS 'String') AS id, + cast('Martin' AS 'String') AS name + UNION ALL + SELECT + cast('3' AS 'String') AS id, + cast('Peter' AS 'String') AS name + ) + + result AS ( + -- Original query with replaced references + SELECT id FROM data__table1 + ) + + SELECT + cast(id AS 'String') AS id + FROM result + ``` + +6. Finally, you can compare your results to some expected results using the `assert_equal` method. + + ```python + expected = [{'id': '1'},{'id': '2'},{'id': '3'}] + res.assert_equal(expected) + ``` + ## Pydantic V1 vs. V2 SQL Mock's published version supports Pydantic V2. You might run into issues when your code depends on Pydantic V1. -We have an alternative branch you can install from that supports Pydantic V1 in the meanwhile: https://github.com/DeepLcom/sql-mock/tree/pydantic-v1 - +We have an alternative branch you can install from that supports Pydantic V1 in the meanwhile: ## Contributing @@ -56,10 +158,10 @@ We welcome contributions to improve and enhance this open-source project. Whethe If you encounter a bug, have a feature request, or face any issues with the project, we encourage you to report them using the project's issue tracker. When creating an issue, please include the following information: -- A clear and descriptive title. -- A detailed description of the problem or suggestion. -- Steps to reproduce the issue (if applicable). -- Any error messages or screenshots that help clarify the problem. +* A clear and descriptive title. +* A detailed description of the problem or suggestion. +* Steps to reproduce the issue (if applicable). +* Any error messages or screenshots that help clarify the problem. ### Feature Requests @@ -79,3 +181,64 @@ The SQL Mock Buddy can be accessed here: [https://chat.openai.com/g/g-FIXNcqu1l- SQL Mock Buddy should help you to get started quickly with SQL Mock. It is still in beta mode and you should definitely double-check its output! + +## FAQ + +### My database system is not supported yet but I want to use SQL Mock. What should I do? + +We are planning to add more and more supported database systems. However, if your system is not supported yet, you can still use SQL Mock. There are only 2 things you need to do: + +#### Create your `TableMock` class + +First, you need to create a `TableMock` class for your database system that inherits from `sql_mock.table_mocks.BaseTableMock`. + +That class needs to implement the `_get_results` method which should make sure to fetch the results of a query (e.g. produced by `self._generate_query()`) and return it as list of dictionaries. + +Look at one of the existing client libraries to see how this could work (e.g. [BigQueryTableMock](https://github.com/DeepLcom/sql-mock/blob/main/src/sql_mock/bigquery/table_mocks.py)). + +You might want to create a settings class as well in case you need some specific connection settings to be available within the `_get_results` method. + +#### Create your `ColumnMocks` + +Your database system might support specific database types. In order to make them available as column types, you can use the `sql_mock.column_mocks.BaseColumnMock` class as a base and inherit your specific column types from it. +For most of your column mocks you might only need to specify the `dtype` that should be used to parse the inputs. + +A good practise is to create a `BaseColumnMock` class that is specific to your database and inherit all your column types from it, e.g.: + +```python +from sql_mock.column_mocks import BaseColumnMock + +class MyFanceDatabaseColumnMock(BaseColumnMock): + # In case you need some specific logic that overwrites the default behavior, you can do so here + pass + +class Int(MyFanceDatabaseColumnMock): + dtype = "Integer" + +class String(MyFanceDatabaseColumnMock): + dtype = "String" +``` + +#### Contribute your database setup + +There will definitely be folks in the community that are in the need of support for the database you just created all the setup for. +Feel free to create a PR on this repository that we can start supporting your database system! + +### I am missing a specific BaseColumnMock type for my model fields + +We implemented some basic column types but it could happen that you don't find the one you need. +Luckily, you can easily create those with the tools provided. +The only thing you need to do is to inherit from the `BaseColumnMock` that is specific to your database system (e.g. `BigQueryColumnMock`) and write classes for the column mocks you are missing. Usually you only need to set the correct `dtype`. This would later be used in the `cast(col to )` expression. + +```python +# Replace the import with the database system you are using +from sql_mock.bigquery.column_mock import BigQueryColumnMock + +class MyFancyMissingColType(BigQueryColumnMock): + dtype = "FancyMissingColType" + + # In case you need to implement additional logic for casting, you can do so here + ... +``` + +**Don't forget to create a PR in case you feel that your column mock type could be useful for the community**! diff --git a/docs/.buildinfo b/docs/.buildinfo deleted file mode 100644 index 94c9eec..0000000 --- a/docs/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: c82d665cc338348dd2b6777f2bd67a49 -tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/.nojekyll b/docs/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/docs/_sources/faq.md.txt b/docs/_sources/faq.md.txt deleted file mode 100644 index 095a1a0..0000000 --- a/docs/_sources/faq.md.txt +++ /dev/null @@ -1,62 +0,0 @@ - -# FAQ - -## My database system is not supported yet but I want to use SQL Mock. What should I do? - -We are planning to add more and more supported database systems. However, if your system is not supported yet, you can still use SQL Mock. There are only 2 things you need to do: - -### Create your `MockTable` class - -First, you need to create a `MockTable` class for your database system that inherits from `sql_mock.table_mocks.BaseMockTable`. - -That class needs to implement the `_get_results` method which should make sure to fetch the results of a query (e.g. produced by `self._generate_query()`) and return it as list of dictionaries. - -Look at one of the existing client libraries to see how this could work (e.g. [BigQueryMockTable](https://github.com/DeepLcom/sql-mock/blob/main/src/sql_mock/bigquery/table_mocks.py)). - -You might want to create a settings class as well in case you need some specific connection settings to be available within the `_get_results` method. - -### Create your `ColumnMocks` - -Your database system might support specific database types. In order to make them available as column types, you can use the `sql_mock.column_mocks.ColumnMock` class as a base and inherit your specific column types from it. -For most of your column mocks you might only need to specify the `dtype` that should be used to parse the inputs. - -A good practise is to create a `ColumnMock` class that is specific to your database and inherit all your column types from it, e.g.: - -```python -from sql_mock.column_mocks import ColumnMock - -class MyFanceDatabaseColumnMock(ColumnMock): - # In case you need some specific logic that overwrites the default behavior, you can do so here - pass - -class Int(MyFanceDatabaseColumnMock): - dtype = "Integer" - -class String(MyFanceDatabaseColumnMock): - dtype = "String" -``` - -### Contribute your database setup - -There will definitely be folks in the community that are in the need of support for the database you just created all the setup for. -Feel free to create a PR on this repository that we can start supporting your database system! - - -## I am missing a specific ColumnMock type for my model fields - -We implemented some basic column types but it could happen that you don't find the one you need. -Luckily, you can easily create those with the tools provided. -The only thing you need to do is to inherit from the `ColumnMock` that is specific to your database system (e.g. `BigQueryColumnMock`) and write classes for the column mocks you are missing. Usually you only need to set the correct `dtype`. This would later be used in the `cast(col to )` expression. - -```python -# Replace the import with the database system you are using -from sql_mock.bigquery.column_mock import BigQueryColumnMock - -class MyFancyMissingColType(BigQueryColumnMock): - dtype = "FancyMissingColType" - - # In case you need to implement additional logic for casting, you can do so here - ... -``` - -**Don't forget to create a PR in case you feel that your column mock type could be useful for the community**! diff --git a/docs/_sources/getting_started/installation.md.txt b/docs/_sources/getting_started/installation.md.txt deleted file mode 100644 index 0a36650..0000000 --- a/docs/_sources/getting_started/installation.md.txt +++ /dev/null @@ -1,39 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Installation - -The library can be installed from [PyPI](https://pypi.org/project/sql-mock/) using pip: - -```shell -# BigQuery -pip install --upgrade "sql-mock[bigquery]" - -# Clickhouse -pip install --upgrade "sql-mock[clickhouse]" - -# Redshift -pip install --upgrade "sql-mock[redshift]" - -# Snowflake -pip install --upgrade "sql-mock[snowflake]" -``` - -If you need to modify this source code, install the dependencies using poetry: - -```shell -poetry install --all-extras -``` - - -## Recommended Setup for Pytest -If you are using pytest, make sure to add a `conftest.py` file to the root of your project. -In the file add the following lines: -```python -import pytest -pytest.register_assert_rewrite('sql_mock') -``` -This allows you to get a rich comparison when using the `.assert_equal` method on the table mock instances. - -We also recommend using [pytest-icdiff](https://github.com/hjwp/pytest-icdiff) for better visibility on diffs of failed tests. diff --git a/docs/_sources/getting_started/quickstart.md.txt b/docs/_sources/getting_started/quickstart.md.txt deleted file mode 100644 index e8b2cd4..0000000 --- a/docs/_sources/getting_started/quickstart.md.txt +++ /dev/null @@ -1,81 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Quickstart - -Before diving into specific database scenarios, let's start with a simplified example of how SQL Mock works behind the scenes. - - -1. You have an original SQL query, for instance: - ```sql - -- path/to/query_for_result_table.sql - SELECT id FROM data.table1 - ``` - - -2. Using SQL Mock, you define mock tables. You can use the built-in column types provided by SQL Mock. Available column types include `Int`, `String`, `Date`, and more. Each database type has their own column types. Define your tables by subclassing a mock table class that fits your database (e.g. `BigQueryMockTable`) and specifying the column types along with default values. In our example we use the `ClickHouseTableMock` class - ```python - from sql_mock.clickhouse import column_mocks as col - from sql_mock.clickhouse.table_mocks import ClickHouseTableMock - from sql_mock.table_mocks import table_meta - - @table_meta(table_ref='data.table1') - class Table(ClickHouseTableMock): - id = col.Int(default=1) - name = col.String(default='Peter') - - @table_meta(table_ref='data.result_table', query_path='path/to/query_for_result_table.sql') - class ResultTable(ClickHouseTableMock): - id = col.Int(default=1) - ``` - -3. **Creating mock data:** Define mock data for your tables using dictionaries. Each dictionary represents a row in the table, with keys corresponding to column names. Table column keys that don't get a value will use the default. - ```python - user_data = [ - {}, # This will use the defaults for both id and name - {'id': 2, 'name': 'Martin'}, - {'id': 3}, # This will use defaults for the name - ] - - input_table_mock = Table.from_dicts(user_data) - ``` - - -4. **Getting results for a table mock:** Use the `from_mocks` method of the table mock object to generate mock query results based on your mock data. - ```python - res = ResultTable.from_mocks(input_data=[input_table_mock]) - ``` - -5. Behind the scene SQL Mock replaces table references (e.g. `data.table1`) in your query with Common Table Expressions (CTEs) filled with dummy data. It can roughly be compared to something like this: - ```sql - WITH data__table1 AS ( - -- Mocked inputs - SELECT - cast('1' AS 'String') AS id, - cast('Peter' AS 'String') AS name - UNION ALL - SELECT - cast('2' AS 'String') AS id, - cast('Martin' AS 'String') AS name - UNION ALL - SELECT - cast('3' AS 'String') AS id, - cast('Peter' AS 'String') AS name - ) - - result AS ( - -- Original query with replaced references - SELECT id FROM data__table1 - ) - - SELECT - cast(id AS 'String') AS id - FROM result - ``` - -6. Finally, you can compare your results to some expected results using the `assert_equal` method. - ```python - expected = [{'id': '1'},{'id': '2'},{'id': '3'}] - res.assert_equal(expected) - ``` diff --git a/docs/_sources/index.rst.txt b/docs/_sources/index.rst.txt deleted file mode 100644 index b78bacb..0000000 --- a/docs/_sources/index.rst.txt +++ /dev/null @@ -1,60 +0,0 @@ -.. SQL Mock documentation master file, created by - sphinx-quickstart on Wed Nov 1 07:36:03 2023. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to SQL Mock's documentation! -==================================== - -The primary purpose of this library is to simplify the testing of SQL data models and queries by allowing users to mock input data and create tests for various scenarios. -It provides a consistent and convenient way to test the execution of your query without the need to process a massive amount of data. - -.. meta:: - :google-site-verification: ohDOHPn1YMLYMaWQpFmqQfPW_KRZXNK9Gq47pP57VQM - -.. automodule:: sql_mock - :members: - :undoc-members: - :show-inheritance: - -.. toctree:: - :maxdepth: 3 - :caption: Getting Started - - getting_started/installation - getting_started/quickstart - faq - -.. toctree:: - :maxdepth: 3 - :caption: Basic Usage - - usage/defining_table_mocks - usage/dbt - usage/your_sql_query_to_test - usage/result_assertion - usage/default_values - usage/examples - -.. toctree:: - :maxdepth: 3 - :caption: Database Specifics - - usage/bigquery/index - usage/clickhouse/index - usage/redshift/index - usage/snowflake/index - -.. toctree:: - :maxdepth: 3 - :caption: API Reference - - API Reference - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/_sources/modules.rst.txt b/docs/_sources/modules.rst.txt deleted file mode 100644 index f4baeab..0000000 --- a/docs/_sources/modules.rst.txt +++ /dev/null @@ -1,8 +0,0 @@ -sql_mock -======== - -.. toctree:: - :maxdepth: 4 - :hidden: - - sql_mock diff --git a/docs/_sources/robots.txt b/docs/_sources/robots.txt deleted file mode 100644 index 7557cc5..0000000 --- a/docs/_sources/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -User-agent: * - -Sitemap: https://deeplcom.github.io/sql-mock/sitemap.xml diff --git a/docs/_sources/sql_mock.bigquery.rst.txt b/docs/_sources/sql_mock.bigquery.rst.txt deleted file mode 100644 index 0ec2aea..0000000 --- a/docs/_sources/sql_mock.bigquery.rst.txt +++ /dev/null @@ -1,37 +0,0 @@ -sql\_mock.bigquery package -========================== - -Submodules ----------- - -sql\_mock.bigquery.column\_mocks module ---------------------------------------- - -.. automodule:: sql_mock.bigquery.column_mocks - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.bigquery.settings module ----------------------------------- - -.. automodule:: sql_mock.bigquery.settings - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.bigquery.table\_mocks module --------------------------------------- - -.. automodule:: sql_mock.bigquery.table_mocks - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: sql_mock.bigquery - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/_sources/sql_mock.clickhouse.rst.txt b/docs/_sources/sql_mock.clickhouse.rst.txt deleted file mode 100644 index d8577e0..0000000 --- a/docs/_sources/sql_mock.clickhouse.rst.txt +++ /dev/null @@ -1,37 +0,0 @@ -sql\_mock.clickhouse package -============================ - -Submodules ----------- - -sql\_mock.clickhouse.column\_mocks module ------------------------------------------ - -.. automodule:: sql_mock.clickhouse.column_mocks - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.clickhouse.settings module ------------------------------------- - -.. automodule:: sql_mock.clickhouse.settings - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.clickhouse.table\_mocks module ----------------------------------------- - -.. automodule:: sql_mock.clickhouse.table_mocks - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: sql_mock.clickhouse - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/_sources/sql_mock.redshift.rst.txt b/docs/_sources/sql_mock.redshift.rst.txt deleted file mode 100644 index 1a3a286..0000000 --- a/docs/_sources/sql_mock.redshift.rst.txt +++ /dev/null @@ -1,37 +0,0 @@ -sql\_mock.redshift package -========================== - -Submodules ----------- - -sql\_mock.redshift.column\_mocks module ---------------------------------------- - -.. automodule:: sql_mock.redshift.column_mocks - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.redshift.settings module ----------------------------------- - -.. automodule:: sql_mock.redshift.settings - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.redshift.table\_mocks module --------------------------------------- - -.. automodule:: sql_mock.redshift.table_mocks - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: sql_mock.redshift - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/_sources/sql_mock.rst.txt b/docs/_sources/sql_mock.rst.txt deleted file mode 100644 index 407d078..0000000 --- a/docs/_sources/sql_mock.rst.txt +++ /dev/null @@ -1,54 +0,0 @@ -sql\_mock package -================= - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - sql_mock.bigquery - sql_mock.clickhouse - -Submodules ----------- - -sql\_mock.column\_mocks module ------------------------------- - -.. automodule:: sql_mock.column_mocks - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.constants module --------------------------- - -.. automodule:: sql_mock.constants - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.exceptions module ---------------------------- - -.. automodule:: sql_mock.exceptions - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.table\_mocks module ------------------------------ - -.. automodule:: sql_mock.table_mocks - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: sql_mock - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/_sources/sql_mock.snowflake.rst.txt b/docs/_sources/sql_mock.snowflake.rst.txt deleted file mode 100644 index ba3ca51..0000000 --- a/docs/_sources/sql_mock.snowflake.rst.txt +++ /dev/null @@ -1,37 +0,0 @@ -sql\_mock.snowflake package -=========================== - -Submodules ----------- - -sql\_mock.snowflake.column\_mocks module ----------------------------------------- - -.. automodule:: sql_mock.snowflake.column_mocks - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.snowflake.settings module ------------------------------------ - -.. automodule:: sql_mock.snowflake.settings - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.snowflake.table\_mocks module ---------------------------------------- - -.. automodule:: sql_mock.snowflake.table_mocks - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: sql_mock.snowflake - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/_sources/usage/bigquery/examples.md.txt b/docs/_sources/usage/bigquery/examples.md.txt deleted file mode 100644 index 99523fa..0000000 --- a/docs/_sources/usage/bigquery/examples.md.txt +++ /dev/null @@ -1,65 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Example: Testing Subscription Counts in BigQuery - -```python -import datetime -from sql_mock.bigquery import column_mocks as col -from sql_mock.bigquery.table_mocks import BigQueryMockTable -from sql_mock.table_mocks import table_meta - -# Define mock tables for your data model that inherit from BigQueryMockTable -@table_meta(table_ref='data.users') -class UserTable(BigQueryMockTable): - user_id = col.Int(default=1) - user_name = col.String(default='Mr. T') - - -@table_meta(table_ref='data.subscriptions') -class SubscriptionTable(BigQueryMockTable): - subscription_id = col.Int(default=1) - period_start_date = col.Date(default=datetime.date(2023, 9, 5)) - period_end_date = col.Date(default=datetime.date(2023, 9, 5)) - user_id = col.Int(default=1) - - -# Define a mock table for your expected results -class SubscriptionCountTable(BigQueryMockTable): - subscription_count = col.Int(default=1) - user_id = col.Int(default=1) - -# Your original SQL query -query = """ -SELECT - count(*) AS subscription_count, - user_id -FROM data.users -LEFT JOIN data.subscriptions USING(user_id) -GROUP BY user_id -""" - -# Create mock data for the 'data.users' and 'data.subscriptions' tables -users = UserTable.from_dicts([{'user_id': 1}, {'user_id': 2}]) -subscriptions = SubscriptionTable.from_dicts([ - {'subscription_id': 1, 'user_id': 1}, - {'subscription_id': 2, 'user_id': 1}, - {'subscription_id': 2, 'user_id': 2}, -]) - -# Define your expected results -expected = [ - {'user_id': 1, 'subscription_count': 2}, - {'user_id': 2, 'subscription_count': 1} -] - -# Simulate the SQL query using SQL Mock -res = SubscriptionCountTable.from_mocks( - query=query, - input_data=[users, subscriptions] -) - -# Assert the results -res.assert_equal(expected) -``` diff --git a/docs/_sources/usage/bigquery/index.rst.txt b/docs/_sources/usage/bigquery/index.rst.txt deleted file mode 100644 index 5af047d..0000000 --- a/docs/_sources/usage/bigquery/index.rst.txt +++ /dev/null @@ -1,10 +0,0 @@ -BigQuery -===================== - -This section documents the specifics on how to use SQL Mock with BigQuery - -.. toctree:: - :maxdepth: 4 - - ./settings.md - ./examples.md diff --git a/docs/_sources/usage/bigquery/settings.md.txt b/docs/_sources/usage/bigquery/settings.md.txt deleted file mode 100644 index 9e261ad..0000000 --- a/docs/_sources/usage/bigquery/settings.md.txt +++ /dev/null @@ -1,9 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Settings - -In order to use sql-mock with BigQuery, ensure you have the `GOOGLE_APPLICATION_CREDENTIALS` environment variable correctly set to point to a service account file. - -You need to service account file in order to let SQL Mock connect to BigQuery while running the tests. diff --git a/docs/_sources/usage/clickhouse/index.rst.txt b/docs/_sources/usage/clickhouse/index.rst.txt deleted file mode 100644 index 4bca7b1..0000000 --- a/docs/_sources/usage/clickhouse/index.rst.txt +++ /dev/null @@ -1,10 +0,0 @@ -Clickhouse -===================== - -This section documents the specifics on how to use SQL Mock with Clickhouse - -.. toctree:: - :maxdepth: 4 - - ./settings.md - ./examples.md diff --git a/docs/_sources/usage/clickhouse/settings.md.txt b/docs/_sources/usage/clickhouse/settings.md.txt deleted file mode 100644 index 8e9d6fb..0000000 --- a/docs/_sources/usage/clickhouse/settings.md.txt +++ /dev/null @@ -1,13 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Settings - -In order to use SQL Mock with Clickhouse, you need to provide the following environment variables when you run tests: -* `SQL_MOCK_CLICKHOUSE_HOST`: Host of your Clickhouse instance -* `SQL_MOCK_CLICKHOUSE_USER`: User you want to use for the connection -* `SQL_MOCK_CLICKHOUSE_PASSWORD`: Password of your user -* `SQL_MOCK_CLICKHOUSE_PORT`: Port of your Clickhouse instance - -Having those environment variables enables SQL Mock to connect to your Clickhouse instance. diff --git a/docs/_sources/usage/dbt.md.txt b/docs/_sources/usage/dbt.md.txt deleted file mode 100644 index 5d30985..0000000 --- a/docs/_sources/usage/dbt.md.txt +++ /dev/null @@ -1,130 +0,0 @@ -# Use with dbt - -## Introduction - -This guide will provide a quick start on how to use SQLMock with dbt (data build tool). You can use it to mock dbt models, sources, and seed models. We'll cover how to use these features effectively in your unit tests. - -## Prerequisites - -- A working dbt project with a `manifest.json` file **that has the latest compiled run.** (make sure to run `dbt compile`). -- The SQLMock library installed in your Python environment. - -## Configuration - -### Setting the dbt Manifest Path - -Initialize your testing environment by setting the global path to your dbt manifest file: - -```python -from sql_mock.config import SQLMockConfig - -SQLMockConfig.set_dbt_manifest_path('/path/to/your/dbt/manifest.json') -``` - -## Creating Mock Tables - -SQLMock offers specialized decorators for different dbt entities: models, sources, and seeds. - -### dbt Model Mock Table - -For dbt models, use the `dbt_model_meta` decorator from `sql_mock.dbt`. This decorator is suited for mocking the transformed data produced by dbt models. - -```python -from sql_mock.dbt import dbt_model_meta -from sql_mock.bigquery.table_mocks import BigQueryMockTable - -@dbt_model_meta(model_name="your_dbt_model_name") -class YourDBTModelTable(BigQueryMockTable): - # Define your table columns and other necessary attributes here - ... -``` - -### dbt Source Mock Table - -For dbt sources, use the `dbt_source_meta` decorator from `sql_mock.dbt`. This is ideal for mocking the raw data sources that dbt models consume. - -```python -from sql_mock.dbt import dbt_source_meta -from sql_mock.bigquery.table_mocks import BigQueryMockTable - -@dbt_source_meta(source_name="your_source_name", table_name="your_source_table") -class YourDBTSourceTable(BigQueryMockTable): - # Define your table columns and other necessary attributes here - ... -``` - -### dbt Seed Mock Table - -For dbt seeds, which are static data sets loaded into the database, use the `dbt_seed_meta` decorator from `sql_mock.dbt`. - -```python -from sql_mock.dbt import dbt_seed_meta -from sql_mock.bigquery.table_mocks import BigQueryMockTable - -@dbt_seed_meta(seed_name="your_dbt_seed_name") -class YourDBTSeedTable(BigQueryMockTable): - # Define your table columns and other necessary attributes here - ... -``` - -## Example: Testing a dbt Model with Upstream Source and Seed Data - -Let’s consider a dbt model named `monthly_user_spend` that aggregates data from a source `user_transactions` and a seed `user_categories`. - -### Step 1: Define Your Source and Seed Mock Tables - -```python -@dbt_source_meta(source_name="transactions", table_name="user_transactions") -class UserTransactionsTable(BigQueryMockTable): - transaction_id = col.Int(default=1) - user_id = col.Int(default=1) - amount = col.Float(default=1.0) - transaction_date = col.Date(default='2023-12-24') - -@dbt_seed_meta(seed_name="user_categories") -class UserCategoriesTable(BigQueryMockTable): - user_id = col.Int(default=1) - category = col.String(default='foo') -``` - -### Step 2: Define Your Model Mock Table - -```python -@dbt_model_meta(model_name="monthly_user_spend") -class MonthlyUserSpendTable(BigQueryMockTable): - user_id = col.Int(default=1) - month = col.String(default='foo') - total_spend = col.Float(default=1.0) - category = col.String(default='foo') -``` - -### Step 3: Write Your Test Case - -```python -import datetime - -def test_monthly_user_spend_model(): - # Mock input data for UserTransactionsTable and UserCategoriesTable - transactions_data = [ - {"transaction_id": 1, "user_id": 1, "amount": 120.0, "transaction_date": datetime.date(2023, 1, 10)}, - {"transaction_id": 2, "user_id": 2, "amount": 150.0, "transaction_date": datetime.date(2023, 1, 20)}, - ] - - categories_data = [ - {"user_id": 1, "category": "Premium"}, - {"user_id": 2, "category": "Standard"} - ] - - transactions_table = UserTransactionsTable.from_dicts(transactions_data) - categories_table = UserCategoriesTable.from_dicts(categories_data) - - # Expected result - expected_output = [ - {"user_id": 1, "month": "2023-01", "total_spend": 120.0, "category": "Premium"}, - {"user_id": 2, "month": "2023-01", "total_spend": 150.0, "category": "Standard"}, - ] - - monthly_spend_table = MonthlyUserSpendTable.from_mocks(input_data=[transactions_table, categories_table]) - - monthly_spend_table.assert_equal(expected_output) -``` diff --git a/docs/_sources/usage/default_values.md.txt b/docs/_sources/usage/default_values.md.txt deleted file mode 100644 index 471c94d..0000000 --- a/docs/_sources/usage/default_values.md.txt +++ /dev/null @@ -1,71 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Default values - -Testing SQL queries can often involve repetitive setup for mock tables. In SQLMock, one effective way to streamline this process is by using default values. By setting reasonable defaults, you can significantly reduce the boilerplate code in your tests, especially when dealing with multiple input tables or complex queries. Let’s explore how you can efficiently implement this. - -## Utilizing Default Values in MockTable Fields - -Defining default values at the field level in your mock tables is straightforward. -The default argument in the field definition allows you to set default values consistency across all test scenarios in one step. -They are particularly useful for ensuring that joins and other query functionalities operate correctly. - -Here's an example: - -```python -@table_meta(table_ref="data.users") -class UserTable(BigQueryMockTable): - user_id = col.Int(default=1) - user_name = col.String(default="Mr. T") - -# Create instances of the UserTable with various combinations of defaults and specified values -users = UserTable.from_dicts([ - {}, # Left empty {} uses default values --> {"user_id": 1, "user_name": "Mr. T"} - {"user_id": 2}, # Overrides user_id but uses default for user_name - {"user_id": 3, "user_name": "Nala"} # No defaults used here -]) -``` - -## Setting Mock Defaults with table_meta - - -When defining your MockTable classes, the `table_meta` decorator accepts a `default_inputs` argument. -The Mock instances passed here, will be used as defaults in the `from_mocks` method. - -Consider this example: - -```python -@table_meta( - query_path="./examples/test_query.sql", - default_inputs=[UserTable([]), SubscriptionTable([])] # We can provide defaults for the class if needed. -) -class MultipleSubscriptionUsersTable(BigQueryMockTable): - user_id = col.Int(default=1) - -# Setting up different scenarios to demonstrate the use of defaults -users = UserTable.from_dicts([ - {"user_id": 1}, - {"user_id": 2} -]) -subscriptions = SubscriptionTable.from_dicts( - [ - {"subscription_id": 1, "user_id": 1}, - {"subscription_id": 2, "user_id": 1}, - {"subscription_id": 2, "user_id": 2}, - ] -) - -# Utilizing the default inputs set in the table_meta -res = MultipleSubscriptionUsersTable.from_mocks(input_data=[]) -res = MultipleSubscriptionUsersTable.from_mocks(input_data=[users]) # Using only users, defaults for others -res = MultipleSubscriptionUsersTable.from_mocks(input_data=[users, subscriptions]) # Overriding defaults -``` - -## When is this useful? - -* **Safe time and code by changing only the data you need for your test case:** You can only change single columns for the data you provide for a test case. The rest will be filled by defaults. -* **Simplifying Happy Path Testing:** Validate basic functionality and syntax correctness of your SQL queries with minimal setup. -* **Testing Subset Logic:** When certain tables in your query don't require data, default values can help focus on specific test scenarios. -* **Provide reasonable defaults for joins:** In tests with numerous input tables you can specify inputs that joins between tables work. For frequent addition of new tables, defaults can prevent the need for extensive refactoring. diff --git a/docs/_sources/usage/defining_table_mocks.md.txt b/docs/_sources/usage/defining_table_mocks.md.txt deleted file mode 100644 index 826430b..0000000 --- a/docs/_sources/usage/defining_table_mocks.md.txt +++ /dev/null @@ -1,51 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Defining table mocks - -When you want to provide mocked data to test your SQL model, you need to create MockTable classes for all upstream data that your model uses, as well as for the model you want to test. Those mock tables can be created by inheriting from a `BaseMockTable` class for the database provider you are using (e.g. `BigQueryMockTable`). - -**We recommend to have a central `model.py` file where you create those models that you can easily reuse them across your tests** - -```python -# models.py - -from sql_mock.bigquery import column_mocks as col -from sql_mock.bigquery.table_mocks import BigQueryMockTable, table_meta - -# The models you are goign to use as inputs need to have a `table_ref` specified -@table_meta(table_ref='data.table1') -class Table(BigQueryMockTable): - id = col.Int(default=1) - name = col.String(default='Peter') - -@table_meta( - table_ref='data.result_table', - query_path='path/to/query_for_result_table.sql', - default_inputs=[Table()] # You can provide default inputs on a class level -) -class ResultTable(BigQueryMockTable): - id = col.Int(default=1) -``` - -Some important things to mention: - -**The models you are goign to use as inputs need to have a `table_ref` specified.** -The `table_ref` is how the table will be referenced in your production database (usually some pattern like `.`) - -**The result model needs to have a query.** -There are currently 2 ways to provide a query to the model: - -1. Pass a path to your query file in the class definition using the `table_meta` decorator. This allows us to only specify it once. - ```python - @table_meta(table_ref='data.result_table', query_path='path/to/query_for_result_table.sql') - class ResultTable(BigQueryMockTable): - ... - ``` -2. Pass it as `query` argument to the `from_mocks` method when you are using the model in your test. This will also overwrite whatever query was read from the `query_path` in the `table_meta` decorator. - ```python - res = ResultTable.from_mocks(query='SELECT 1', input_data=[]) - ``` - -More details on how to handle queries can be found [in the "Your SQL query to test" section](./your_sql_query_to_test.md) diff --git a/docs/_sources/usage/examples.md.txt b/docs/_sources/usage/examples.md.txt deleted file mode 100644 index 39763e6..0000000 --- a/docs/_sources/usage/examples.md.txt +++ /dev/null @@ -1,7 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Examples - -You can find some examples in the [examples folder](https://github.com/DeepLcom/sql-mock/tree/main/examples). diff --git a/docs/_sources/usage/redshift/examples.md.txt b/docs/_sources/usage/redshift/examples.md.txt deleted file mode 100644 index 24691c3..0000000 --- a/docs/_sources/usage/redshift/examples.md.txt +++ /dev/null @@ -1,61 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Example: Testing Subscription Counts in Redshift - -```python -import datetime -from sql_mock.redshift import column_mocks as col -from sql_mock.redshift.table_mocks import RedshiftMockTable -from sql_mock.table_mocks import table_meta - -# Define mock tables for your data model that inherit from RedshiftMockTable -@table_meta(table_ref="data.users") -class UserTable(RedshiftMockTable): - user_id = col.INTEGER(default=1) - user_name = col.VARCHAR(default="Mr. T") - - -@table_meta(table_ref="data.subscriptions") -class SubscriptionTable(RedshiftMockTable): - subscription_id = col.INTEGER(default=1) - period_start_date = col.DATE(default=datetime.date(2023, 9, 5)) - period_end_date = col.DATE(default=datetime.date(2023, 9, 5)) - user_id = col.INTEGER(default=1) - -# Define a mock table for your expected results -class SubscriptionCountTable(RedshiftMockTable): - subscription_count = col.INTEGER(default=1) - user_id = col.INTEGER(default=1) - -# Your original SQL query -query = """ -SELECT - count(*) AS subscription_count, - user_id -FROM data.users -LEFT JOIN data.subscriptions USING(user_id) -GROUP BY user_id -""" - -# Create mock data for the 'data.users' and 'data.subscriptions' tables -users = UserTable.from_dicts([{'user_id': 1}, {'user_id': 2}]) -subscriptions = SubscriptionTable.from_dicts([ - {'subscription_id': 1, 'user_id': 1}, - {'subscription_id': 2, 'user_id': 1}, - {'subscription_id': 2, 'user_id': 2}, -]) - -# Define your expected results -expected = [ - {'user_id': 1, 'subscription_count': 2}, - {'user_id': 2, 'subscription_count': 1} -] - -# Simulate the SQL query using SQL Mock -res = SubscriptionCountTable.from_mocks(query=query, input_data=[users, subscriptions]) - -# Assert the results -res.assert_equal(expected) -``` diff --git a/docs/_sources/usage/redshift/index.rst.txt b/docs/_sources/usage/redshift/index.rst.txt deleted file mode 100644 index b2f7caa..0000000 --- a/docs/_sources/usage/redshift/index.rst.txt +++ /dev/null @@ -1,10 +0,0 @@ -Redshift -===================== - -This section documents the specifics on how to use SQL Mock with Redshift - -.. toctree:: - :maxdepth: 4 - - ./settings.md - ./examples.md diff --git a/docs/_sources/usage/redshift/settings.md.txt b/docs/_sources/usage/redshift/settings.md.txt deleted file mode 100644 index fdf1ba0..0000000 --- a/docs/_sources/usage/redshift/settings.md.txt +++ /dev/null @@ -1,14 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Settings - -In order to use SQL Mock with Redshift, you need to provide the following environment variables when you run tests: - -* `SQL_MOCK_REDSHIFT_HOST`: The host of your Redshift instance -* `SQL_MOCK_REDSHIFT_USER`: The user of your Redshift instance -* `SQL_MOCK_REDSHIFT_PASSWORD`: The password of your Redshift instance -* `SQL_MOCK_REDSHIFT_PORT`: The port of your Redshift instance - -Having those environment variables enables SQL Mock to connect to your Redshift instance. diff --git a/docs/_sources/usage/result_assertion.md.txt b/docs/_sources/usage/result_assertion.md.txt deleted file mode 100644 index fecaa11..0000000 --- a/docs/_sources/usage/result_assertion.md.txt +++ /dev/null @@ -1,88 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Result assertion - -There are 2 ways how you can check the output of your query given the mocked input data on your Table Mock instance: - -1. **`assert_equal` method:** Assert the normal result of the query (running the full query with your input mocks) -2. **`assert_cte_equal` method:** Assert the result of a **CTE** in your query. A lot of times when we built more complicated data models, they include a bunch of CTEs that map to separate logical steps. In those cases, when we unit test our models, we want to be able to not only check the final result but also the single steps. To do this, you can use the `assert_cte_equal` method. - - -Let's assume we have the following query: - -```sql -WITH subscriptions_per_user AS ( - SELECT - count(sub.user_id) AS subscription_count, - users.user_id - FROM data.users AS users - LEFT JOIN data.subscriptions AS sub ON sub.user_id = users.user_id - GROUP BY user_id -), - -users_with_multiple_subs AS ( - SELECT - * - FROM subscriptions_per_user - WHERE subscription_count >= 2 -) - -SELECT user_id FROM users_with_multiple_subs -``` - -... and we define the following mock tables: - -```python -import datetime - -from sql_mock.bigquery import column_mocks as col -from sql_mock.bigquery.table_mocks import BigQueryMockTable -from sql_mock.table_mocks import table_meta - -@table_meta(table_ref="data.users") -class UserTable(BigQueryMockTable): - user_id = col.Int(default=1) - user_name = col.String(default="Mr. T") - - -@table_meta(table_ref="data.subscriptions") -class SubscriptionTable(BigQueryMockTable): - subscription_id = col.Int(default=1) - period_start_date = col.Date(default=datetime.date(2023, 9, 5)) - period_end_date = col.Date(default=datetime.date(2023, 9, 5)) - user_id = col.Int(default=1) - - -@table_meta(query_path="./examples/test_query.sql") -class MultipleSubscriptionUsersTable(BigQueryMockTable): - user_id = col.Int(default=1) -``` - -Now we can use the different testing methods the following way: - -```python -def test_model(): - users = UserTable.from_dicts([{"user_id": 1}, {"user_id": 2}]) - subscriptions = SubscriptionTable.from_dicts( - [ - {"subscription_id": 1, "user_id": 1}, - {"subscription_id": 2, "user_id": 1}, - {"subscription_id": 2, "user_id": 2}, - ] - ) - - subscriptions_per_user__expected = [{"user_id": 1, "subscription_count": 2}, {"user_id": 2, "subscription_count": 1}] - users_with_multiple_subs__expected = [{"user_id": 1, "subscription_count": 2}] - end_result__expected = [{"user_id": 1}] - - res = MultipleSubscriptionUsersTable.from_mocks(input_data=[users, subscriptions]) - - # Check the results of the subscriptions_per_user CTE - res.assert_cte_equal('subscriptions_per_user', subscriptions_per_user__expected) - # Check the results of the users_with_multiple_subs CTE - res.assert_cte_equal('users_with_multiple_subs', users_with_multiple_subs__expected) - # Check the end result - res.assert_equal(end_result__expected) -``` diff --git a/docs/_sources/usage/snowflake/examples.md.txt b/docs/_sources/usage/snowflake/examples.md.txt deleted file mode 100644 index 645621b..0000000 --- a/docs/_sources/usage/snowflake/examples.md.txt +++ /dev/null @@ -1,63 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Example: Testing Subscription Counts in Snowflake - -```python -import datetime -from sql_mock.snowflake import column_mocks as col -from sql_mock.snowflake.table_mocks import SnowflakeMockTable -from sql_mock.table_mocks import table_meta - -# Define mock tables for your data model that inherit from SnowflakeMockTable -@table_meta(table_ref="data.users") -class UserTable(SnowflakeMockTable): - user_id = col.INTEGER(default=1) - user_name = col.STRING(default="Mr. T") - - -@table_meta(table_ref="data.subscriptions") -class SubscriptionTable(SnowflakeMockTable): - subscription_id = col.INTEGER(default=1) - period_start_date = col.DATE(default=datetime.date(2023, 9, 5)) - period_end_date = col.DATE(default=datetime.date(2023, 9, 5)) - user_id = col.INTEGER(default=1) - - -# Define a mock table for your expected results -class SubscriptionCountTable(SnowflakeMockTable): - subscription_count = col.INTEGER(default=1) - user_id = col.INTEGER(default=1) - -# Your original SQL query -query = """ -SELECT - count(*) AS subscription_count, - user_id -FROM data.users -LEFT JOIN data.subscriptions USING(user_id) -GROUP BY user_id -""" - -def test_something(): - # Create mock data for the 'data.users' and 'data.subscriptions' tables - users = UserTable.from_dicts([{'user_id': 1}, {'user_id': 2}]) - subscriptions = SubscriptionTable.from_dicts([ - {'subscription_id': 1, 'user_id': 1}, - {'subscription_id': 2, 'user_id': 1}, - {'subscription_id': 2, 'user_id': 2}, - ]) - - # Define your expected results - expected = [ - {"USER_ID": 1, "SUBSCRIPTION_COUNT": 2}, - {"USER_ID": 2, "SUBSCRIPTION_COUNT": 1}, - ] - - # Simulate the SQL query using SQL Mock - res = SubscriptionCountTable.from_mocks(query=query, input_data=[users, subscriptions]) - - # Assert the results - res.assert_equal(expected) -``` diff --git a/docs/_sources/usage/snowflake/index.rst.txt b/docs/_sources/usage/snowflake/index.rst.txt deleted file mode 100644 index 6c143df..0000000 --- a/docs/_sources/usage/snowflake/index.rst.txt +++ /dev/null @@ -1,10 +0,0 @@ -Snowflake -===================== - -This section documents the specifics on how to use SQL Mock with Snowflake - -.. toctree:: - :maxdepth: 4 - - ./settings.md - ./examples.md diff --git a/docs/_sources/usage/snowflake/settings.md.txt b/docs/_sources/usage/snowflake/settings.md.txt deleted file mode 100644 index 2c9143d..0000000 --- a/docs/_sources/usage/snowflake/settings.md.txt +++ /dev/null @@ -1,13 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Settings - -In order to use SQL Mock with Snowflake, you need to provide the following environment variables when you run tests: - -* `SQL_MOCK_SNOWFLAKE_ACCOUNT`: The name of your Snowflake account -* `SQL_MOCK_SNOWFLAKE_USER`: The name of your Snowflake user -* `SQL_MOCK_SNOWFLAKE_PASSWORD`: The password for your Snowflake user - -Having those environment variables enables SQL Mock to connect to your Snowflake instance. diff --git a/docs/_sources/usage/your_sql_query_to_test.md.txt b/docs/_sources/usage/your_sql_query_to_test.md.txt deleted file mode 100644 index e662f95..0000000 --- a/docs/_sources/usage/your_sql_query_to_test.md.txt +++ /dev/null @@ -1,56 +0,0 @@ -# Your SQL query to test - -There are multiple ways on how you can provide the SQL query that you want to test. Let's walk through them and also cover some specifics. - -## Ways to provide your SQL query to be tested - -### Option 1 (recommended): Use the `table_meta` decorator - -When defining your [Table Mock classes](./defining_table_mocks.md), you can pass a path to your query (`query_path` argument) or the query as string (`query` argument) to the `table_meta` decorator of the table mock you want to test. - -```python -# Pass the query path -@table_meta(table_ref='data.result_table', query_path='path/to/query_for_result_table.sql') -class ResultTable(BigQueryTableMock): - id = col.Int(default=1) - -# Pass the query itself -query = 'SELECT user_id AS id FROM data.users' -@table_meta(table_ref='data.result_table', query=query) -class ResultTable(BigQueryTableMock): - id = col.Int(default=1) -``` - -The advantage of that option is that you only need to define your Table Mock class once (e.g. in a `models.py` file). After that you can reuse it for many tests. - -### Option 2: Pass the query in the `.from_mocks` call - -You can also pass your query in your test case when you call the `from_mocks` method. - -```python -res = ResultTable.from_mocks(query='SELECT 1', input_data=[]) -``` - -Note that this will overwride whatever was specified by using the `table_meta` decorator. - -## Queries with Jinja templates - -Sometimes we need to test queries that use jinja templates (e.g. for dbt). -In those cases, you can provide the necessary context for rendering your query using the `from_mocks` call. - -**Example**: - -Let's assume the following jinja template query: - -```jinja -SELECT * FROM data.users -WHERE created_at > {{ creation_date }} -``` - -We can provide the `creation_date` variable in a dictionary using the `query_template_kwargs` argument: - -```python -res = ResultTable.from_mocks(input_data=[your_input_mock_instances], query_template_kwargs={'creation_date': '2023-09-05'}) -``` - -This will automatically render your query using the given input. diff --git a/docs/_static/_sphinx_javascript_frameworks_compat.js b/docs/_static/_sphinx_javascript_frameworks_compat.js deleted file mode 100644 index 8141580..0000000 --- a/docs/_static/_sphinx_javascript_frameworks_compat.js +++ /dev/null @@ -1,123 +0,0 @@ -/* Compatability shim for jQuery and underscores.js. - * - * Copyright Sphinx contributors - * Released under the two clause BSD licence - */ - -/** - * small helper function to urldecode strings - * - * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL - */ -jQuery.urldecode = function(x) { - if (!x) { - return x - } - return decodeURIComponent(x.replace(/\+/g, ' ')); -}; - -/** - * small helper function to urlencode strings - */ -jQuery.urlencode = encodeURIComponent; - -/** - * This function returns the parsed url parameters of the - * current request. Multiple values per key are supported, - * it will always return arrays of strings for the value parts. - */ -jQuery.getQueryParameters = function(s) { - if (typeof s === 'undefined') - s = document.location.search; - var parts = s.substr(s.indexOf('?') + 1).split('&'); - var result = {}; - for (var i = 0; i < parts.length; i++) { - var tmp = parts[i].split('=', 2); - var key = jQuery.urldecode(tmp[0]); - var value = jQuery.urldecode(tmp[1]); - if (key in result) - result[key].push(value); - else - result[key] = [value]; - } - return result; -}; - -/** - * highlight a given string on a jquery object by wrapping it in - * span elements with the given class name. - */ -jQuery.fn.highlightText = function(text, className) { - function highlight(node, addItems) { - if (node.nodeType === 3) { - var val = node.nodeValue; - var pos = val.toLowerCase().indexOf(text); - if (pos >= 0 && - !jQuery(node.parentNode).hasClass(className) && - !jQuery(node.parentNode).hasClass("nohighlight")) { - var span; - var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); - if (isInSVG) { - span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - } else { - span = document.createElement("span"); - span.className = className; - } - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - node.parentNode.insertBefore(span, node.parentNode.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling)); - node.nodeValue = val.substr(0, pos); - if (isInSVG) { - var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); - var bbox = node.parentElement.getBBox(); - rect.x.baseVal.value = bbox.x; - rect.y.baseVal.value = bbox.y; - rect.width.baseVal.value = bbox.width; - rect.height.baseVal.value = bbox.height; - rect.setAttribute('class', className); - addItems.push({ - "parent": node.parentNode, - "target": rect}); - } - } - } - else if (!jQuery(node).is("button, select, textarea")) { - jQuery.each(node.childNodes, function() { - highlight(this, addItems); - }); - } - } - var addItems = []; - var result = this.each(function() { - highlight(this, addItems); - }); - for (var i = 0; i < addItems.length; ++i) { - jQuery(addItems[i].parent).before(addItems[i].target); - } - return result; -}; - -/* - * backward compatibility for jQuery.browser - * This will be supported until firefox bug is fixed. - */ -if (!jQuery.browser) { - jQuery.uaMatch = function(ua) { - ua = ua.toLowerCase(); - - var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || - /(webkit)[ \/]([\w.]+)/.exec(ua) || - /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || - /(msie) ([\w.]+)/.exec(ua) || - ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || - []; - - return { - browser: match[ 1 ] || "", - version: match[ 2 ] || "0" - }; - }; - jQuery.browser = {}; - jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; -} diff --git a/docs/_static/basic.css b/docs/_static/basic.css deleted file mode 100644 index 30fee9d..0000000 --- a/docs/_static/basic.css +++ /dev/null @@ -1,925 +0,0 @@ -/* - * basic.css - * ~~~~~~~~~ - * - * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -div.section::after { - display: block; - content: ''; - clear: left; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; - word-wrap: break-word; - overflow-wrap : break-word; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox form.search { - overflow: hidden; -} - -div.sphinxsidebar #searchbox input[type="text"] { - float: left; - width: 80%; - padding: 0.25em; - box-sizing: border-box; -} - -div.sphinxsidebar #searchbox input[type="submit"] { - float: left; - width: 20%; - border-left: none; - padding: 0.25em; - box-sizing: border-box; -} - - -img { - border: 0; - max-width: 100%; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li p.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; - margin-left: auto; - margin-right: auto; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable ul { - margin-top: 0; - margin-bottom: 0; - list-style-type: none; -} - -table.indextable > tbody > tr > td > ul { - padding-left: 0em; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- domain module index --------------------------------------------------- */ - -table.modindextable td { - padding: 2px; - border-collapse: collapse; -} - -/* -- general body styles --------------------------------------------------- */ - -div.body { - min-width: 360px; - max-width: 800px; -} - -div.body p, div.body dd, div.body li, div.body blockquote { - -moz-hyphens: auto; - -ms-hyphens: auto; - -webkit-hyphens: auto; - hyphens: auto; -} - -a.headerlink { - visibility: hidden; -} - -a:visited { - color: #551A8B; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink, -caption:hover > a.headerlink, -p.caption:hover > a.headerlink, -div.code-block-caption:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -img.align-left, figure.align-left, .figure.align-left, object.align-left { - clear: left; - float: left; - margin-right: 1em; -} - -img.align-right, figure.align-right, .figure.align-right, object.align-right { - clear: right; - float: right; - margin-left: 1em; -} - -img.align-center, figure.align-center, .figure.align-center, object.align-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -img.align-default, figure.align-default, .figure.align-default { - display: block; - margin-left: auto; - margin-right: auto; -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-default { - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar, -aside.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px; - background-color: #ffe; - width: 40%; - float: right; - clear: right; - overflow-x: auto; -} - -p.sidebar-title { - font-weight: bold; -} - -nav.contents, -aside.topic, -div.admonition, div.topic, blockquote { - clear: left; -} - -/* -- topics ---------------------------------------------------------------- */ - -nav.contents, -aside.topic, -div.topic { - border: 1px solid #ccc; - padding: 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- content of sidebars/topics/admonitions -------------------------------- */ - -div.sidebar > :last-child, -aside.sidebar > :last-child, -nav.contents > :last-child, -aside.topic > :last-child, -div.topic > :last-child, -div.admonition > :last-child { - margin-bottom: 0; -} - -div.sidebar::after, -aside.sidebar::after, -nav.contents::after, -aside.topic::after, -div.topic::after, -div.admonition::after, -blockquote::after { - display: block; - content: ''; - clear: both; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - margin-top: 10px; - margin-bottom: 10px; - border: 0; - border-collapse: collapse; -} - -table.align-center { - margin-left: auto; - margin-right: auto; -} - -table.align-default { - margin-left: auto; - margin-right: auto; -} - -table caption span.caption-number { - font-style: italic; -} - -table caption span.caption-text { -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -th { - text-align: left; - padding-right: 5px; -} - -table.citation { - border-left: solid 1px gray; - margin-left: 1px; -} - -table.citation td { - border-bottom: none; -} - -th > :first-child, -td > :first-child { - margin-top: 0px; -} - -th > :last-child, -td > :last-child { - margin-bottom: 0px; -} - -/* -- figures --------------------------------------------------------------- */ - -div.figure, figure { - margin: 0.5em; - padding: 0.5em; -} - -div.figure p.caption, figcaption { - padding: 0.3em; -} - -div.figure p.caption span.caption-number, -figcaption span.caption-number { - font-style: italic; -} - -div.figure p.caption span.caption-text, -figcaption span.caption-text { -} - -/* -- field list styles ----------------------------------------------------- */ - -table.field-list td, table.field-list th { - border: 0 !important; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.field-name { - -moz-hyphens: manual; - -ms-hyphens: manual; - -webkit-hyphens: manual; - hyphens: manual; -} - -/* -- hlist styles ---------------------------------------------------------- */ - -table.hlist { - margin: 1em 0; -} - -table.hlist td { - vertical-align: top; -} - -/* -- object description styles --------------------------------------------- */ - -.sig { - font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; -} - -.sig-name, code.descname { - background-color: transparent; - font-weight: bold; -} - -.sig-name { - font-size: 1.1em; -} - -code.descname { - font-size: 1.2em; -} - -.sig-prename, code.descclassname { - background-color: transparent; -} - -.optional { - font-size: 1.3em; -} - -.sig-paren { - font-size: larger; -} - -.sig-param.n { - font-style: italic; -} - -/* C++ specific styling */ - -.sig-inline.c-texpr, -.sig-inline.cpp-texpr { - font-family: unset; -} - -.sig.c .k, .sig.c .kt, -.sig.cpp .k, .sig.cpp .kt { - color: #0033B3; -} - -.sig.c .m, -.sig.cpp .m { - color: #1750EB; -} - -.sig.c .s, .sig.c .sc, -.sig.cpp .s, .sig.cpp .sc { - color: #067D17; -} - - -/* -- other body styles ----------------------------------------------------- */ - -ol.arabic { - list-style: decimal; -} - -ol.loweralpha { - list-style: lower-alpha; -} - -ol.upperalpha { - list-style: upper-alpha; -} - -ol.lowerroman { - list-style: lower-roman; -} - -ol.upperroman { - list-style: upper-roman; -} - -:not(li) > ol > li:first-child > :first-child, -:not(li) > ul > li:first-child > :first-child { - margin-top: 0px; -} - -:not(li) > ol > li:last-child > :last-child, -:not(li) > ul > li:last-child > :last-child { - margin-bottom: 0px; -} - -ol.simple ol p, -ol.simple ul p, -ul.simple ol p, -ul.simple ul p { - margin-top: 0; -} - -ol.simple > li:not(:first-child) > p, -ul.simple > li:not(:first-child) > p { - margin-top: 0; -} - -ol.simple p, -ul.simple p { - margin-bottom: 0; -} - -aside.footnote > span, -div.citation > span { - float: left; -} -aside.footnote > span:last-of-type, -div.citation > span:last-of-type { - padding-right: 0.5em; -} -aside.footnote > p { - margin-left: 2em; -} -div.citation > p { - margin-left: 4em; -} -aside.footnote > p:last-of-type, -div.citation > p:last-of-type { - margin-bottom: 0em; -} -aside.footnote > p:last-of-type:after, -div.citation > p:last-of-type:after { - content: ""; - clear: both; -} - -dl.field-list { - display: grid; - grid-template-columns: fit-content(30%) auto; -} - -dl.field-list > dt { - font-weight: bold; - word-break: break-word; - padding-left: 0.5em; - padding-right: 5px; -} - -dl.field-list > dd { - padding-left: 0.5em; - margin-top: 0em; - margin-left: 0em; - margin-bottom: 0em; -} - -dl { - margin-bottom: 15px; -} - -dd > :first-child { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -.sig dd { - margin-top: 0px; - margin-bottom: 0px; -} - -.sig dl { - margin-top: 0px; - margin-bottom: 0px; -} - -dl > dd:last-child, -dl > dd:last-child > :last-child { - margin-bottom: 0; -} - -dt:target, span.highlighted { - background-color: #fbe54e; -} - -rect.highlighted { - fill: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.versionmodified { - font-style: italic; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} - -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} - -.guilabel, .menuselection { - font-family: sans-serif; -} - -.accelerator { - text-decoration: underline; -} - -.classifier { - font-style: oblique; -} - -.classifier:before { - font-style: normal; - margin: 0 0.5em; - content: ":"; - display: inline-block; -} - -abbr, acronym { - border-bottom: dotted 1px; - cursor: help; -} - -.translated { - background-color: rgba(207, 255, 207, 0.2) -} - -.untranslated { - background-color: rgba(255, 207, 207, 0.2) -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; /* fixes display issues on Chrome browsers */ -} - -pre, div[class*="highlight-"] { - clear: both; -} - -span.pre { - -moz-hyphens: none; - -ms-hyphens: none; - -webkit-hyphens: none; - hyphens: none; - white-space: nowrap; -} - -div[class*="highlight-"] { - margin: 1em 0; -} - -td.linenos pre { - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - display: block; -} - -table.highlighttable tbody { - display: block; -} - -table.highlighttable tr { - display: flex; -} - -table.highlighttable td { - margin: 0; - padding: 0; -} - -table.highlighttable td.linenos { - padding-right: 0.5em; -} - -table.highlighttable td.code { - flex: 1; - overflow: hidden; -} - -.highlight .hll { - display: block; -} - -div.highlight pre, -table.highlighttable pre { - margin: 0; -} - -div.code-block-caption + div { - margin-top: 0; -} - -div.code-block-caption { - margin-top: 1em; - padding: 2px 5px; - font-size: small; -} - -div.code-block-caption code { - background-color: transparent; -} - -table.highlighttable td.linenos, -span.linenos, -div.highlight span.gp { /* gp: Generic.Prompt */ - user-select: none; - -webkit-user-select: text; /* Safari fallback only */ - -webkit-user-select: none; /* Chrome/Safari */ - -moz-user-select: none; /* Firefox */ - -ms-user-select: none; /* IE10+ */ -} - -div.code-block-caption span.caption-number { - padding: 0.1em 0.3em; - font-style: italic; -} - -div.code-block-caption span.caption-text { -} - -div.literal-block-wrapper { - margin: 1em 0; -} - -code.xref, a code { - background-color: transparent; - font-weight: bold; -} - -h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -span.eqno a.headerlink { - position: absolute; - z-index: 1; -} - -div.math:hover a.headerlink { - visibility: visible; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} \ No newline at end of file diff --git a/docs/_static/css/badge_only.css b/docs/_static/css/badge_only.css deleted file mode 100644 index c718cee..0000000 --- a/docs/_static/css/badge_only.css +++ /dev/null @@ -1 +0,0 @@ -.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/docs/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/_static/css/fonts/Roboto-Slab-Bold.woff deleted file mode 100644 index 6cb6000..0000000 Binary files a/docs/_static/css/fonts/Roboto-Slab-Bold.woff and /dev/null differ diff --git a/docs/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/_static/css/fonts/Roboto-Slab-Bold.woff2 deleted file mode 100644 index 7059e23..0000000 Binary files a/docs/_static/css/fonts/Roboto-Slab-Bold.woff2 and /dev/null differ diff --git a/docs/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/_static/css/fonts/Roboto-Slab-Regular.woff deleted file mode 100644 index f815f63..0000000 Binary files a/docs/_static/css/fonts/Roboto-Slab-Regular.woff and /dev/null differ diff --git a/docs/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/_static/css/fonts/Roboto-Slab-Regular.woff2 deleted file mode 100644 index f2c76e5..0000000 Binary files a/docs/_static/css/fonts/Roboto-Slab-Regular.woff2 and /dev/null differ diff --git a/docs/_static/css/fonts/fontawesome-webfont.eot b/docs/_static/css/fonts/fontawesome-webfont.eot deleted file mode 100644 index e9f60ca..0000000 Binary files a/docs/_static/css/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/docs/_static/css/fonts/fontawesome-webfont.svg b/docs/_static/css/fonts/fontawesome-webfont.svg deleted file mode 100644 index 855c845..0000000 --- a/docs/_static/css/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,2671 +0,0 @@ - - - - -Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 - By ,,, -Copyright Dave Gandy 2016. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/_static/css/fonts/fontawesome-webfont.ttf b/docs/_static/css/fonts/fontawesome-webfont.ttf deleted file mode 100644 index 35acda2..0000000 Binary files a/docs/_static/css/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/docs/_static/css/fonts/fontawesome-webfont.woff b/docs/_static/css/fonts/fontawesome-webfont.woff deleted file mode 100644 index 400014a..0000000 Binary files a/docs/_static/css/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/docs/_static/css/fonts/fontawesome-webfont.woff2 b/docs/_static/css/fonts/fontawesome-webfont.woff2 deleted file mode 100644 index 4d13fc6..0000000 Binary files a/docs/_static/css/fonts/fontawesome-webfont.woff2 and /dev/null differ diff --git a/docs/_static/css/fonts/lato-bold-italic.woff b/docs/_static/css/fonts/lato-bold-italic.woff deleted file mode 100644 index 88ad05b..0000000 Binary files a/docs/_static/css/fonts/lato-bold-italic.woff and /dev/null differ diff --git a/docs/_static/css/fonts/lato-bold-italic.woff2 b/docs/_static/css/fonts/lato-bold-italic.woff2 deleted file mode 100644 index c4e3d80..0000000 Binary files a/docs/_static/css/fonts/lato-bold-italic.woff2 and /dev/null differ diff --git a/docs/_static/css/fonts/lato-bold.woff b/docs/_static/css/fonts/lato-bold.woff deleted file mode 100644 index c6dff51..0000000 Binary files a/docs/_static/css/fonts/lato-bold.woff and /dev/null differ diff --git a/docs/_static/css/fonts/lato-bold.woff2 b/docs/_static/css/fonts/lato-bold.woff2 deleted file mode 100644 index bb19504..0000000 Binary files a/docs/_static/css/fonts/lato-bold.woff2 and /dev/null differ diff --git a/docs/_static/css/fonts/lato-normal-italic.woff b/docs/_static/css/fonts/lato-normal-italic.woff deleted file mode 100644 index 76114bc..0000000 Binary files a/docs/_static/css/fonts/lato-normal-italic.woff and /dev/null differ diff --git a/docs/_static/css/fonts/lato-normal-italic.woff2 b/docs/_static/css/fonts/lato-normal-italic.woff2 deleted file mode 100644 index 3404f37..0000000 Binary files a/docs/_static/css/fonts/lato-normal-italic.woff2 and /dev/null differ diff --git a/docs/_static/css/fonts/lato-normal.woff b/docs/_static/css/fonts/lato-normal.woff deleted file mode 100644 index ae1307f..0000000 Binary files a/docs/_static/css/fonts/lato-normal.woff and /dev/null differ diff --git a/docs/_static/css/fonts/lato-normal.woff2 b/docs/_static/css/fonts/lato-normal.woff2 deleted file mode 100644 index 3bf9843..0000000 Binary files a/docs/_static/css/fonts/lato-normal.woff2 and /dev/null differ diff --git a/docs/_static/css/theme.css b/docs/_static/css/theme.css deleted file mode 100644 index 19a446a..0000000 --- a/docs/_static/css/theme.css +++ /dev/null @@ -1,4 +0,0 @@ -html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/docs/_static/doctools.js b/docs/_static/doctools.js deleted file mode 100644 index d06a71d..0000000 --- a/docs/_static/doctools.js +++ /dev/null @@ -1,156 +0,0 @@ -/* - * doctools.js - * ~~~~~~~~~~~ - * - * Base JavaScript utilities for all Sphinx HTML documentation. - * - * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ -"use strict"; - -const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ - "TEXTAREA", - "INPUT", - "SELECT", - "BUTTON", -]); - -const _ready = (callback) => { - if (document.readyState !== "loading") { - callback(); - } else { - document.addEventListener("DOMContentLoaded", callback); - } -}; - -/** - * Small JavaScript module for the documentation. - */ -const Documentation = { - init: () => { - Documentation.initDomainIndexTable(); - Documentation.initOnKeyListeners(); - }, - - /** - * i18n support - */ - TRANSLATIONS: {}, - PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), - LOCALE: "unknown", - - // gettext and ngettext don't access this so that the functions - // can safely bound to a different name (_ = Documentation.gettext) - gettext: (string) => { - const translated = Documentation.TRANSLATIONS[string]; - switch (typeof translated) { - case "undefined": - return string; // no translation - case "string": - return translated; // translation exists - default: - return translated[0]; // (singular, plural) translation tuple exists - } - }, - - ngettext: (singular, plural, n) => { - const translated = Documentation.TRANSLATIONS[singular]; - if (typeof translated !== "undefined") - return translated[Documentation.PLURAL_EXPR(n)]; - return n === 1 ? singular : plural; - }, - - addTranslations: (catalog) => { - Object.assign(Documentation.TRANSLATIONS, catalog.messages); - Documentation.PLURAL_EXPR = new Function( - "n", - `return (${catalog.plural_expr})` - ); - Documentation.LOCALE = catalog.locale; - }, - - /** - * helper function to focus on search bar - */ - focusSearchBar: () => { - document.querySelectorAll("input[name=q]")[0]?.focus(); - }, - - /** - * Initialise the domain index toggle buttons - */ - initDomainIndexTable: () => { - const toggler = (el) => { - const idNumber = el.id.substr(7); - const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); - if (el.src.substr(-9) === "minus.png") { - el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; - toggledRows.forEach((el) => (el.style.display = "none")); - } else { - el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; - toggledRows.forEach((el) => (el.style.display = "")); - } - }; - - const togglerElements = document.querySelectorAll("img.toggler"); - togglerElements.forEach((el) => - el.addEventListener("click", (event) => toggler(event.currentTarget)) - ); - togglerElements.forEach((el) => (el.style.display = "")); - if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); - }, - - initOnKeyListeners: () => { - // only install a listener if it is really needed - if ( - !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && - !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS - ) - return; - - document.addEventListener("keydown", (event) => { - // bail for input elements - if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; - // bail with special keys - if (event.altKey || event.ctrlKey || event.metaKey) return; - - if (!event.shiftKey) { - switch (event.key) { - case "ArrowLeft": - if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; - - const prevLink = document.querySelector('link[rel="prev"]'); - if (prevLink && prevLink.href) { - window.location.href = prevLink.href; - event.preventDefault(); - } - break; - case "ArrowRight": - if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; - - const nextLink = document.querySelector('link[rel="next"]'); - if (nextLink && nextLink.href) { - window.location.href = nextLink.href; - event.preventDefault(); - } - break; - } - } - - // some keyboard layouts may need Shift to get / - switch (event.key) { - case "/": - if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; - Documentation.focusSearchBar(); - event.preventDefault(); - } - }); - }, -}; - -// quick alias for translations -const _ = Documentation.gettext; - -_ready(Documentation.init); diff --git a/docs/_static/documentation_options.js b/docs/_static/documentation_options.js deleted file mode 100644 index 7254ddd..0000000 --- a/docs/_static/documentation_options.js +++ /dev/null @@ -1,13 +0,0 @@ -const DOCUMENTATION_OPTIONS = { - VERSION: '0.3.0', - LANGUAGE: 'en', - COLLAPSE_INDEX: false, - BUILDER: 'html', - FILE_SUFFIX: '.html', - LINK_SUFFIX: '.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt', - NAVIGATION_WITH_KEYS: false, - SHOW_SEARCH_SUMMARY: true, - ENABLE_SEARCH_SHORTCUTS: true, -}; \ No newline at end of file diff --git a/docs/_static/file.png b/docs/_static/file.png deleted file mode 100644 index a858a41..0000000 Binary files a/docs/_static/file.png and /dev/null differ diff --git a/docs/_static/jquery.js b/docs/_static/jquery.js deleted file mode 100644 index c4c6022..0000000 --- a/docs/_static/jquery.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"
","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/docs/_static/js/html5shiv.min.js b/docs/_static/js/html5shiv.min.js deleted file mode 100644 index cd1c674..0000000 --- a/docs/_static/js/html5shiv.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/** -* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed -*/ -!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/docs/_static/js/theme.js b/docs/_static/js/theme.js deleted file mode 100644 index 1fddb6e..0000000 --- a/docs/_static/js/theme.js +++ /dev/null @@ -1 +0,0 @@ -!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 - var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 - var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 - var s_v = "^(" + C + ")?" + v; // vowel in stem - - this.stemWord = function (w) { - var stem; - var suffix; - var firstch; - var origword = w; - - if (w.length < 3) - return w; - - var re; - var re2; - var re3; - var re4; - - firstch = w.substr(0,1); - if (firstch == "y") - w = firstch.toUpperCase() + w.substr(1); - - // Step 1a - re = /^(.+?)(ss|i)es$/; - re2 = /^(.+?)([^s])s$/; - - if (re.test(w)) - w = w.replace(re,"$1$2"); - else if (re2.test(w)) - w = w.replace(re2,"$1$2"); - - // Step 1b - re = /^(.+?)eed$/; - re2 = /^(.+?)(ed|ing)$/; - if (re.test(w)) { - var fp = re.exec(w); - re = new RegExp(mgr0); - if (re.test(fp[1])) { - re = /.$/; - w = w.replace(re,""); - } - } - else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1]; - re2 = new RegExp(s_v); - if (re2.test(stem)) { - w = stem; - re2 = /(at|bl|iz)$/; - re3 = new RegExp("([^aeiouylsz])\\1$"); - re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - if (re2.test(w)) - w = w + "e"; - else if (re3.test(w)) { - re = /.$/; - w = w.replace(re,""); - } - else if (re4.test(w)) - w = w + "e"; - } - } - - // Step 1c - re = /^(.+?)y$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(s_v); - if (re.test(stem)) - w = stem + "i"; - } - - // Step 2 - re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = new RegExp(mgr0); - if (re.test(stem)) - w = stem + step2list[suffix]; - } - - // Step 3 - re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = new RegExp(mgr0); - if (re.test(stem)) - w = stem + step3list[suffix]; - } - - // Step 4 - re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; - re2 = /^(.+?)(s|t)(ion)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(mgr1); - if (re.test(stem)) - w = stem; - } - else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1] + fp[2]; - re2 = new RegExp(mgr1); - if (re2.test(stem)) - w = stem; - } - - // Step 5 - re = /^(.+?)e$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(mgr1); - re2 = new RegExp(meq1); - re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) - w = stem; - } - re = /ll$/; - re2 = new RegExp(mgr1); - if (re.test(w) && re2.test(w)) { - re = /.$/; - w = w.replace(re,""); - } - - // and turn initial Y back to y - if (firstch == "y") - w = firstch.toLowerCase() + w.substr(1); - return w; - } -} - diff --git a/docs/_static/minus.png b/docs/_static/minus.png deleted file mode 100644 index d96755f..0000000 Binary files a/docs/_static/minus.png and /dev/null differ diff --git a/docs/_static/plus.png b/docs/_static/plus.png deleted file mode 100644 index 7107cec..0000000 Binary files a/docs/_static/plus.png and /dev/null differ diff --git a/docs/_static/pygments.css b/docs/_static/pygments.css deleted file mode 100644 index 84ab303..0000000 --- a/docs/_static/pygments.css +++ /dev/null @@ -1,75 +0,0 @@ -pre { line-height: 125%; } -td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } -span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } -td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } -span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } -.highlight .hll { background-color: #ffffcc } -.highlight { background: #f8f8f8; } -.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ -.highlight .err { border: 1px solid #FF0000 } /* Error */ -.highlight .k { color: #008000; font-weight: bold } /* Keyword */ -.highlight .o { color: #666666 } /* Operator */ -.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ -.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #9C6500 } /* Comment.Preproc */ -.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ -.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ -.highlight .gd { color: #A00000 } /* Generic.Deleted */ -.highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ -.highlight .gr { color: #E40000 } /* Generic.Error */ -.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -.highlight .gi { color: #008400 } /* Generic.Inserted */ -.highlight .go { color: #717171 } /* Generic.Output */ -.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ -.highlight .gs { font-weight: bold } /* Generic.Strong */ -.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.highlight .gt { color: #0044DD } /* Generic.Traceback */ -.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ -.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ -.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ -.highlight .kp { color: #008000 } /* Keyword.Pseudo */ -.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ -.highlight .kt { color: #B00040 } /* Keyword.Type */ -.highlight .m { color: #666666 } /* Literal.Number */ -.highlight .s { color: #BA2121 } /* Literal.String */ -.highlight .na { color: #687822 } /* Name.Attribute */ -.highlight .nb { color: #008000 } /* Name.Builtin */ -.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ -.highlight .no { color: #880000 } /* Name.Constant */ -.highlight .nd { color: #AA22FF } /* Name.Decorator */ -.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ -.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ -.highlight .nf { color: #0000FF } /* Name.Function */ -.highlight .nl { color: #767600 } /* Name.Label */ -.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ -.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ -.highlight .nv { color: #19177C } /* Name.Variable */ -.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ -.highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mb { color: #666666 } /* Literal.Number.Bin */ -.highlight .mf { color: #666666 } /* Literal.Number.Float */ -.highlight .mh { color: #666666 } /* Literal.Number.Hex */ -.highlight .mi { color: #666666 } /* Literal.Number.Integer */ -.highlight .mo { color: #666666 } /* Literal.Number.Oct */ -.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ -.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ -.highlight .sc { color: #BA2121 } /* Literal.String.Char */ -.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ -.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ -.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ -.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ -.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ -.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ -.highlight .sx { color: #008000 } /* Literal.String.Other */ -.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ -.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ -.highlight .ss { color: #19177C } /* Literal.String.Symbol */ -.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ -.highlight .fm { color: #0000FF } /* Name.Function.Magic */ -.highlight .vc { color: #19177C } /* Name.Variable.Class */ -.highlight .vg { color: #19177C } /* Name.Variable.Global */ -.highlight .vi { color: #19177C } /* Name.Variable.Instance */ -.highlight .vm { color: #19177C } /* Name.Variable.Magic */ -.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/_static/searchtools.js b/docs/_static/searchtools.js deleted file mode 100644 index 7918c3f..0000000 --- a/docs/_static/searchtools.js +++ /dev/null @@ -1,574 +0,0 @@ -/* - * searchtools.js - * ~~~~~~~~~~~~~~~~ - * - * Sphinx JavaScript utilities for the full-text search. - * - * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ -"use strict"; - -/** - * Simple result scoring code. - */ -if (typeof Scorer === "undefined") { - var Scorer = { - // Implement the following function to further tweak the score for each result - // The function takes a result array [docname, title, anchor, descr, score, filename] - // and returns the new score. - /* - score: result => { - const [docname, title, anchor, descr, score, filename] = result - return score - }, - */ - - // query matches the full name of an object - objNameMatch: 11, - // or matches in the last dotted part of the object name - objPartialMatch: 6, - // Additive scores depending on the priority of the object - objPrio: { - 0: 15, // used to be importantResults - 1: 5, // used to be objectResults - 2: -5, // used to be unimportantResults - }, - // Used when the priority is not in the mapping. - objPrioDefault: 0, - - // query found in title - title: 15, - partialTitle: 7, - // query found in terms - term: 5, - partialTerm: 2, - }; -} - -const _removeChildren = (element) => { - while (element && element.lastChild) element.removeChild(element.lastChild); -}; - -/** - * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping - */ -const _escapeRegExp = (string) => - string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string - -const _displayItem = (item, searchTerms, highlightTerms) => { - const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; - const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; - const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; - const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; - const contentRoot = document.documentElement.dataset.content_root; - - const [docName, title, anchor, descr, score, _filename] = item; - - let listItem = document.createElement("li"); - let requestUrl; - let linkUrl; - if (docBuilder === "dirhtml") { - // dirhtml builder - let dirname = docName + "/"; - if (dirname.match(/\/index\/$/)) - dirname = dirname.substring(0, dirname.length - 6); - else if (dirname === "index/") dirname = ""; - requestUrl = contentRoot + dirname; - linkUrl = requestUrl; - } else { - // normal html builders - requestUrl = contentRoot + docName + docFileSuffix; - linkUrl = docName + docLinkSuffix; - } - let linkEl = listItem.appendChild(document.createElement("a")); - linkEl.href = linkUrl + anchor; - linkEl.dataset.score = score; - linkEl.innerHTML = title; - if (descr) { - listItem.appendChild(document.createElement("span")).innerHTML = - " (" + descr + ")"; - // highlight search terms in the description - if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js - highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); - } - else if (showSearchSummary) - fetch(requestUrl) - .then((responseData) => responseData.text()) - .then((data) => { - if (data) - listItem.appendChild( - Search.makeSearchSummary(data, searchTerms) - ); - // highlight search terms in the summary - if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js - highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); - }); - Search.output.appendChild(listItem); -}; -const _finishSearch = (resultCount) => { - Search.stopPulse(); - Search.title.innerText = _("Search Results"); - if (!resultCount) - Search.status.innerText = Documentation.gettext( - "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." - ); - else - Search.status.innerText = _( - `Search finished, found ${resultCount} page(s) matching the search query.` - ); -}; -const _displayNextItem = ( - results, - resultCount, - searchTerms, - highlightTerms, -) => { - // results left, load the summary and display it - // this is intended to be dynamic (don't sub resultsCount) - if (results.length) { - _displayItem(results.pop(), searchTerms, highlightTerms); - setTimeout( - () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), - 5 - ); - } - // search finished, update title and status message - else _finishSearch(resultCount); -}; - -/** - * Default splitQuery function. Can be overridden in ``sphinx.search`` with a - * custom function per language. - * - * The regular expression works by splitting the string on consecutive characters - * that are not Unicode letters, numbers, underscores, or emoji characters. - * This is the same as ``\W+`` in Python, preserving the surrogate pair area. - */ -if (typeof splitQuery === "undefined") { - var splitQuery = (query) => query - .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) - .filter(term => term) // remove remaining empty strings -} - -/** - * Search Module - */ -const Search = { - _index: null, - _queued_query: null, - _pulse_status: -1, - - htmlToText: (htmlString) => { - const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); - htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); - const docContent = htmlElement.querySelector('[role="main"]'); - if (docContent !== undefined) return docContent.textContent; - console.warn( - "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." - ); - return ""; - }, - - init: () => { - const query = new URLSearchParams(window.location.search).get("q"); - document - .querySelectorAll('input[name="q"]') - .forEach((el) => (el.value = query)); - if (query) Search.performSearch(query); - }, - - loadIndex: (url) => - (document.body.appendChild(document.createElement("script")).src = url), - - setIndex: (index) => { - Search._index = index; - if (Search._queued_query !== null) { - const query = Search._queued_query; - Search._queued_query = null; - Search.query(query); - } - }, - - hasIndex: () => Search._index !== null, - - deferQuery: (query) => (Search._queued_query = query), - - stopPulse: () => (Search._pulse_status = -1), - - startPulse: () => { - if (Search._pulse_status >= 0) return; - - const pulse = () => { - Search._pulse_status = (Search._pulse_status + 1) % 4; - Search.dots.innerText = ".".repeat(Search._pulse_status); - if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); - }; - pulse(); - }, - - /** - * perform a search for something (or wait until index is loaded) - */ - performSearch: (query) => { - // create the required interface elements - const searchText = document.createElement("h2"); - searchText.textContent = _("Searching"); - const searchSummary = document.createElement("p"); - searchSummary.classList.add("search-summary"); - searchSummary.innerText = ""; - const searchList = document.createElement("ul"); - searchList.classList.add("search"); - - const out = document.getElementById("search-results"); - Search.title = out.appendChild(searchText); - Search.dots = Search.title.appendChild(document.createElement("span")); - Search.status = out.appendChild(searchSummary); - Search.output = out.appendChild(searchList); - - const searchProgress = document.getElementById("search-progress"); - // Some themes don't use the search progress node - if (searchProgress) { - searchProgress.innerText = _("Preparing search..."); - } - Search.startPulse(); - - // index already loaded, the browser was quick! - if (Search.hasIndex()) Search.query(query); - else Search.deferQuery(query); - }, - - /** - * execute search (requires search index to be loaded) - */ - query: (query) => { - const filenames = Search._index.filenames; - const docNames = Search._index.docnames; - const titles = Search._index.titles; - const allTitles = Search._index.alltitles; - const indexEntries = Search._index.indexentries; - - // stem the search terms and add them to the correct list - const stemmer = new Stemmer(); - const searchTerms = new Set(); - const excludedTerms = new Set(); - const highlightTerms = new Set(); - const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); - splitQuery(query.trim()).forEach((queryTerm) => { - const queryTermLower = queryTerm.toLowerCase(); - - // maybe skip this "word" - // stopwords array is from language_data.js - if ( - stopwords.indexOf(queryTermLower) !== -1 || - queryTerm.match(/^\d+$/) - ) - return; - - // stem the word - let word = stemmer.stemWord(queryTermLower); - // select the correct list - if (word[0] === "-") excludedTerms.add(word.substr(1)); - else { - searchTerms.add(word); - highlightTerms.add(queryTermLower); - } - }); - - if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js - localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) - } - - // console.debug("SEARCH: searching for:"); - // console.info("required: ", [...searchTerms]); - // console.info("excluded: ", [...excludedTerms]); - - // array of [docname, title, anchor, descr, score, filename] - let results = []; - _removeChildren(document.getElementById("search-progress")); - - const queryLower = query.toLowerCase(); - for (const [title, foundTitles] of Object.entries(allTitles)) { - if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { - for (const [file, id] of foundTitles) { - let score = Math.round(100 * queryLower.length / title.length) - results.push([ - docNames[file], - titles[file] !== title ? `${titles[file]} > ${title}` : title, - id !== null ? "#" + id : "", - null, - score, - filenames[file], - ]); - } - } - } - - // search for explicit entries in index directives - for (const [entry, foundEntries] of Object.entries(indexEntries)) { - if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { - for (const [file, id] of foundEntries) { - let score = Math.round(100 * queryLower.length / entry.length) - results.push([ - docNames[file], - titles[file], - id ? "#" + id : "", - null, - score, - filenames[file], - ]); - } - } - } - - // lookup as object - objectTerms.forEach((term) => - results.push(...Search.performObjectSearch(term, objectTerms)) - ); - - // lookup as search terms in fulltext - results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); - - // let the scorer override scores with a custom scoring function - if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); - - // now sort the results by score (in opposite order of appearance, since the - // display function below uses pop() to retrieve items) and then - // alphabetically - results.sort((a, b) => { - const leftScore = a[4]; - const rightScore = b[4]; - if (leftScore === rightScore) { - // same score: sort alphabetically - const leftTitle = a[1].toLowerCase(); - const rightTitle = b[1].toLowerCase(); - if (leftTitle === rightTitle) return 0; - return leftTitle > rightTitle ? -1 : 1; // inverted is intentional - } - return leftScore > rightScore ? 1 : -1; - }); - - // remove duplicate search results - // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept - let seen = new Set(); - results = results.reverse().reduce((acc, result) => { - let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); - if (!seen.has(resultStr)) { - acc.push(result); - seen.add(resultStr); - } - return acc; - }, []); - - results = results.reverse(); - - // for debugging - //Search.lastresults = results.slice(); // a copy - // console.info("search results:", Search.lastresults); - - // print the results - _displayNextItem(results, results.length, searchTerms, highlightTerms); - }, - - /** - * search for object names - */ - performObjectSearch: (object, objectTerms) => { - const filenames = Search._index.filenames; - const docNames = Search._index.docnames; - const objects = Search._index.objects; - const objNames = Search._index.objnames; - const titles = Search._index.titles; - - const results = []; - - const objectSearchCallback = (prefix, match) => { - const name = match[4] - const fullname = (prefix ? prefix + "." : "") + name; - const fullnameLower = fullname.toLowerCase(); - if (fullnameLower.indexOf(object) < 0) return; - - let score = 0; - const parts = fullnameLower.split("."); - - // check for different match types: exact matches of full name or - // "last name" (i.e. last dotted part) - if (fullnameLower === object || parts.slice(-1)[0] === object) - score += Scorer.objNameMatch; - else if (parts.slice(-1)[0].indexOf(object) > -1) - score += Scorer.objPartialMatch; // matches in last name - - const objName = objNames[match[1]][2]; - const title = titles[match[0]]; - - // If more than one term searched for, we require other words to be - // found in the name/title/description - const otherTerms = new Set(objectTerms); - otherTerms.delete(object); - if (otherTerms.size > 0) { - const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); - if ( - [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) - ) - return; - } - - let anchor = match[3]; - if (anchor === "") anchor = fullname; - else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; - - const descr = objName + _(", in ") + title; - - // add custom score for some objects according to scorer - if (Scorer.objPrio.hasOwnProperty(match[2])) - score += Scorer.objPrio[match[2]]; - else score += Scorer.objPrioDefault; - - results.push([ - docNames[match[0]], - fullname, - "#" + anchor, - descr, - score, - filenames[match[0]], - ]); - }; - Object.keys(objects).forEach((prefix) => - objects[prefix].forEach((array) => - objectSearchCallback(prefix, array) - ) - ); - return results; - }, - - /** - * search for full-text terms in the index - */ - performTermsSearch: (searchTerms, excludedTerms) => { - // prepare search - const terms = Search._index.terms; - const titleTerms = Search._index.titleterms; - const filenames = Search._index.filenames; - const docNames = Search._index.docnames; - const titles = Search._index.titles; - - const scoreMap = new Map(); - const fileMap = new Map(); - - // perform the search on the required terms - searchTerms.forEach((word) => { - const files = []; - const arr = [ - { files: terms[word], score: Scorer.term }, - { files: titleTerms[word], score: Scorer.title }, - ]; - // add support for partial matches - if (word.length > 2) { - const escapedWord = _escapeRegExp(word); - Object.keys(terms).forEach((term) => { - if (term.match(escapedWord) && !terms[word]) - arr.push({ files: terms[term], score: Scorer.partialTerm }); - }); - Object.keys(titleTerms).forEach((term) => { - if (term.match(escapedWord) && !titleTerms[word]) - arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); - }); - } - - // no match but word was a required one - if (arr.every((record) => record.files === undefined)) return; - - // found search word in contents - arr.forEach((record) => { - if (record.files === undefined) return; - - let recordFiles = record.files; - if (recordFiles.length === undefined) recordFiles = [recordFiles]; - files.push(...recordFiles); - - // set score for the word in each file - recordFiles.forEach((file) => { - if (!scoreMap.has(file)) scoreMap.set(file, {}); - scoreMap.get(file)[word] = record.score; - }); - }); - - // create the mapping - files.forEach((file) => { - if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) - fileMap.get(file).push(word); - else fileMap.set(file, [word]); - }); - }); - - // now check if the files don't contain excluded terms - const results = []; - for (const [file, wordList] of fileMap) { - // check if all requirements are matched - - // as search terms with length < 3 are discarded - const filteredTermCount = [...searchTerms].filter( - (term) => term.length > 2 - ).length; - if ( - wordList.length !== searchTerms.size && - wordList.length !== filteredTermCount - ) - continue; - - // ensure that none of the excluded terms is in the search result - if ( - [...excludedTerms].some( - (term) => - terms[term] === file || - titleTerms[term] === file || - (terms[term] || []).includes(file) || - (titleTerms[term] || []).includes(file) - ) - ) - break; - - // select one (max) score for the file. - const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); - // add result to the result list - results.push([ - docNames[file], - titles[file], - "", - null, - score, - filenames[file], - ]); - } - return results; - }, - - /** - * helper function to return a node containing the - * search summary for a given text. keywords is a list - * of stemmed words. - */ - makeSearchSummary: (htmlText, keywords) => { - const text = Search.htmlToText(htmlText); - if (text === "") return null; - - const textLower = text.toLowerCase(); - const actualStartPosition = [...keywords] - .map((k) => textLower.indexOf(k.toLowerCase())) - .filter((i) => i > -1) - .slice(-1)[0]; - const startWithContext = Math.max(actualStartPosition - 120, 0); - - const top = startWithContext === 0 ? "" : "..."; - const tail = startWithContext + 240 < text.length ? "..." : ""; - - let summary = document.createElement("p"); - summary.classList.add("context"); - summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; - - return summary; - }, -}; - -_ready(Search.init); diff --git a/docs/_static/sphinx_highlight.js b/docs/_static/sphinx_highlight.js deleted file mode 100644 index 8a96c69..0000000 --- a/docs/_static/sphinx_highlight.js +++ /dev/null @@ -1,154 +0,0 @@ -/* Highlighting utilities for Sphinx HTML documentation. */ -"use strict"; - -const SPHINX_HIGHLIGHT_ENABLED = true - -/** - * highlight a given string on a node by wrapping it in - * span elements with the given class name. - */ -const _highlight = (node, addItems, text, className) => { - if (node.nodeType === Node.TEXT_NODE) { - const val = node.nodeValue; - const parent = node.parentNode; - const pos = val.toLowerCase().indexOf(text); - if ( - pos >= 0 && - !parent.classList.contains(className) && - !parent.classList.contains("nohighlight") - ) { - let span; - - const closestNode = parent.closest("body, svg, foreignObject"); - const isInSVG = closestNode && closestNode.matches("svg"); - if (isInSVG) { - span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - } else { - span = document.createElement("span"); - span.classList.add(className); - } - - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - const rest = document.createTextNode(val.substr(pos + text.length)); - parent.insertBefore( - span, - parent.insertBefore( - rest, - node.nextSibling - ) - ); - node.nodeValue = val.substr(0, pos); - /* There may be more occurrences of search term in this node. So call this - * function recursively on the remaining fragment. - */ - _highlight(rest, addItems, text, className); - - if (isInSVG) { - const rect = document.createElementNS( - "http://www.w3.org/2000/svg", - "rect" - ); - const bbox = parent.getBBox(); - rect.x.baseVal.value = bbox.x; - rect.y.baseVal.value = bbox.y; - rect.width.baseVal.value = bbox.width; - rect.height.baseVal.value = bbox.height; - rect.setAttribute("class", className); - addItems.push({ parent: parent, target: rect }); - } - } - } else if (node.matches && !node.matches("button, select, textarea")) { - node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); - } -}; -const _highlightText = (thisNode, text, className) => { - let addItems = []; - _highlight(thisNode, addItems, text, className); - addItems.forEach((obj) => - obj.parent.insertAdjacentElement("beforebegin", obj.target) - ); -}; - -/** - * Small JavaScript module for the documentation. - */ -const SphinxHighlight = { - - /** - * highlight the search words provided in localstorage in the text - */ - highlightSearchWords: () => { - if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight - - // get and clear terms from localstorage - const url = new URL(window.location); - const highlight = - localStorage.getItem("sphinx_highlight_terms") - || url.searchParams.get("highlight") - || ""; - localStorage.removeItem("sphinx_highlight_terms") - url.searchParams.delete("highlight"); - window.history.replaceState({}, "", url); - - // get individual terms from highlight string - const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); - if (terms.length === 0) return; // nothing to do - - // There should never be more than one element matching "div.body" - const divBody = document.querySelectorAll("div.body"); - const body = divBody.length ? divBody[0] : document.querySelector("body"); - window.setTimeout(() => { - terms.forEach((term) => _highlightText(body, term, "highlighted")); - }, 10); - - const searchBox = document.getElementById("searchbox"); - if (searchBox === null) return; - searchBox.appendChild( - document - .createRange() - .createContextualFragment( - '" - ) - ); - }, - - /** - * helper function to hide the search marks again - */ - hideSearchWords: () => { - document - .querySelectorAll("#searchbox .highlight-link") - .forEach((el) => el.remove()); - document - .querySelectorAll("span.highlighted") - .forEach((el) => el.classList.remove("highlighted")); - localStorage.removeItem("sphinx_highlight_terms") - }, - - initEscapeListener: () => { - // only install a listener if it is really needed - if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; - - document.addEventListener("keydown", (event) => { - // bail for input elements - if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; - // bail with special keys - if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; - if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { - SphinxHighlight.hideSearchWords(); - event.preventDefault(); - } - }); - }, -}; - -_ready(() => { - /* Do not call highlightSearchWords() when we are on the search page. - * It will highlight words from the *previous* search query. - */ - if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); - SphinxHighlight.initEscapeListener(); -}); diff --git a/docsource/usage/bigquery/examples.md b/docs/bigquery.md similarity index 79% rename from docsource/usage/bigquery/examples.md rename to docs/bigquery.md index f0c9c18..00772b7 100644 --- a/docsource/usage/bigquery/examples.md +++ b/docs/bigquery.md @@ -1,8 +1,12 @@ -```{toctree} -:maxdepth: 2 -``` +# Bigquery Docs + +## Settings + +In order to use sql-mock with BigQuery, ensure you have the `GOOGLE_APPLICATION_CREDENTIALS` environment variable correctly set to point to a service account file. + +You need to service account file in order to let SQL Mock connect to BigQuery while running the tests. -# Example: Testing Subscription Counts in BigQuery +## Example: Testing Subscription Counts in BigQuery ```python import datetime @@ -10,7 +14,7 @@ from sql_mock.bigquery import column_mocks as col from sql_mock.bigquery.table_mocks import BigQueryTableMock from sql_mock.table_mocks import table_meta -# Define mock tables for your data model that inherit from BigQueryTableMock +# Define table mocks for your data model that inherit from BigQueryTableMock @table_meta(table_ref='data.users') class UserTable(BigQueryTableMock): user_id = col.Int(default=1) diff --git a/docs/_sources/usage/clickhouse/examples.md.txt b/docs/clickhouse.md similarity index 70% rename from docs/_sources/usage/clickhouse/examples.md.txt rename to docs/clickhouse.md index d0a5c1b..73e21d2 100644 --- a/docs/_sources/usage/clickhouse/examples.md.txt +++ b/docs/clickhouse.md @@ -1,15 +1,24 @@ -```{toctree} -:maxdepth: 2 -``` +# Clickhouse Docs + +## Settings + +In order to use SQL Mock with Clickhouse, you need to provide the following environment variables when you run tests: + +* `SQL_MOCK_CLICKHOUSE_HOST`: Host of your Clickhouse instance +* `SQL_MOCK_CLICKHOUSE_USER`: User you want to use for the connection +* `SQL_MOCK_CLICKHOUSE_PASSWORD`: Password of your user +* `SQL_MOCK_CLICKHOUSE_PORT`: Port of your Clickhouse instance + +Having those environment variables enables SQL Mock to connect to your Clickhouse instance. -# Example: Testing Subscription Counts in ClickHouse +## Example: Testing Subscription Counts in ClickHouse ```python from sql_mock.clickhouse import column_mocks as col from sql_mock.clickhouse.table_mocks import ClickHouseTableMock from sql_mock.table_mocks import table_meta -# Define mock tables for your data model that inherit from ClickHouseTableMock +# Define table mocks for your data model that inherit from ClickHouseTableMock @table_meta(table_ref='data.users') class UserTable(ClickHouseTableMock): user_id = col.Int(default=1) @@ -47,7 +56,7 @@ subscriptions = SubscriptionTable.from_dicts([ # Define your expected results expected = [ - {'user_id': 1, 'subscription_count': 2}, + {'user_id': 1, 'subscription_count': 2}, {'user_id': 2, 'subscription_count': 1} ] diff --git a/docsource/usage/dbt.md b/docs/dbt.md similarity index 98% rename from docsource/usage/dbt.md rename to docs/dbt.md index e1dd090..bd56f0f 100644 --- a/docsource/usage/dbt.md +++ b/docs/dbt.md @@ -21,7 +21,7 @@ from sql_mock.config import SQLMockConfig SQLMockConfig.set_dbt_manifest_path('/path/to/your/dbt/manifest.json') ``` -## Creating Mock Tables +## Creating Table Mocks SQLMock offers specialized decorators for different dbt entities: models, sources, and seeds. @@ -71,7 +71,7 @@ class YourDBTSeedTable(BigQueryTableMock): Let’s consider a dbt model named `monthly_user_spend` that aggregates data from a source `user_transactions` and a seed `user_categories`. -### Step 1: Define Your Source and Seed Mock Tables +### Step 1: Define Your Source and Seed Table Mocks ```python @dbt_source_meta(source_name="transactions", table_name="user_transactions") diff --git a/docsource/usage/default_values.md b/docs/default_values.md similarity index 93% rename from docsource/usage/default_values.md rename to docs/default_values.md index 657d63a..09e6506 100644 --- a/docsource/usage/default_values.md +++ b/docs/default_values.md @@ -1,14 +1,10 @@ -```{toctree} -:maxdepth: 2 -``` - # Default values -Testing SQL queries can often involve repetitive setup for mock tables. In SQLMock, one effective way to streamline this process is by using default values. By setting reasonable defaults, you can significantly reduce the boilerplate code in your tests, especially when dealing with multiple input tables or complex queries. Let’s explore how you can efficiently implement this. +Testing SQL queries can often involve repetitive setup for table mocks. In SQLMock, one effective way to streamline this process is by using default values. By setting reasonable defaults, you can significantly reduce the boilerplate code in your tests, especially when dealing with multiple input tables or complex queries. Let’s explore how you can efficiently implement this. ## Utilizing Default Values in TableMock Fields -Defining default values at the field level in your mock tables is straightforward. +Defining default values at the field level in your table mocks is straightforward. The default argument in the field definition allows you to set default values consistency across all test scenarios in one step. They are particularly useful for ensuring that joins and other query functionalities operate correctly. diff --git a/docsource/usage/defining_table_mocks.md b/docs/defining_table_mocks.md similarity index 92% rename from docsource/usage/defining_table_mocks.md rename to docs/defining_table_mocks.md index 5506c97..8c6b85f 100644 --- a/docsource/usage/defining_table_mocks.md +++ b/docs/defining_table_mocks.md @@ -1,10 +1,6 @@ -```{toctree} -:maxdepth: 2 -``` - # Defining table mocks -When you want to provide mocked data to test your SQL model, you need to create TableMock classes for all upstream data that your model uses, as well as for the model you want to test. Those mock tables can be created by inheriting from a `BaseTableMock` class for the database provider you are using (e.g. `BigQueryTableMock`). +When you want to provide mocked data to test your SQL model, you need to create TableMock classes for all upstream data that your model uses, as well as for the model you want to test. Those table mocks can be created by inheriting from a `BaseTableMock` class for the database provider you are using (e.g. `BigQueryTableMock`). **We recommend to have a central `model.py` file where you create those models that you can easily reuse them across your tests** diff --git a/docs/faq.html b/docs/faq.html deleted file mode 100644 index ed6a5aa..0000000 --- a/docs/faq.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - - FAQ — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

FAQ

-
-

My database system is not supported yet but I want to use SQL Mock. What should I do?

-

We are planning to add more and more supported database systems. However, if your system is not supported yet, you can still use SQL Mock. There are only 2 things you need to do:

-
-

Create your MockTable class

-

First, you need to create a MockTable class for your database system that inherits from sql_mock.table_mocks.BaseMockTable.

-

That class needs to implement the _get_results method which should make sure to fetch the results of a query (e.g. produced by self._generate_query()) and return it as list of dictionaries.

-

Look at one of the existing client libraries to see how this could work (e.g. BigQueryMockTable).

-

You might want to create a settings class as well in case you need some specific connection settings to be available within the _get_results method.

-
-
-

Create your ColumnMocks

-

Your database system might support specific database types. In order to make them available as column types, you can use the sql_mock.column_mocks.ColumnMock class as a base and inherit your specific column types from it. -For most of your column mocks you might only need to specify the dtype that should be used to parse the inputs.

-

A good practise is to create a ColumnMock class that is specific to your database and inherit all your column types from it, e.g.:

-
from sql_mock.column_mocks import ColumnMock
-
-class MyFanceDatabaseColumnMock(ColumnMock):
-    # In case you need some specific logic that overwrites the default behavior, you can do so here
-    pass
-
-class Int(MyFanceDatabaseColumnMock):
-    dtype = "Integer"
-
-class String(MyFanceDatabaseColumnMock):
-    dtype = "String"
-
-
-
-
-

Contribute your database setup

-

There will definitely be folks in the community that are in the need of support for the database you just created all the setup for. -Feel free to create a PR on this repository that we can start supporting your database system!

-
-
-
-

I am missing a specific ColumnMock type for my model fields

-

We implemented some basic column types but it could happen that you don’t find the one you need. -Luckily, you can easily create those with the tools provided. -The only thing you need to do is to inherit from the ColumnMock that is specific to your database system (e.g. BigQueryColumnMock) and write classes for the column mocks you are missing. Usually you only need to set the correct dtype. This would later be used in the cast(col to <dtype>) expression.

-
# Replace the import with the database system you are using
-from sql_mock.bigquery.column_mock import BigQueryColumnMock
-
-class MyFancyMissingColType(BigQueryColumnMock):
-    dtype = "FancyMissingColType"
-
-    # In case you need to implement additional logic for casting, you can do so here
-    ...
-
-
-

Don’t forget to create a PR in case you feel that your column mock type could be useful for the community!

-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/genindex.html b/docs/genindex.html deleted file mode 100644 index 981ed35..0000000 --- a/docs/genindex.html +++ /dev/null @@ -1,865 +0,0 @@ - - - - - - Index — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- - -

Index

- -
- _ - | A - | B - | C - | D - | F - | G - | H - | I - | L - | M - | N - | O - | P - | Q - | R - | S - | T - | U - | V - -
-

_

- - - -
- -

A

- - - -
- -

B

- - - -
- -

C

- - - -
- -

D

- - -
- -

F

- - - -
- -

G

- - - -
- -

H

- - - -
- -

I

- - - -
- -

L

- - -
- -

M

- - -
- -

N

- - - -
- -

O

- - -
- -

P

- - - -
- -

Q

- - -
- -

R

- - - -
- -

S

- - - -
- -

T

- - - -
- -

U

- - - -
- -

V

- - - -
- - - -
-
-
- -
- -
-

© Copyright 2023, DeepL, Thomas Schmidt.

-
- - Built with Sphinx using a - theme - provided by Read the Docs. - - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/docs/getting_started/installation.html b/docs/getting_started/installation.html deleted file mode 100644 index fc06c34..0000000 --- a/docs/getting_started/installation.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - - Installation — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-
-
-

Installation

-

The library can be installed from PyPI using pip:

-
# BigQuery
-pip install --upgrade "sql-mock[bigquery]"
-
-# Clickhouse
-pip install --upgrade "sql-mock[clickhouse]"
-
-# Redshift
-pip install --upgrade "sql-mock[redshift]"
-
-# Snowflake
-pip install --upgrade "sql-mock[snowflake]"
-
-
-

If you need to modify this source code, install the dependencies using poetry:

-
poetry install --all-extras
-
-
- -
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/getting_started/quickstart.html b/docs/getting_started/quickstart.html deleted file mode 100644 index 7a69fbf..0000000 --- a/docs/getting_started/quickstart.html +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - Quickstart — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-
-
-

Quickstart

-

Before diving into specific database scenarios, let’s start with a simplified example of how SQL Mock works behind the scenes.

-
    -
  1. You have an original SQL query, for instance:

    -
    -- path/to/query_for_result_table.sql
    -SELECT id FROM data.table1
    -
    -
    -
  2. -
  3. Using SQL Mock, you define mock tables. You can use the built-in column types provided by SQL Mock. Available column types include Int, String, Date, and more. Each database type has their own column types. Define your tables by subclassing a mock table class that fits your database (e.g. BigQueryMockTable) and specifying the column types along with default values. In our example we use the ClickHouseTableMock class

    -
    from sql_mock.clickhouse import column_mocks as col
    -from sql_mock.clickhouse.table_mocks import ClickHouseTableMock
    -from sql_mock.table_mocks import table_meta
    -
    -@table_meta(table_ref='data.table1')
    -class Table(ClickHouseTableMock):
    -    id = col.Int(default=1)
    -    name = col.String(default='Peter')
    -
    -@table_meta(table_ref='data.result_table', query_path='path/to/query_for_result_table.sql')
    -class ResultTable(ClickHouseTableMock):
    -    id = col.Int(default=1)
    -
    -
    -
  4. -
  5. Creating mock data: Define mock data for your tables using dictionaries. Each dictionary represents a row in the table, with keys corresponding to column names. Table column keys that don’t get a value will use the default.

    -
    user_data = [
    -    {}, # This will use the defaults for both id and name
    -    {'id': 2, 'name': 'Martin'},
    -    {'id': 3}, # This will use defaults for the name
    -]
    -
    -input_table_mock = Table.from_dicts(user_data)
    -
    -
    -
  6. -
  7. Getting results for a table mock: Use the from_mocks method of the table mock object to generate mock query results based on your mock data.

    -
    res = ResultTable.from_mocks(input_data=[input_table_mock])
    -
    -
    -
  8. -
  9. Behind the scene SQL Mock replaces table references (e.g. data.table1) in your query with Common Table Expressions (CTEs) filled with dummy data. It can roughly be compared to something like this:

    -
    WITH data__table1 AS (
    -    -- Mocked inputs
    -    SELECT 
    -        cast('1' AS 'String') AS id, 
    -        cast('Peter' AS 'String') AS name
    -    UNION ALL 
    -    SELECT 
    -        cast('2' AS 'String') AS id, 
    -        cast('Martin' AS 'String') AS name
    -    UNION ALL 
    -    SELECT 
    -        cast('3' AS 'String') AS id, 
    -        cast('Peter' AS 'String') AS name
    -)
    -
    -result AS (
    -    -- Original query with replaced references
    -    SELECT id FROM data__table1 
    -)
    -
    -SELECT 
    -    cast(id AS 'String') AS id
    -FROM result
    -
    -
    -
  10. -
  11. Finally, you can compare your results to some expected results using the assert_equal method.

    -
    expected = [{'id': '1'},{'id': '2'},{'id': '3'}]
    -res.assert_equal(expected)
    -
    -
    -
  12. -
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 443a051..0000000 --- a/docs/index.html +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - - - Welcome to SQL Mock’s documentation! — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

Welcome to SQL Mock’s documentation!

-

The primary purpose of this library is to simplify the testing of SQL data models and queries by allowing users to mock input data and create tests for various scenarios. -It provides a consistent and convenient way to test the execution of your query without the need to process a massive amount of data.

- - - -
-

API Reference

- -
-
-
-

Indices and tables

- -
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/modules.html b/docs/modules.html deleted file mode 100644 index 7b6f4ab..0000000 --- a/docs/modules.html +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - sql_mock — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

sql_mock

-
-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/objects.inv b/docs/objects.inv deleted file mode 100644 index 26e6138..0000000 Binary files a/docs/objects.inv and /dev/null differ diff --git a/docs/py-modindex.html b/docs/py-modindex.html deleted file mode 100644 index 80a0df4..0000000 --- a/docs/py-modindex.html +++ /dev/null @@ -1,243 +0,0 @@ - - - - - - Python Module Index — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
-
    -
  • - -
  • -
  • -
-
-
-
-
- - -

Python Module Index

- -
- s -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
- s
- sql_mock -
    - sql_mock.bigquery -
    - sql_mock.bigquery.column_mocks -
    - sql_mock.bigquery.settings -
    - sql_mock.bigquery.table_mocks -
    - sql_mock.clickhouse -
    - sql_mock.clickhouse.column_mocks -
    - sql_mock.clickhouse.settings -
    - sql_mock.clickhouse.table_mocks -
    - sql_mock.column_mocks -
    - sql_mock.constants -
    - sql_mock.exceptions -
    - sql_mock.redshift -
    - sql_mock.redshift.column_mocks -
    - sql_mock.redshift.settings -
    - sql_mock.redshift.table_mocks -
    - sql_mock.snowflake -
    - sql_mock.snowflake.column_mocks -
    - sql_mock.snowflake.settings -
    - sql_mock.snowflake.table_mocks -
    - sql_mock.table_mocks -
- - -
-
-
- -
- -
-

© Copyright 2023, DeepL, Thomas Schmidt.

-
- - Built with Sphinx using a - theme - provided by Read the Docs. - - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/docsource/usage/redshift/examples.md b/docs/redshift.md similarity index 72% rename from docsource/usage/redshift/examples.md rename to docs/redshift.md index 4ce4c12..87a01fd 100644 --- a/docsource/usage/redshift/examples.md +++ b/docs/redshift.md @@ -1,8 +1,17 @@ -```{toctree} -:maxdepth: 2 -``` +# Redshift Docs + +## Settings + +In order to use SQL Mock with Redshift, you need to provide the following environment variables when you run tests: + +* `SQL_MOCK_REDSHIFT_HOST`: The host of your Redshift instance +* `SQL_MOCK_REDSHIFT_USER`: The user of your Redshift instance +* `SQL_MOCK_REDSHIFT_PASSWORD`: The password of your Redshift instance +* `SQL_MOCK_REDSHIFT_PORT`: The port of your Redshift instance + +Having those environment variables enables SQL Mock to connect to your Redshift instance. -# Example: Testing Subscription Counts in Redshift +## Example: Testing Subscription Counts in Redshift ```python import datetime @@ -10,7 +19,7 @@ from sql_mock.redshift import column_mocks as col from sql_mock.redshift.table_mocks import RedshiftTableMock from sql_mock.table_mocks import table_meta -# Define mock tables for your data model that inherit from RedshiftTableMock +# Define table mocks for your data model that inherit from RedshiftTableMock @table_meta(table_ref="data.users") class UserTable(RedshiftTableMock): user_id = col.INTEGER(default=1) diff --git a/docsource/usage/result_assertion.md b/docs/result_assertion.md similarity index 97% rename from docsource/usage/result_assertion.md rename to docs/result_assertion.md index 2aca22d..80bf81f 100644 --- a/docsource/usage/result_assertion.md +++ b/docs/result_assertion.md @@ -1,7 +1,3 @@ -```{toctree} -:maxdepth: 2 -``` - # Result assertion There are 2 ways how you can check the output of your query given the mocked input data on your Table Mock instance: @@ -31,7 +27,7 @@ users_with_multiple_subs AS ( SELECT user_id FROM users_with_multiple_subs ``` -... and we define the following mock tables: +... and we define the following table mocks: ```python import datetime diff --git a/docs/robots.html b/docs/robots.html deleted file mode 100644 index d20502d..0000000 --- a/docs/robots.html +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - <no title> — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

User-agent: *

-

Sitemap: https://deeplcom.github.io/sql-mock/sitemap.xml

- - -
-
-
- -
- -
-

© Copyright 2023, DeepL, Thomas Schmidt.

-
- - Built with Sphinx using a - theme - provided by Read the Docs. - - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/docs/search.html b/docs/search.html deleted file mode 100644 index 946753b..0000000 --- a/docs/search.html +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - Search — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
-
    -
  • - -
  • -
  • -
-
-
-
-
- - - - -
- -
- -
-
-
- -
- -
-

© Copyright 2023, DeepL, Thomas Schmidt.

-
- - Built with Sphinx using a - theme - provided by Read the Docs. - - -
-
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/searchindex.js b/docs/searchindex.js deleted file mode 100644 index 788ec11..0000000 --- a/docs/searchindex.js +++ /dev/null @@ -1 +0,0 @@ -Search.setIndex({"docnames": ["faq", "getting_started/installation", "getting_started/quickstart", "index", "modules", "robots", "sql_mock", "sql_mock.bigquery", "sql_mock.clickhouse", "sql_mock.redshift", "sql_mock.snowflake", "usage/bigquery/examples", "usage/bigquery/index", "usage/bigquery/settings", "usage/clickhouse/examples", "usage/clickhouse/index", "usage/clickhouse/settings", "usage/dbt", "usage/default_values", "usage/defining_table_mocks", "usage/examples", "usage/redshift/examples", "usage/redshift/index", "usage/redshift/settings", "usage/result_assertion", "usage/snowflake/examples", "usage/snowflake/index", "usage/snowflake/settings", "usage/your_sql_query_to_test"], "filenames": ["faq.md", "getting_started/installation.md", "getting_started/quickstart.md", "index.rst", "modules.rst", "robots.txt", "sql_mock.rst", "sql_mock.bigquery.rst", "sql_mock.clickhouse.rst", "sql_mock.redshift.rst", "sql_mock.snowflake.rst", "usage/bigquery/examples.md", "usage/bigquery/index.rst", "usage/bigquery/settings.md", "usage/clickhouse/examples.md", "usage/clickhouse/index.rst", "usage/clickhouse/settings.md", "usage/dbt.md", "usage/default_values.md", "usage/defining_table_mocks.md", "usage/examples.md", "usage/redshift/examples.md", "usage/redshift/index.rst", "usage/redshift/settings.md", "usage/result_assertion.md", "usage/snowflake/examples.md", "usage/snowflake/index.rst", "usage/snowflake/settings.md", "usage/your_sql_query_to_test.md"], "titles": ["FAQ", "Installation", "Quickstart", "Welcome to SQL Mock\u2019s documentation!", "sql_mock", "<no title>", "sql_mock package", "sql_mock.bigquery package", "sql_mock.clickhouse package", "sql_mock.redshift package", "sql_mock.snowflake package", "Example: Testing Subscription Counts in BigQuery", "BigQuery", "Settings", "Example: Testing Subscription Counts in ClickHouse", "Clickhouse", "Settings", "Use with dbt", "Default values", "Defining table mocks", "Examples", "Example: Testing Subscription Counts in Redshift", "Redshift", "Settings", "Result assertion", "Example: Testing Subscription Counts in Snowflake", "Snowflake", "Settings", "Your SQL query to test"], "terms": {"we": [0, 1, 2, 6, 17, 18, 19, 24, 28], "ar": [0, 1, 6, 17, 18, 19, 24, 28], "plan": 0, "add": [0, 1, 6], "more": [0, 2, 19, 24], "howev": 0, "you": [0, 1, 2, 6, 13, 16, 17, 18, 19, 20, 23, 24, 27, 28], "can": [0, 1, 2, 6, 17, 18, 19, 20, 24, 28], "still": 0, "There": [0, 19, 24, 28], "onli": [0, 6, 18, 19, 24, 28], "2": [0, 2, 3, 11, 14, 18, 19, 21, 24, 25], "thing": [0, 19], "need": [0, 1, 3, 6, 13, 16, 18, 19, 23, 27, 28], "first": 0, "inherit": [0, 6, 11, 14, 19, 21, 25], "from": [0, 1, 2, 6, 7, 8, 9, 10, 11, 14, 17, 19, 21, 24, 25, 28], "sql_mock": [0, 1, 2, 11, 14, 17, 19, 21, 24, 25], "table_mock": [0, 2, 11, 14, 17, 19, 21, 24, 25], "basemockt": [0, 6, 7, 8, 9, 10, 19], "That": 0, "implement": [0, 18], "_get_result": 0, "method": [0, 1, 2, 18, 19, 24, 28], "which": [0, 6, 17], "make": [0, 1, 17], "sure": [0, 1, 17], "fetch": 0, "result": [0, 2, 3, 6, 11, 14, 17, 19, 21, 25], "queri": [0, 2, 3, 6, 11, 14, 18, 19, 21, 24, 25], "e": [0, 2, 6, 19, 28], "g": [0, 2, 6, 19, 28], "produc": [0, 17], "self": 0, "_generate_queri": 0, "return": [0, 6], "list": [0, 6], "dictionari": [0, 2, 6, 7, 8, 9, 10, 28], "look": 0, "one": [0, 6, 18], "exist": 0, "client": 0, "librari": [0, 1, 3, 17], "see": 0, "how": [0, 2, 12, 15, 17, 18, 19, 22, 24, 26, 28], "thi": [0, 1, 2, 3, 6, 7, 8, 9, 10, 12, 15, 17, 19, 22, 24, 26, 28], "could": 0, "work": [0, 2, 17, 18], "bigquerymockt": [0, 2, 6, 7, 11, 17, 18, 19, 24], "might": 0, "set": [0, 3, 6, 12, 15, 22, 26], "well": [0, 19], "case": [0, 3, 18, 24, 28], "some": [0, 2, 19, 20, 28], "connect": [0, 13, 16, 23, 27], "avail": [0, 2], "within": [0, 6], "In": [0, 1, 2, 13, 16, 18, 23, 24, 27, 28], "order": [0, 6, 13, 16, 23, 27], "them": [0, 19, 28], "column": [0, 2, 6, 17, 18], "column_mock": [0, 2, 11, 14, 19, 21, 24, 25], "base": [0, 2, 6, 7, 8, 9, 10], "For": [0, 17, 18], "most": 0, "specifi": [0, 2, 18, 19, 28], "dtype": [0, 6, 7, 8, 9, 10], "pars": 0, "input": [0, 2, 3, 6, 17, 18, 19, 24, 28], "A": [0, 6, 17, 24], "good": 0, "practis": 0, "all": [0, 1, 2, 6, 18, 19], "import": [0, 1, 2, 11, 14, 17, 19, 21, 24, 25], "myfancedatabasecolumnmock": 0, "logic": [0, 18, 24], "overwrit": [0, 6, 19], "default": [0, 2, 3, 6, 7, 8, 9, 10, 11, 14, 17, 19, 21, 24, 25, 28], "behavior": 0, "so": 0, "here": [0, 17, 18], "pass": [0, 3, 18, 19], "int": [0, 2, 6, 7, 8, 9, 11, 14, 17, 18, 19, 24, 28], "integ": [0, 7, 8, 9, 10, 21, 25], "string": [0, 2, 6, 7, 8, 10, 11, 14, 17, 18, 19, 24, 25, 28], "definit": [0, 18, 19], "folk": 0, "commun": 0, "just": 0, "feel": 0, "free": 0, "pr": 0, "repositori": 0, "start": [0, 2, 17], "basic": [0, 18], "happen": [0, 6], "don": [0, 2, 18], "t": [0, 2, 11, 14, 18, 21, 24, 25], "find": [0, 20], "luckili": 0, "easili": [0, 19], "those": [0, 16, 19, 23, 24, 27, 28], "tool": [0, 17], "provid": [0, 2, 3, 6, 16, 17, 18, 19, 23, 27], "The": [0, 1, 3, 6, 17, 18, 19, 23, 27, 28], "bigquerycolumnmock": [0, 6, 7], "write": [0, 3], "usual": [0, 19], "correct": [0, 18], "would": [0, 6], "later": 0, "cast": [0, 2, 6], "col": [0, 2, 11, 14, 17, 18, 19, 21, 24, 25, 28], "express": [0, 2], "replac": [0, 2, 6, 7, 8, 9, 10], "bigqueri": [0, 1, 3, 6, 13, 17, 19, 24], "myfancymissingcoltyp": 0, "fancymissingcoltyp": 0, "addit": [0, 18], "forget": 0, "pypi": 1, "us": [1, 2, 3, 6, 11, 12, 13, 14, 15, 16, 19, 21, 22, 23, 24, 25, 26, 27], "pip": 1, "upgrad": 1, "sql": [1, 2, 5, 6, 11, 12, 13, 14, 15, 16, 18, 19, 21, 22, 23, 24, 25, 26, 27], "mock": [1, 2, 5, 6, 11, 12, 13, 14, 15, 16, 21, 22, 23, 24, 25, 26, 27, 28], "clickhous": [1, 2, 3, 6, 16], "redshift": [1, 3, 23], "If": [1, 6], "modifi": 1, "sourc": [1, 3], "code": [1, 18], "depend": 1, "poetri": 1, "extra": [1, 7, 8, 9, 10], "conftest": 1, "py": [1, 19, 28], "file": [1, 6, 13, 17, 19, 28], "root": 1, "your": [1, 2, 3, 11, 14, 16, 18, 19, 21, 23, 24, 25, 27], "project": [1, 17], "follow": [1, 16, 23, 24, 27, 28], "line": 1, "register_assert_rewrit": 1, "allow": [1, 3, 18, 19], "get": [1, 2], "rich": 1, "comparison": [1, 6], "when": [1, 3, 6, 16, 19, 23, 24, 27, 28], "assert_equ": [1, 2, 6, 11, 14, 17, 21, 24, 25], "tabl": [1, 2, 6, 11, 14, 18, 21, 24, 25, 28], "instanc": [1, 2, 6, 16, 18, 19, 23, 24, 27, 28], "also": [1, 19, 24, 28], "icdiff": 1, "better": 1, "visibl": 1, "diff": 1, "fail": [1, 6], "test": [1, 3, 6, 12, 13, 15, 16, 18, 19, 22, 23, 24, 26, 27], "befor": 2, "dive": 2, "specif": [2, 12, 15, 18, 22, 26, 28], "databas": [2, 6, 9, 17, 19], "scenario": [2, 3, 18], "let": [2, 13, 17, 18, 24, 28], "": [2, 6, 17, 18, 24, 28], "simplifi": [2, 3, 18], "exampl": [2, 3, 12, 15, 18, 22, 24, 26, 28], "behind": 2, "scene": 2, "have": [2, 13, 16, 19, 23, 24, 27], "an": [2, 18], "origin": [2, 6, 11, 14, 21, 25], "path": [2, 3, 6, 7, 8, 9, 10, 18, 19, 28], "query_for_result_t": [2, 19, 28], "select": [2, 11, 14, 19, 21, 24, 25, 28], "id": [2, 19, 28], "data": [2, 3, 6, 11, 14, 18, 19, 21, 24, 25, 28], "table1": [2, 19], "defin": [2, 3, 6, 7, 8, 9, 10, 11, 14, 18, 21, 24, 25, 28], "built": [2, 24], "type": [2, 3, 6], "includ": [2, 24], "date": [2, 6, 7, 8, 9, 10, 11, 14, 17, 21, 24, 25], "each": 2, "ha": [2, 17], "own": 2, "subclass": 2, "class": [2, 3, 6, 7, 8, 9, 10, 11, 14, 17, 18, 19, 21, 24, 25, 28], "fit": 2, "along": 2, "valu": [2, 3, 6], "our": [2, 24], "clickhousetablemock": [2, 6, 8, 14], "table_meta": [2, 3, 6, 11, 14, 19, 21, 24, 25], "table_ref": [2, 6, 11, 14, 18, 19, 21, 24, 25, 28], "1": [2, 3, 6, 11, 14, 18, 19, 21, 24, 25], "name": [2, 6, 7, 8, 9, 10, 17, 19, 27], "peter": [2, 19], "result_t": [2, 19, 28], "query_path": [2, 6, 18, 19, 24, 28], "resultt": [2, 19, 28], "creat": [2, 3, 6, 11, 14, 18, 19, 21, 25], "repres": [2, 6], "row": [2, 6], "kei": [2, 6], "correspond": 2, "user_data": 2, "both": 2, "martin": 2, "3": [2, 3, 18], "input_table_mock": 2, "from_dict": [2, 6, 11, 14, 17, 18, 21, 24, 25], "from_mock": [2, 3, 6, 11, 14, 17, 18, 19, 21, 24, 25], "object": [2, 6, 10], "gener": [2, 6], "re": [2, 11, 14, 18, 19, 21, 24, 25, 28], "input_data": [2, 6, 11, 14, 17, 18, 19, 21, 24, 25, 28], "refer": [2, 6], "common": 2, "cte": [2, 6, 24], "fill": [2, 18], "dummi": 2, "It": [2, 3, 6], "roughli": 2, "compar": [2, 6], "someth": 2, "like": [2, 6, 19], "WITH": [2, 24], "data__table1": 2, "AS": [2, 11, 14, 21, 24, 25, 28], "union": [2, 6], "final": [2, 6, 24], "expect": [2, 6, 11, 14, 17, 21, 25], "primari": 3, "purpos": 3, "i": [3, 6, 17, 19, 28], "model": [3, 6, 7, 8, 9, 10, 11, 14, 19, 21, 24, 25, 28], "user": [3, 5, 6, 8, 9, 10, 11, 14, 16, 18, 21, 23, 24, 25, 27, 28], "variou": [3, 18], "consist": [3, 18], "conveni": 3, "wai": [3, 18, 19, 24], "execut": 3, "without": 3, "process": [3, 6, 18], "massiv": 3, "amount": [3, 17], "instal": [3, 17], "recommend": [3, 19], "setup": [3, 18], "pytest": 3, "quickstart": 3, "faq": 3, "my": 3, "system": 3, "support": 3, "yet": 3, "want": [3, 6, 16, 19, 24, 28], "what": 3, "should": [3, 6, 7, 8, 9, 10], "do": [3, 24], "mocktabl": [3, 6, 19], "columnmock": [3, 6, 7, 8, 9, 10], "contribut": 3, "am": 3, "miss": 3, "field": [3, 6, 7, 8, 9, 10], "dbt": [3, 28], "introduct": 3, "prerequisit": 3, "configur": [3, 6, 7, 8, 9, 10], "manifest": 3, "seed": 3, "upstream": [3, 19], "step": [3, 18, 24], "option": 3, "decor": [3, 6, 17, 18, 19], "call": 3, "jinja": [3, 6], "templat": [3, 6], "assert": [3, 6, 11, 14, 21, 25], "util": 3, "subscript": [3, 12, 15, 18, 22, 24, 26], "count": [3, 12, 15, 22, 24, 26], "index": 3, "modul": 3, "search": 3, "page": 3, "agent": 5, "sitemap": 5, "http": 5, "deeplcom": 5, "github": 5, "io": 5, "xml": 5, "arrai": [6, 7, 8, 10], "use_quotes_for_cast": [6, 7, 8, 10], "decim": [6, 7, 8, 9, 10], "float": [6, 7, 8, 10, 17], "bigqueryset": [6, 7], "google_application_credenti": [6, 7, 13], "model_config": [6, 7, 8, 9, 10], "model_field": [6, 7, 8, 9, 10], "boolean": [6, 8, 9, 10], "clickhousecolumnmock": [6, 8], "datetim": [6, 8, 11, 14, 17, 21, 24, 25], "datetime64": [6, 8], "clickhouseset": [6, 8], "host": [6, 8, 9, 16, 23], "password": [6, 8, 9, 10, 16, 23, 27], "port": [6, 8, 9, 16, 23], "none": [6, 7, 8, 9, 10], "nullabl": [6, 7, 8, 9, 10], "fals": [6, 7, 8, 9, 10], "str": [6, 7, 8, 9, 10], "indic": 6, "whether": 6, "null": 6, "quot": 6, "bool": [6, 7, 8, 9, 10], "cast_field": 6, "column_nam": 6, "to_sql": 6, "noinput": 6, "true": [6, 7, 8, 9, 10], "validationerror": 6, "dict": [6, 7, 8, 9, 10], "sql_mock_data": 6, "sqlmockdata": 6, "attribut": [6, 17], "col1": 6, "_sql_mock_data": 6, "store": 6, "automatci": 6, "instanti": 6, "_sql_dialect": 6, "dialect": 6, "leverag": 6, "sqlglot": 6, "as_sql_input": 6, "combin": [6, 18], "assert_cte_equ": [6, 24], "cte_nam": 6, "ignore_missing_kei": 6, "ignore_ord": 6, "print_query_on_fail": 6, "equal": 6, "paramet": 6, "against": 6, "present": 6, "argument": [6, 18, 19, 28], "ignor": 6, "print": 6, "consol": 6, "output": [6, 24], "classmethod": 6, "query_template_kwarg": [6, 28], "run": [6, 13, 16, 17, 23, 24, 27], "static": [6, 17], "hold": 6, "pair": 6, "render": [6, 28], "cl": 6, "_sql_mock_meta": 6, "mocktablemeta": 6, "default_input": [6, 18, 19], "basemodel": 6, "metadata": [6, 7, 8, 9, 10], "dure": 6, "avoid": 6, "collis": 6, "srting": 6, "format": 6, "properti": 6, "classvar": [6, 7, 8, 9, 10], "configdict": [6, 7, 8, 9, 10], "arbitrary_types_allow": [6, 7, 8, 9, 10], "conform": [6, 7, 8, 9, 10], "pydant": [6, 7, 8, 9, 10], "config": [6, 7, 8, 9, 10, 17], "fieldinfo": [6, 7, 8, 9, 10], "annot": [6, 7, 8, 9, 10], "skipvalid": 6, "requir": [6, 7, 8, 9, 10, 18], "about": [6, 7, 8, 9, 10], "map": [6, 7, 8, 9, 10, 24], "__fields__": [6, 7, 8, 9, 10], "v1": [6, 7, 8, 9, 10], "rendered_queri": 6, "last_queri": 6, "note": [6, 28], "serv": 6, "other": [6, 17, 18], "inner_dtyp": [7, 8], "precis": [7, 8, 9, 10], "scale": [7, 8, 9, 10], "_case_sensit": [7, 8, 9, 10], "_env_prefix": [7, 8, 9, 10], "_env_fil": [7, 8, 9, 10], "dotenvtyp": [7, 8, 9, 10], "posixpath": [7, 8, 9, 10], "_env_file_encod": [7, 8, 9, 10], "_env_nested_delimit": [7, 8, 9, 10], "_secrets_dir": [7, 8, 9, 10], "baseset": [7, 8, 9, 10], "settingsconfigdict": [7, 8, 9, 10], "case_sensit": [7, 8, 9, 10], "env_fil": [7, 8, 9, 10], "env_file_encod": [7, 8, 9, 10], "env_nested_delimit": [7, 8, 9, 10], "env_prefix": [7, 8, 9, 10], "forbid": [7, 8, 9, 10], "protected_namespac": [7, 8, 9, 10], "model_": [7, 8, 9, 10], "settings_": [7, 8, 9, 10], "secrets_dir": [7, 8, 9, 10], "validate_default": [7, 8, 9, 10], "arg": [7, 8, 9, 10], "kwarg": [7, 8, 9, 10], "sql_mock_clickhouse_": 8, "bigint": 9, "redshiftcolumnmock": 9, "char": 9, "double_precis": 9, "doubl": 9, "geographi": [9, 10], "geometri": 9, "hllsketch": 9, "real": 9, "smallint": 9, "super": 9, "time": [9, 10, 18, 24], "timestamp": [9, 10], "timestamptz": 9, "timetz": 9, "varbyt": 9, "varchar": [9, 21], "redshiftset": 9, "5439": 9, "sql_mock_redshift_": 9, "redshiftmockt": [9, 21], "usert": [11, 14, 18, 21, 24, 25], "user_id": [11, 14, 17, 18, 21, 24, 25, 28], "user_nam": [11, 14, 18, 21, 24, 25], "mr": [11, 14, 18, 21, 24, 25], "subscriptiont": [11, 14, 18, 21, 24, 25], "subscription_id": [11, 14, 18, 21, 24, 25], "period_start_d": [11, 14, 21, 24, 25], "2023": [11, 14, 17, 21, 24, 25, 28], "9": [11, 14, 21, 24, 25], "5": [11, 14, 21, 24, 25], "period_end_d": [11, 14, 21, 24, 25], "subscriptioncountt": [11, 14, 21, 25], "subscription_count": [11, 14, 21, 24, 25], "left": [11, 14, 18, 21, 24, 25], "join": [11, 14, 18, 21, 24, 25], "group": [11, 14, 21, 24, 25], "BY": [11, 14, 21, 24, 25], "simul": [11, 14, 21, 25], "section": [12, 15, 19, 22, 26], "document": [12, 15, 22, 26], "ensur": [13, 18], "environ": [13, 16, 17, 23, 27], "variabl": [13, 16, 23, 27, 28], "correctli": [13, 18], "point": 13, "servic": 13, "account": [10, 13, 27], "while": 13, "sql_mock_clickhouse_host": 16, "sql_mock_clickhouse_us": 16, "sql_mock_clickhouse_password": 16, "sql_mock_clickhouse_port": 16, "enabl": [16, 23, 27], "guid": 17, "quick": 17, "sqlmock": [17, 18], "build": 17, "ll": 17, "cover": [17, 28], "featur": 17, "effect": [17, 18], "unit": [17, 24], "json": 17, "latest": 17, "compil": 17, "python": 17, "initi": 17, "global": 17, "sqlmockconfig": 17, "set_dbt_manifest_path": 17, "offer": 17, "special": 17, "differ": [17, 18, 24], "entiti": 17, "dbt_model_meta": 17, "suit": 17, "transform": 17, "model_nam": 17, "your_dbt_model_nam": 17, "yourdbtmodelt": 17, "necessari": [17, 28], "dbt_source_meta": 17, "ideal": 17, "raw": 17, "consum": 17, "source_nam": 17, "your_source_nam": 17, "table_nam": 17, "your_source_t": 17, "yourdbtsourcet": 17, "load": 17, "dbt_seed_meta": 17, "seed_nam": 17, "your_dbt_seed_nam": 17, "yourdbtseedt": 17, "consid": [17, 18], "monthly_user_spend": 17, "aggreg": 17, "user_transact": 17, "user_categori": 17, "transact": 17, "usertransactionst": 17, "transaction_id": 17, "0": 17, "transaction_d": 17, "12": 17, "24": 17, "usercategoriest": 17, "categori": 17, "foo": 17, "monthlyuserspendt": 17, "month": 17, "total_spend": 17, "def": [17, 24, 25], "test_monthly_user_spend_model": 17, "transactions_data": 17, "120": 17, "10": 17, "150": 17, "20": 17, "categories_data": 17, "premium": 17, "standard": 17, "transactions_t": 17, "categories_t": 17, "expected_output": 17, "01": 17, "monthly_spend_t": 17, "often": 18, "involv": 18, "repetit": 18, "streamlin": 18, "By": 18, "reason": 18, "significantli": 18, "reduc": 18, "boilerpl": 18, "especi": 18, "deal": 18, "multipl": [18, 28], "complex": 18, "explor": 18, "effici": 18, "level": [18, 19], "straightforward": 18, "across": [18, 19], "thei": [18, 24], "particularli": 18, "function": 18, "oper": 18, "empti": 18, "overrid": 18, "nala": 18, "No": 18, "accept": 18, "test_queri": [18, 24], "multiplesubscriptionuserst": [18, 24], "up": 18, "demonstr": 18, "safe": 18, "chang": 18, "singl": [18, 24], "rest": 18, "happi": 18, "valid": 18, "syntax": 18, "minim": 18, "subset": 18, "certain": 18, "help": 18, "focu": 18, "numer": 18, "between": 18, "frequent": 18, "new": 18, "prevent": 18, "extens": 18, "refactor": 18, "central": 19, "where": [19, 24, 28], "reus": [19, 28], "goign": 19, "mention": 19, "referenc": 19, "product": 19, "pattern": 19, "schema": 19, "current": 19, "u": 19, "onc": [19, 28], "whatev": [19, 28], "wa": [19, 28], "read": 19, "detail": 19, "handl": 19, "found": 19, "folder": 20, "sql_mock_redshift_host": 23, "sql_mock_redshift_us": 23, "sql_mock_redshift_password": 23, "sql_mock_redshift_port": 23, "check": 24, "given": [24, 28], "normal": 24, "full": 24, "lot": 24, "complic": 24, "bunch": 24, "separ": 24, "abl": 24, "To": 24, "assum": [24, 28], "subscriptions_per_us": 24, "sub": 24, "ON": 24, "users_with_multiple_sub": 24, "now": 24, "test_model": 24, "subscriptions_per_user__expect": 24, "users_with_multiple_subs__expect": 24, "end_result__expect": 24, "end": 24, "walk": 28, "through": 28, "bigquerytablemock": 28, "itself": 28, "advantag": 28, "after": 28, "mani": 28, "overwrid": 28, "sometim": 28, "context": 28, "created_at": 28, "creation_d": 28, "your_input_mock_inst": 28, "09": 28, "05": 28, "automat": 28, "snowflak": [1, 3, 27], "snowflakecolumnmock": 10, "binari": 10, "text": 10, "timestamp_ltz": 10, "timestamp_ntz": 10, "timestamp_tz": 10, "variant": 10, "snowflakeset": 10, "sql_mock_snowflake_": 10, "snowflakemockt": [10, 25], "test_someth": 25, "sql_mock_snowflake_account": 27, "sql_mock_snowflake_us": 27, "sql_mock_snowflake_password": 27}, "objects": {"": [[6, 0, 0, "-", "sql_mock"]], "sql_mock": [[7, 0, 0, "-", "bigquery"], [8, 0, 0, "-", "clickhouse"], [6, 0, 0, "-", "column_mocks"], [6, 0, 0, "-", "constants"], [6, 0, 0, "-", "exceptions"], [9, 0, 0, "-", "redshift"], [10, 0, 0, "-", "snowflake"], [6, 0, 0, "-", "table_mocks"]], "sql_mock.bigquery": [[7, 0, 0, "-", "column_mocks"], [7, 0, 0, "-", "settings"], [7, 0, 0, "-", "table_mocks"]], "sql_mock.bigquery.column_mocks": [[7, 1, 1, "", "Array"], [7, 1, 1, "", "BigQueryColumnMock"], [7, 1, 1, "", "Date"], [7, 1, 1, "", "Decimal"], [7, 1, 1, "", "Float"], [7, 1, 1, "", "Int"], [7, 1, 1, "", "String"]], "sql_mock.bigquery.column_mocks.Array": [[7, 2, 1, "", "use_quotes_for_casting"]], "sql_mock.bigquery.column_mocks.Date": [[7, 2, 1, "", "dtype"]], "sql_mock.bigquery.column_mocks.Float": [[7, 2, 1, "", "dtype"]], "sql_mock.bigquery.column_mocks.Int": [[7, 2, 1, "", "dtype"]], "sql_mock.bigquery.column_mocks.String": [[7, 2, 1, "", "dtype"]], "sql_mock.bigquery.settings": [[7, 1, 1, "", "BigQuerySettings"]], "sql_mock.bigquery.settings.BigQuerySettings": [[7, 2, 1, "", "google_application_credentials"], [7, 2, 1, "", "model_config"], [7, 2, 1, "", "model_fields"]], "sql_mock.bigquery.table_mocks": [[7, 1, 1, "", "BigQueryMockTable"]], "sql_mock.clickhouse": [[8, 0, 0, "-", "column_mocks"], [8, 0, 0, "-", "settings"], [8, 0, 0, "-", "table_mocks"]], "sql_mock.clickhouse.column_mocks": [[8, 1, 1, "", "Array"], [8, 1, 1, "", "Boolean"], [8, 1, 1, "", "ClickhouseColumnMock"], [8, 1, 1, "", "Date"], [8, 1, 1, "", "Datetime"], [8, 1, 1, "", "Datetime64"], [8, 1, 1, "", "Decimal"], [8, 1, 1, "", "Float"], [8, 1, 1, "", "Int"], [8, 1, 1, "", "String"]], "sql_mock.clickhouse.column_mocks.Array": [[8, 2, 1, "", "use_quotes_for_casting"]], "sql_mock.clickhouse.column_mocks.Boolean": [[8, 2, 1, "", "dtype"]], "sql_mock.clickhouse.column_mocks.Date": [[8, 2, 1, "", "dtype"]], "sql_mock.clickhouse.column_mocks.Datetime": [[8, 2, 1, "", "dtype"]], "sql_mock.clickhouse.column_mocks.Datetime64": [[8, 2, 1, "", "dtype"]], "sql_mock.clickhouse.column_mocks.Float": [[8, 2, 1, "", "dtype"]], "sql_mock.clickhouse.column_mocks.Int": [[8, 2, 1, "", "dtype"]], "sql_mock.clickhouse.column_mocks.String": [[8, 2, 1, "", "dtype"]], "sql_mock.clickhouse.settings": [[8, 1, 1, "", "ClickHouseSettings"]], "sql_mock.clickhouse.settings.ClickHouseSettings": [[8, 2, 1, "", "host"], [8, 2, 1, "", "model_config"], [8, 2, 1, "", "model_fields"], [8, 2, 1, "", "password"], [8, 2, 1, "", "port"], [8, 2, 1, "", "user"]], "sql_mock.clickhouse.table_mocks": [[8, 1, 1, "", "ClickHouseTableMock"]], "sql_mock.column_mocks": [[6, 1, 1, "", "ColumnMock"]], "sql_mock.column_mocks.ColumnMock": [[6, 3, 1, "", "cast_field"], [6, 2, 1, "id0", "default"], [6, 2, 1, "id1", "dtype"], [6, 2, 1, "id2", "nullable"], [6, 3, 1, "", "to_sql"], [6, 2, 1, "id3", "use_quotes_for_casting"]], "sql_mock.constants": [[6, 1, 1, "", "NoInput"]], "sql_mock.exceptions": [[6, 4, 1, "", "ValidationError"]], "sql_mock.redshift": [[9, 0, 0, "-", "column_mocks"], [9, 0, 0, "-", "settings"], [9, 0, 0, "-", "table_mocks"]], "sql_mock.redshift.column_mocks": [[9, 1, 1, "", "BIGINT"], [9, 1, 1, "", "BOOLEAN"], [9, 1, 1, "", "CHAR"], [9, 1, 1, "", "DATE"], [9, 1, 1, "", "DECIMAL"], [9, 1, 1, "", "DOUBLE_PRECISION"], [9, 1, 1, "", "GEOGRAPHY"], [9, 1, 1, "", "GEOMETRY"], [9, 1, 1, "", "HLLSKETCH"], [9, 1, 1, "", "INTEGER"], [9, 1, 1, "", "REAL"], [9, 1, 1, "", "RedshiftColumnMock"], [9, 1, 1, "", "SMALLINT"], [9, 1, 1, "", "SUPER"], [9, 1, 1, "", "TIME"], [9, 1, 1, "", "TIMESTAMP"], [9, 1, 1, "", "TIMESTAMPTZ"], [9, 1, 1, "", "TIMETZ"], [9, 1, 1, "", "VARBYTE"], [9, 1, 1, "", "VARCHAR"]], "sql_mock.redshift.column_mocks.BIGINT": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.BOOLEAN": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.CHAR": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.DATE": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.DOUBLE_PRECISION": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.GEOGRAPHY": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.GEOMETRY": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.HLLSKETCH": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.INTEGER": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.REAL": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.SMALLINT": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.SUPER": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.TIME": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.TIMESTAMP": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.TIMESTAMPTZ": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.TIMETZ": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.VARBYTE": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.column_mocks.VARCHAR": [[9, 2, 1, "", "dtype"]], "sql_mock.redshift.settings": [[9, 1, 1, "", "RedshiftSettings"]], "sql_mock.redshift.settings.RedshiftSettings": [[9, 2, 1, "", "database"], [9, 2, 1, "", "host"], [9, 2, 1, "", "model_config"], [9, 2, 1, "", "model_fields"], [9, 2, 1, "", "password"], [9, 2, 1, "", "port"], [9, 2, 1, "", "user"]], "sql_mock.redshift.table_mocks": [[9, 1, 1, "", "RedshiftMockTable"]], "sql_mock.snowflake": [[10, 0, 0, "-", "column_mocks"], [10, 0, 0, "-", "settings"], [10, 0, 0, "-", "table_mocks"]], "sql_mock.snowflake.column_mocks": [[10, 1, 1, "", "ARRAY"], [10, 1, 1, "", "BINARY"], [10, 1, 1, "", "BOOLEAN"], [10, 1, 1, "", "DATE"], [10, 1, 1, "", "DECIMAL"], [10, 1, 1, "", "FLOAT"], [10, 1, 1, "", "GEOGRAPHY"], [10, 1, 1, "", "INTEGER"], [10, 1, 1, "", "OBJECT"], [10, 1, 1, "", "STRING"], [10, 1, 1, "", "SnowflakeColumnMock"], [10, 1, 1, "", "TEXT"], [10, 1, 1, "", "TIME"], [10, 1, 1, "", "TIMESTAMP"], [10, 1, 1, "", "TIMESTAMP_LTZ"], [10, 1, 1, "", "TIMESTAMP_NTZ"], [10, 1, 1, "", "TIMESTAMP_TZ"], [10, 1, 1, "", "VARIANT"]], "sql_mock.snowflake.column_mocks.ARRAY": [[10, 2, 1, "", "dtype"], [10, 2, 1, "", "use_quotes_for_casting"]], "sql_mock.snowflake.column_mocks.BINARY": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.column_mocks.BOOLEAN": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.column_mocks.DATE": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.column_mocks.FLOAT": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.column_mocks.GEOGRAPHY": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.column_mocks.INTEGER": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.column_mocks.OBJECT": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.column_mocks.STRING": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.column_mocks.TEXT": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.column_mocks.TIME": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.column_mocks.TIMESTAMP": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.column_mocks.TIMESTAMP_LTZ": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.column_mocks.TIMESTAMP_NTZ": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.column_mocks.TIMESTAMP_TZ": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.column_mocks.VARIANT": [[10, 2, 1, "", "dtype"]], "sql_mock.snowflake.settings": [[10, 1, 1, "", "SnowflakeSettings"]], "sql_mock.snowflake.settings.SnowflakeSettings": [[10, 2, 1, "", "account"], [10, 2, 1, "", "model_config"], [10, 2, 1, "", "model_fields"], [10, 2, 1, "", "password"], [10, 2, 1, "", "user"]], "sql_mock.snowflake.table_mocks": [[10, 1, 1, "", "SnowflakeMockTable"]], "sql_mock.table_mocks": [[6, 1, 1, "", "BaseMockTable"], [6, 1, 1, "", "MockTableMeta"], [6, 1, 1, "", "SQLMockData"], [6, 6, 1, "", "table_meta"]], "sql_mock.table_mocks.BaseMockTable": [[6, 2, 1, "", "_sql_dialect"], [6, 2, 1, "", "_sql_mock_data"], [6, 3, 1, "", "as_sql_input"], [6, 3, 1, "", "assert_cte_equal"], [6, 3, 1, "", "assert_equal"], [6, 3, 1, "", "from_dicts"], [6, 3, 1, "", "from_mocks"]], "sql_mock.table_mocks.MockTableMeta": [[6, 5, 1, "", "cte_name"], [6, 2, 1, "", "default_inputs"], [6, 2, 1, "", "model_config"], [6, 2, 1, "", "model_fields"], [6, 2, 1, "id4", "query"], [6, 2, 1, "id5", "table_ref"]], "sql_mock.table_mocks.SQLMockData": [[6, 2, 1, "", "columns"], [6, 2, 1, "", "data"], [6, 2, 1, "", "input_data"], [6, 2, 1, "", "last_query"], [6, 2, 1, "", "model_config"], [6, 2, 1, "", "model_fields"], [6, 2, 1, "", "rendered_query"]]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:attribute", "3": "py:method", "4": "py:exception", "5": "py:property", "6": "py:function"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "attribute", "Python attribute"], "3": ["py", "method", "Python method"], "4": ["py", "exception", "Python exception"], "5": ["py", "property", "Python property"], "6": ["py", "function", "Python function"]}, "titleterms": {"faq": 0, "my": 0, "databas": [0, 3], "system": 0, "i": [0, 18], "support": 0, "yet": 0, "want": 0, "us": [0, 17, 18, 28], "sql": [0, 3, 28], "mock": [0, 3, 17, 18, 19], "what": 0, "should": 0, "do": 0, "creat": [0, 17], "your": [0, 17, 28], "mocktabl": [0, 18], "class": 0, "columnmock": 0, "contribut": 0, "setup": [0, 1], "am": 0, "miss": 0, "specif": [0, 3], "type": 0, "model": [0, 17], "field": [0, 18], "instal": 1, "recommend": [1, 28], "pytest": 1, "quickstart": 2, "welcom": 3, "": 3, "document": 3, "get": 3, "start": 3, "basic": 3, "usag": 3, "api": 3, "refer": 3, "indic": 3, "tabl": [3, 17, 19], "sql_mock": [4, 6, 7, 8, 9, 10], "packag": [6, 7, 8, 9, 10], "subpackag": 6, "submodul": [6, 7, 8, 9, 10], "column_mock": [6, 7, 8, 9, 10], "modul": [6, 7, 8, 9, 10], "constant": 6, "except": 6, "table_mock": [6, 7, 8, 9, 10], "content": [6, 7, 8, 9, 10], "bigqueri": [7, 11, 12], "set": [7, 8, 9, 10, 13, 16, 17, 18, 23, 27], "clickhous": [8, 14, 15], "redshift": [9, 21, 22], "exampl": [11, 14, 17, 20, 21, 25], "test": [11, 14, 17, 21, 25, 28], "subscript": [11, 14, 21, 25], "count": [11, 14, 21, 25], "dbt": 17, "introduct": 17, "prerequisit": 17, "configur": 17, "manifest": 17, "path": 17, "sourc": 17, "seed": 17, "upstream": 17, "data": 17, "step": 17, "1": [17, 28], "defin": [17, 19], "2": [17, 28], "3": 17, "write": 17, "case": 17, "default": 18, "valu": 18, "util": 18, "table_meta": [18, 28], "when": 18, "thi": 18, "result": 24, "assert": 24, "queri": 28, "wai": 28, "provid": 28, "option": 28, "decor": 28, "pass": 28, "from_mock": 28, "call": 28, "jinja": 28, "templat": 28, "snowflak": [10, 25, 26]}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 60}, "alltitles": {"Quickstart": [[2, "quickstart"]], "sql_mock": [[4, "sql-mock"]], "Example: Testing Subscription Counts in BigQuery": [[11, "example-testing-subscription-counts-in-bigquery"]], "BigQuery": [[12, "bigquery"]], "Settings": [[13, "settings"], [16, "settings"], [23, "settings"], [27, "settings"]], "Example: Testing Subscription Counts in ClickHouse": [[14, "example-testing-subscription-counts-in-clickhouse"]], "Clickhouse": [[15, "clickhouse"]], "Use with dbt": [[17, "use-with-dbt"]], "Introduction": [[17, "introduction"]], "Prerequisites": [[17, "prerequisites"]], "Configuration": [[17, "configuration"]], "Setting the dbt Manifest Path": [[17, "setting-the-dbt-manifest-path"]], "Creating Mock Tables": [[17, "creating-mock-tables"]], "dbt Model Mock Table": [[17, "dbt-model-mock-table"]], "dbt Source Mock Table": [[17, "dbt-source-mock-table"]], "dbt Seed Mock Table": [[17, "dbt-seed-mock-table"]], "Example: Testing a dbt Model with Upstream Source and Seed Data": [[17, "example-testing-a-dbt-model-with-upstream-source-and-seed-data"]], "Step 1: Define Your Source and Seed Mock Tables": [[17, "step-1-define-your-source-and-seed-mock-tables"]], "Step 2: Define Your Model Mock Table": [[17, "step-2-define-your-model-mock-table"]], "Step 3: Write Your Test Case": [[17, "step-3-write-your-test-case"]], "Default values": [[18, "default-values"]], "Utilizing Default Values in MockTable Fields": [[18, "utilizing-default-values-in-mocktable-fields"]], "Setting Mock Defaults with table_meta": [[18, "setting-mock-defaults-with-table-meta"]], "When is this useful?": [[18, "when-is-this-useful"]], "Defining table mocks": [[19, "defining-table-mocks"]], "Examples": [[20, "examples"]], "Result assertion": [[24, "result-assertion"]], "Your SQL query to test": [[28, "your-sql-query-to-test"]], "Ways to provide your SQL query to be tested": [[28, "ways-to-provide-your-sql-query-to-be-tested"]], "Option 1 (recommended): Use the table_meta decorator": [[28, "option-1-recommended-use-the-table-meta-decorator"]], "Option 2: Pass the query in the .from_mocks call": [[28, "option-2-pass-the-query-in-the-from-mocks-call"]], "Queries with Jinja templates": [[28, "queries-with-jinja-templates"]], "FAQ": [[0, "faq"]], "My database system is not supported yet but I want to use SQL Mock. What should I do?": [[0, "my-database-system-is-not-supported-yet-but-i-want-to-use-sql-mock-what-should-i-do"]], "Create your MockTable class": [[0, "create-your-mocktable-class"]], "Create your ColumnMocks": [[0, "create-your-columnmocks"]], "Contribute your database setup": [[0, "contribute-your-database-setup"]], "I am missing a specific ColumnMock type for my model fields": [[0, "i-am-missing-a-specific-columnmock-type-for-my-model-fields"]], "Installation": [[1, "installation"]], "Recommended Setup for Pytest": [[1, "recommended-setup-for-pytest"]], "Welcome to SQL Mock\u2019s documentation!": [[3, "welcome-to-sql-mock-s-documentation"]], "Getting Started": [[3, null]], "Basic Usage": [[3, null]], "Database Specifics": [[3, null]], "API Reference": [[3, null]], "Indices and tables": [[3, "indices-and-tables"]], "sql_mock package": [[6, "sql-mock-package"]], "Subpackages": [[6, "subpackages"]], "Submodules": [[6, "submodules"], [7, "submodules"], [8, "submodules"], [9, "submodules"], [10, "submodules"]], "sql_mock.column_mocks module": [[6, "module-sql_mock.column_mocks"]], "sql_mock.constants module": [[6, "module-sql_mock.constants"]], "sql_mock.exceptions module": [[6, "module-sql_mock.exceptions"]], "sql_mock.table_mocks module": [[6, "module-sql_mock.table_mocks"]], "Module contents": [[6, "module-sql_mock"], [7, "module-sql_mock.bigquery"], [8, "module-sql_mock.clickhouse"], [9, "module-sql_mock.redshift"], [10, "module-sql_mock.snowflake"]], "sql_mock.bigquery package": [[7, "sql-mock-bigquery-package"]], "sql_mock.bigquery.column_mocks module": [[7, "module-sql_mock.bigquery.column_mocks"]], "sql_mock.bigquery.settings module": [[7, "module-sql_mock.bigquery.settings"]], "sql_mock.bigquery.table_mocks module": [[7, "module-sql_mock.bigquery.table_mocks"]], "sql_mock.clickhouse package": [[8, "sql-mock-clickhouse-package"]], "sql_mock.clickhouse.column_mocks module": [[8, "module-sql_mock.clickhouse.column_mocks"]], "sql_mock.clickhouse.settings module": [[8, "module-sql_mock.clickhouse.settings"]], "sql_mock.clickhouse.table_mocks module": [[8, "module-sql_mock.clickhouse.table_mocks"]], "sql_mock.redshift package": [[9, "sql-mock-redshift-package"]], "sql_mock.redshift.column_mocks module": [[9, "module-sql_mock.redshift.column_mocks"]], "sql_mock.redshift.settings module": [[9, "module-sql_mock.redshift.settings"]], "sql_mock.redshift.table_mocks module": [[9, "module-sql_mock.redshift.table_mocks"]], "sql_mock.snowflake package": [[10, "sql-mock-snowflake-package"]], "sql_mock.snowflake.column_mocks module": [[10, "module-sql_mock.snowflake.column_mocks"]], "sql_mock.snowflake.settings module": [[10, "module-sql_mock.snowflake.settings"]], "sql_mock.snowflake.table_mocks module": [[10, "module-sql_mock.snowflake.table_mocks"]], "Example: Testing Subscription Counts in Redshift": [[21, "example-testing-subscription-counts-in-redshift"]], "Redshift": [[22, "redshift"]], "Example: Testing Subscription Counts in Snowflake": [[25, "example-testing-subscription-counts-in-snowflake"]], "Snowflake": [[26, "snowflake"]]}, "indexentries": {"module": [[3, "module-sql_mock"], [6, "module-sql_mock"], [6, "module-sql_mock.column_mocks"], [6, "module-sql_mock.constants"], [6, "module-sql_mock.exceptions"], [6, "module-sql_mock.table_mocks"], [7, "module-sql_mock.bigquery"], [7, "module-sql_mock.bigquery.column_mocks"], [7, "module-sql_mock.bigquery.settings"], [7, "module-sql_mock.bigquery.table_mocks"], [8, "module-sql_mock.clickhouse"], [8, "module-sql_mock.clickhouse.column_mocks"], [8, "module-sql_mock.clickhouse.settings"], [8, "module-sql_mock.clickhouse.table_mocks"], [9, "module-sql_mock.redshift"], [9, "module-sql_mock.redshift.column_mocks"], [9, "module-sql_mock.redshift.settings"], [9, "module-sql_mock.redshift.table_mocks"], [10, "module-sql_mock.snowflake"], [10, "module-sql_mock.snowflake.column_mocks"], [10, "module-sql_mock.snowflake.settings"], [10, "module-sql_mock.snowflake.table_mocks"]], "sql_mock": [[3, "module-sql_mock"], [6, "module-sql_mock"]], "basemocktable (class in sql_mock.table_mocks)": [[6, "sql_mock.table_mocks.BaseMockTable"]], "columnmock (class in sql_mock.column_mocks)": [[6, "sql_mock.column_mocks.ColumnMock"]], "mocktablemeta (class in sql_mock.table_mocks)": [[6, "sql_mock.table_mocks.MockTableMeta"]], "noinput (class in sql_mock.constants)": [[6, "sql_mock.constants.NoInput"]], "sqlmockdata (class in sql_mock.table_mocks)": [[6, "sql_mock.table_mocks.SQLMockData"]], "validationerror": [[6, "sql_mock.exceptions.ValidationError"]], "_sql_dialect (sql_mock.table_mocks.basemocktable attribute)": [[6, "sql_mock.table_mocks.BaseMockTable._sql_dialect"]], "_sql_mock_data (sql_mock.table_mocks.basemocktable attribute)": [[6, "sql_mock.table_mocks.BaseMockTable._sql_mock_data"]], "as_sql_input() (sql_mock.table_mocks.basemocktable method)": [[6, "sql_mock.table_mocks.BaseMockTable.as_sql_input"]], "assert_cte_equal() (sql_mock.table_mocks.basemocktable method)": [[6, "sql_mock.table_mocks.BaseMockTable.assert_cte_equal"]], "assert_equal() (sql_mock.table_mocks.basemocktable method)": [[6, "sql_mock.table_mocks.BaseMockTable.assert_equal"]], "cast_field() (sql_mock.column_mocks.columnmock method)": [[6, "sql_mock.column_mocks.ColumnMock.cast_field"]], "columns (sql_mock.table_mocks.sqlmockdata attribute)": [[6, "sql_mock.table_mocks.SQLMockData.columns"]], "cte_name (sql_mock.table_mocks.mocktablemeta property)": [[6, "sql_mock.table_mocks.MockTableMeta.cte_name"]], "data (sql_mock.table_mocks.sqlmockdata attribute)": [[6, "sql_mock.table_mocks.SQLMockData.data"]], "default (sql_mock.column_mocks.columnmock attribute)": [[6, "id0"], [6, "sql_mock.column_mocks.ColumnMock.default"]], "default_inputs (sql_mock.table_mocks.mocktablemeta attribute)": [[6, "sql_mock.table_mocks.MockTableMeta.default_inputs"]], "dtype (sql_mock.column_mocks.columnmock attribute)": [[6, "id1"], [6, "sql_mock.column_mocks.ColumnMock.dtype"]], "from_dicts() (sql_mock.table_mocks.basemocktable class method)": [[6, "sql_mock.table_mocks.BaseMockTable.from_dicts"]], "from_mocks() (sql_mock.table_mocks.basemocktable class method)": [[6, "sql_mock.table_mocks.BaseMockTable.from_mocks"]], "input_data (sql_mock.table_mocks.sqlmockdata attribute)": [[6, "sql_mock.table_mocks.SQLMockData.input_data"]], "last_query (sql_mock.table_mocks.sqlmockdata attribute)": [[6, "sql_mock.table_mocks.SQLMockData.last_query"]], "model_config (sql_mock.table_mocks.mocktablemeta attribute)": [[6, "sql_mock.table_mocks.MockTableMeta.model_config"]], "model_config (sql_mock.table_mocks.sqlmockdata attribute)": [[6, "sql_mock.table_mocks.SQLMockData.model_config"]], "model_fields (sql_mock.table_mocks.mocktablemeta attribute)": [[6, "sql_mock.table_mocks.MockTableMeta.model_fields"]], "model_fields (sql_mock.table_mocks.sqlmockdata attribute)": [[6, "sql_mock.table_mocks.SQLMockData.model_fields"]], "nullable (sql_mock.column_mocks.columnmock attribute)": [[6, "id2"], [6, "sql_mock.column_mocks.ColumnMock.nullable"]], "query (sql_mock.table_mocks.mocktablemeta attribute)": [[6, "id4"], [6, "sql_mock.table_mocks.MockTableMeta.query"]], "rendered_query (sql_mock.table_mocks.sqlmockdata attribute)": [[6, "sql_mock.table_mocks.SQLMockData.rendered_query"]], "sql_mock.column_mocks": [[6, "module-sql_mock.column_mocks"]], "sql_mock.constants": [[6, "module-sql_mock.constants"]], "sql_mock.exceptions": [[6, "module-sql_mock.exceptions"]], "sql_mock.table_mocks": [[6, "module-sql_mock.table_mocks"]], "table_meta() (in module sql_mock.table_mocks)": [[6, "sql_mock.table_mocks.table_meta"]], "table_ref (sql_mock.table_mocks.mocktablemeta attribute)": [[6, "id5"], [6, "sql_mock.table_mocks.MockTableMeta.table_ref"]], "to_sql() (sql_mock.column_mocks.columnmock method)": [[6, "sql_mock.column_mocks.ColumnMock.to_sql"]], "use_quotes_for_casting (sql_mock.column_mocks.columnmock attribute)": [[6, "id3"], [6, "sql_mock.column_mocks.ColumnMock.use_quotes_for_casting"]], "array (class in sql_mock.bigquery.column_mocks)": [[7, "sql_mock.bigquery.column_mocks.Array"]], "bigquerycolumnmock (class in sql_mock.bigquery.column_mocks)": [[7, "sql_mock.bigquery.column_mocks.BigQueryColumnMock"]], "bigquerymocktable (class in sql_mock.bigquery.table_mocks)": [[7, "sql_mock.bigquery.table_mocks.BigQueryMockTable"]], "bigquerysettings (class in sql_mock.bigquery.settings)": [[7, "sql_mock.bigquery.settings.BigQuerySettings"]], "date (class in sql_mock.bigquery.column_mocks)": [[7, "sql_mock.bigquery.column_mocks.Date"]], "decimal (class in sql_mock.bigquery.column_mocks)": [[7, "sql_mock.bigquery.column_mocks.Decimal"]], "float (class in sql_mock.bigquery.column_mocks)": [[7, "sql_mock.bigquery.column_mocks.Float"]], "int (class in sql_mock.bigquery.column_mocks)": [[7, "sql_mock.bigquery.column_mocks.Int"]], "string (class in sql_mock.bigquery.column_mocks)": [[7, "sql_mock.bigquery.column_mocks.String"]], "dtype (sql_mock.bigquery.column_mocks.date attribute)": [[7, "sql_mock.bigquery.column_mocks.Date.dtype"]], "dtype (sql_mock.bigquery.column_mocks.float attribute)": [[7, "sql_mock.bigquery.column_mocks.Float.dtype"]], "dtype (sql_mock.bigquery.column_mocks.int attribute)": [[7, "sql_mock.bigquery.column_mocks.Int.dtype"]], "dtype (sql_mock.bigquery.column_mocks.string attribute)": [[7, "sql_mock.bigquery.column_mocks.String.dtype"]], "google_application_credentials (sql_mock.bigquery.settings.bigquerysettings attribute)": [[7, "sql_mock.bigquery.settings.BigQuerySettings.google_application_credentials"]], "model_config (sql_mock.bigquery.settings.bigquerysettings attribute)": [[7, "sql_mock.bigquery.settings.BigQuerySettings.model_config"]], "model_fields (sql_mock.bigquery.settings.bigquerysettings attribute)": [[7, "sql_mock.bigquery.settings.BigQuerySettings.model_fields"]], "sql_mock.bigquery": [[7, "module-sql_mock.bigquery"]], "sql_mock.bigquery.column_mocks": [[7, "module-sql_mock.bigquery.column_mocks"]], "sql_mock.bigquery.settings": [[7, "module-sql_mock.bigquery.settings"]], "sql_mock.bigquery.table_mocks": [[7, "module-sql_mock.bigquery.table_mocks"]], "use_quotes_for_casting (sql_mock.bigquery.column_mocks.array attribute)": [[7, "sql_mock.bigquery.column_mocks.Array.use_quotes_for_casting"]], "array (class in sql_mock.clickhouse.column_mocks)": [[8, "sql_mock.clickhouse.column_mocks.Array"]], "boolean (class in sql_mock.clickhouse.column_mocks)": [[8, "sql_mock.clickhouse.column_mocks.Boolean"]], "clickhousesettings (class in sql_mock.clickhouse.settings)": [[8, "sql_mock.clickhouse.settings.ClickHouseSettings"]], "clickhousetablemock (class in sql_mock.clickhouse.table_mocks)": [[8, "sql_mock.clickhouse.table_mocks.ClickHouseTableMock"]], "clickhousecolumnmock (class in sql_mock.clickhouse.column_mocks)": [[8, "sql_mock.clickhouse.column_mocks.ClickhouseColumnMock"]], "date (class in sql_mock.clickhouse.column_mocks)": [[8, "sql_mock.clickhouse.column_mocks.Date"]], "datetime (class in sql_mock.clickhouse.column_mocks)": [[8, "sql_mock.clickhouse.column_mocks.Datetime"]], "datetime64 (class in sql_mock.clickhouse.column_mocks)": [[8, "sql_mock.clickhouse.column_mocks.Datetime64"]], "decimal (class in sql_mock.clickhouse.column_mocks)": [[8, "sql_mock.clickhouse.column_mocks.Decimal"]], "float (class in sql_mock.clickhouse.column_mocks)": [[8, "sql_mock.clickhouse.column_mocks.Float"]], "int (class in sql_mock.clickhouse.column_mocks)": [[8, "sql_mock.clickhouse.column_mocks.Int"]], "string (class in sql_mock.clickhouse.column_mocks)": [[8, "sql_mock.clickhouse.column_mocks.String"]], "dtype (sql_mock.clickhouse.column_mocks.boolean attribute)": [[8, "sql_mock.clickhouse.column_mocks.Boolean.dtype"]], "dtype (sql_mock.clickhouse.column_mocks.date attribute)": [[8, "sql_mock.clickhouse.column_mocks.Date.dtype"]], "dtype (sql_mock.clickhouse.column_mocks.datetime attribute)": [[8, "sql_mock.clickhouse.column_mocks.Datetime.dtype"]], "dtype (sql_mock.clickhouse.column_mocks.datetime64 attribute)": [[8, "sql_mock.clickhouse.column_mocks.Datetime64.dtype"]], "dtype (sql_mock.clickhouse.column_mocks.float attribute)": [[8, "sql_mock.clickhouse.column_mocks.Float.dtype"]], "dtype (sql_mock.clickhouse.column_mocks.int attribute)": [[8, "sql_mock.clickhouse.column_mocks.Int.dtype"]], "dtype (sql_mock.clickhouse.column_mocks.string attribute)": [[8, "sql_mock.clickhouse.column_mocks.String.dtype"]], "host (sql_mock.clickhouse.settings.clickhousesettings attribute)": [[8, "sql_mock.clickhouse.settings.ClickHouseSettings.host"]], "model_config (sql_mock.clickhouse.settings.clickhousesettings attribute)": [[8, "sql_mock.clickhouse.settings.ClickHouseSettings.model_config"]], "model_fields (sql_mock.clickhouse.settings.clickhousesettings attribute)": [[8, "sql_mock.clickhouse.settings.ClickHouseSettings.model_fields"]], "password (sql_mock.clickhouse.settings.clickhousesettings attribute)": [[8, "sql_mock.clickhouse.settings.ClickHouseSettings.password"]], "port (sql_mock.clickhouse.settings.clickhousesettings attribute)": [[8, "sql_mock.clickhouse.settings.ClickHouseSettings.port"]], "sql_mock.clickhouse": [[8, "module-sql_mock.clickhouse"]], "sql_mock.clickhouse.column_mocks": [[8, "module-sql_mock.clickhouse.column_mocks"]], "sql_mock.clickhouse.settings": [[8, "module-sql_mock.clickhouse.settings"]], "sql_mock.clickhouse.table_mocks": [[8, "module-sql_mock.clickhouse.table_mocks"]], "use_quotes_for_casting (sql_mock.clickhouse.column_mocks.array attribute)": [[8, "sql_mock.clickhouse.column_mocks.Array.use_quotes_for_casting"]], "user (sql_mock.clickhouse.settings.clickhousesettings attribute)": [[8, "sql_mock.clickhouse.settings.ClickHouseSettings.user"]], "bigint (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.BIGINT"]], "boolean (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.BOOLEAN"]], "char (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.CHAR"]], "date (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.DATE"]], "decimal (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.DECIMAL"]], "double_precision (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.DOUBLE_PRECISION"]], "geography (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.GEOGRAPHY"]], "geometry (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.GEOMETRY"]], "hllsketch (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.HLLSKETCH"]], "integer (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.INTEGER"]], "real (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.REAL"]], "redshiftcolumnmock (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.RedshiftColumnMock"]], "redshiftmocktable (class in sql_mock.redshift.table_mocks)": [[9, "sql_mock.redshift.table_mocks.RedshiftMockTable"]], "redshiftsettings (class in sql_mock.redshift.settings)": [[9, "sql_mock.redshift.settings.RedshiftSettings"]], "smallint (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.SMALLINT"]], "super (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.SUPER"]], "time (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.TIME"]], "timestamp (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.TIMESTAMP"]], "timestamptz (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.TIMESTAMPTZ"]], "timetz (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.TIMETZ"]], "varbyte (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.VARBYTE"]], "varchar (class in sql_mock.redshift.column_mocks)": [[9, "sql_mock.redshift.column_mocks.VARCHAR"]], "database (sql_mock.redshift.settings.redshiftsettings attribute)": [[9, "sql_mock.redshift.settings.RedshiftSettings.database"]], "dtype (sql_mock.redshift.column_mocks.bigint attribute)": [[9, "sql_mock.redshift.column_mocks.BIGINT.dtype"]], "dtype (sql_mock.redshift.column_mocks.boolean attribute)": [[9, "sql_mock.redshift.column_mocks.BOOLEAN.dtype"]], "dtype (sql_mock.redshift.column_mocks.char attribute)": [[9, "sql_mock.redshift.column_mocks.CHAR.dtype"]], "dtype (sql_mock.redshift.column_mocks.date attribute)": [[9, "sql_mock.redshift.column_mocks.DATE.dtype"]], "dtype (sql_mock.redshift.column_mocks.double_precision attribute)": [[9, "sql_mock.redshift.column_mocks.DOUBLE_PRECISION.dtype"]], "dtype (sql_mock.redshift.column_mocks.geography attribute)": [[9, "sql_mock.redshift.column_mocks.GEOGRAPHY.dtype"]], "dtype (sql_mock.redshift.column_mocks.geometry attribute)": [[9, "sql_mock.redshift.column_mocks.GEOMETRY.dtype"]], "dtype (sql_mock.redshift.column_mocks.hllsketch attribute)": [[9, "sql_mock.redshift.column_mocks.HLLSKETCH.dtype"]], "dtype (sql_mock.redshift.column_mocks.integer attribute)": [[9, "sql_mock.redshift.column_mocks.INTEGER.dtype"]], "dtype (sql_mock.redshift.column_mocks.real attribute)": [[9, "sql_mock.redshift.column_mocks.REAL.dtype"]], "dtype (sql_mock.redshift.column_mocks.smallint attribute)": [[9, "sql_mock.redshift.column_mocks.SMALLINT.dtype"]], "dtype (sql_mock.redshift.column_mocks.super attribute)": [[9, "sql_mock.redshift.column_mocks.SUPER.dtype"]], "dtype (sql_mock.redshift.column_mocks.time attribute)": [[9, "sql_mock.redshift.column_mocks.TIME.dtype"]], "dtype (sql_mock.redshift.column_mocks.timestamp attribute)": [[9, "sql_mock.redshift.column_mocks.TIMESTAMP.dtype"]], "dtype (sql_mock.redshift.column_mocks.timestamptz attribute)": [[9, "sql_mock.redshift.column_mocks.TIMESTAMPTZ.dtype"]], "dtype (sql_mock.redshift.column_mocks.timetz attribute)": [[9, "sql_mock.redshift.column_mocks.TIMETZ.dtype"]], "dtype (sql_mock.redshift.column_mocks.varbyte attribute)": [[9, "sql_mock.redshift.column_mocks.VARBYTE.dtype"]], "dtype (sql_mock.redshift.column_mocks.varchar attribute)": [[9, "sql_mock.redshift.column_mocks.VARCHAR.dtype"]], "host (sql_mock.redshift.settings.redshiftsettings attribute)": [[9, "sql_mock.redshift.settings.RedshiftSettings.host"]], "model_config (sql_mock.redshift.settings.redshiftsettings attribute)": [[9, "sql_mock.redshift.settings.RedshiftSettings.model_config"]], "model_fields (sql_mock.redshift.settings.redshiftsettings attribute)": [[9, "sql_mock.redshift.settings.RedshiftSettings.model_fields"]], "password (sql_mock.redshift.settings.redshiftsettings attribute)": [[9, "sql_mock.redshift.settings.RedshiftSettings.password"]], "port (sql_mock.redshift.settings.redshiftsettings attribute)": [[9, "sql_mock.redshift.settings.RedshiftSettings.port"]], "sql_mock.redshift": [[9, "module-sql_mock.redshift"]], "sql_mock.redshift.column_mocks": [[9, "module-sql_mock.redshift.column_mocks"]], "sql_mock.redshift.settings": [[9, "module-sql_mock.redshift.settings"]], "sql_mock.redshift.table_mocks": [[9, "module-sql_mock.redshift.table_mocks"]], "user (sql_mock.redshift.settings.redshiftsettings attribute)": [[9, "sql_mock.redshift.settings.RedshiftSettings.user"]], "array (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.ARRAY"]], "binary (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.BINARY"]], "boolean (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.BOOLEAN"]], "date (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.DATE"]], "decimal (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.DECIMAL"]], "float (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.FLOAT"]], "geography (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.GEOGRAPHY"]], "integer (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.INTEGER"]], "object (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.OBJECT"]], "string (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.STRING"]], "snowflakecolumnmock (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.SnowflakeColumnMock"]], "snowflakemocktable (class in sql_mock.snowflake.table_mocks)": [[10, "sql_mock.snowflake.table_mocks.SnowflakeMockTable"]], "snowflakesettings (class in sql_mock.snowflake.settings)": [[10, "sql_mock.snowflake.settings.SnowflakeSettings"]], "text (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.TEXT"]], "time (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.TIME"]], "timestamp (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.TIMESTAMP"]], "timestamp_ltz (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.TIMESTAMP_LTZ"]], "timestamp_ntz (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.TIMESTAMP_NTZ"]], "timestamp_tz (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.TIMESTAMP_TZ"]], "variant (class in sql_mock.snowflake.column_mocks)": [[10, "sql_mock.snowflake.column_mocks.VARIANT"]], "account (sql_mock.snowflake.settings.snowflakesettings attribute)": [[10, "sql_mock.snowflake.settings.SnowflakeSettings.account"]], "dtype (sql_mock.snowflake.column_mocks.array attribute)": [[10, "sql_mock.snowflake.column_mocks.ARRAY.dtype"]], "dtype (sql_mock.snowflake.column_mocks.binary attribute)": [[10, "sql_mock.snowflake.column_mocks.BINARY.dtype"]], "dtype (sql_mock.snowflake.column_mocks.boolean attribute)": [[10, "sql_mock.snowflake.column_mocks.BOOLEAN.dtype"]], "dtype (sql_mock.snowflake.column_mocks.date attribute)": [[10, "sql_mock.snowflake.column_mocks.DATE.dtype"]], "dtype (sql_mock.snowflake.column_mocks.float attribute)": [[10, "sql_mock.snowflake.column_mocks.FLOAT.dtype"]], "dtype (sql_mock.snowflake.column_mocks.geography attribute)": [[10, "sql_mock.snowflake.column_mocks.GEOGRAPHY.dtype"]], "dtype (sql_mock.snowflake.column_mocks.integer attribute)": [[10, "sql_mock.snowflake.column_mocks.INTEGER.dtype"]], "dtype (sql_mock.snowflake.column_mocks.object attribute)": [[10, "sql_mock.snowflake.column_mocks.OBJECT.dtype"]], "dtype (sql_mock.snowflake.column_mocks.string attribute)": [[10, "sql_mock.snowflake.column_mocks.STRING.dtype"]], "dtype (sql_mock.snowflake.column_mocks.text attribute)": [[10, "sql_mock.snowflake.column_mocks.TEXT.dtype"]], "dtype (sql_mock.snowflake.column_mocks.time attribute)": [[10, "sql_mock.snowflake.column_mocks.TIME.dtype"]], "dtype (sql_mock.snowflake.column_mocks.timestamp attribute)": [[10, "sql_mock.snowflake.column_mocks.TIMESTAMP.dtype"]], "dtype (sql_mock.snowflake.column_mocks.timestamp_ltz attribute)": [[10, "sql_mock.snowflake.column_mocks.TIMESTAMP_LTZ.dtype"]], "dtype (sql_mock.snowflake.column_mocks.timestamp_ntz attribute)": [[10, "sql_mock.snowflake.column_mocks.TIMESTAMP_NTZ.dtype"]], "dtype (sql_mock.snowflake.column_mocks.timestamp_tz attribute)": [[10, "sql_mock.snowflake.column_mocks.TIMESTAMP_TZ.dtype"]], "dtype (sql_mock.snowflake.column_mocks.variant attribute)": [[10, "sql_mock.snowflake.column_mocks.VARIANT.dtype"]], "model_config (sql_mock.snowflake.settings.snowflakesettings attribute)": [[10, "sql_mock.snowflake.settings.SnowflakeSettings.model_config"]], "model_fields (sql_mock.snowflake.settings.snowflakesettings attribute)": [[10, "sql_mock.snowflake.settings.SnowflakeSettings.model_fields"]], "password (sql_mock.snowflake.settings.snowflakesettings attribute)": [[10, "sql_mock.snowflake.settings.SnowflakeSettings.password"]], "sql_mock.snowflake": [[10, "module-sql_mock.snowflake"]], "sql_mock.snowflake.column_mocks": [[10, "module-sql_mock.snowflake.column_mocks"]], "sql_mock.snowflake.settings": [[10, "module-sql_mock.snowflake.settings"]], "sql_mock.snowflake.table_mocks": [[10, "module-sql_mock.snowflake.table_mocks"]], "use_quotes_for_casting (sql_mock.snowflake.column_mocks.array attribute)": [[10, "sql_mock.snowflake.column_mocks.ARRAY.use_quotes_for_casting"]], "user (sql_mock.snowflake.settings.snowflakesettings attribute)": [[10, "sql_mock.snowflake.settings.SnowflakeSettings.user"]]}}) \ No newline at end of file diff --git a/docs/sitemap.xml b/docs/sitemap.xml deleted file mode 100644 index 2b36a1a..0000000 --- a/docs/sitemap.xml +++ /dev/null @@ -1,2 +0,0 @@ - -https://deeplcom.github.io/sql-mock/en/faq.htmlhttps://deeplcom.github.io/sql-mock/en/getting_started/installation.htmlhttps://deeplcom.github.io/sql-mock/en/index.htmlhttps://deeplcom.github.io/sql-mock/en/modules.htmlhttps://deeplcom.github.io/sql-mock/en/sql_mock.htmlhttps://deeplcom.github.io/sql-mock/en/sql_mock.bigquery.htmlhttps://deeplcom.github.io/sql-mock/en/sql_mock.clickhouse.htmlhttps://deeplcom.github.io/sql-mock/en/sql_mock.redshift.htmlhttps://deeplcom.github.io/sql-mock/en/sql_mock.snowflake.htmlhttps://deeplcom.github.io/sql-mock/en/usage/redshift/examples.htmlhttps://deeplcom.github.io/sql-mock/en/usage/redshift/index.htmlhttps://deeplcom.github.io/sql-mock/en/usage/redshift/settings.htmlhttps://deeplcom.github.io/sql-mock/en/usage/snowflake/examples.htmlhttps://deeplcom.github.io/sql-mock/en/usage/snowflake/index.htmlhttps://deeplcom.github.io/sql-mock/en/usage/snowflake/settings.htmlhttps://deeplcom.github.io/sql-mock/en/genindex.htmlhttps://deeplcom.github.io/sql-mock/en/py-modindex.htmlhttps://deeplcom.github.io/sql-mock/en/search.html \ No newline at end of file diff --git a/docsource/usage/snowflake/examples.md b/docs/snowflake.md similarity index 75% rename from docsource/usage/snowflake/examples.md rename to docs/snowflake.md index 9979f5f..a294d4d 100644 --- a/docsource/usage/snowflake/examples.md +++ b/docs/snowflake.md @@ -1,8 +1,16 @@ -```{toctree} -:maxdepth: 2 -``` +# Snowflake Docs + +## Settings + +In order to use SQL Mock with Snowflake, you need to provide the following environment variables when you run tests: + +* `SQL_MOCK_SNOWFLAKE_ACCOUNT`: The name of your Snowflake account +* `SQL_MOCK_SNOWFLAKE_USER`: The name of your Snowflake user +* `SQL_MOCK_SNOWFLAKE_PASSWORD`: The password for your Snowflake user + +Having those environment variables enables SQL Mock to connect to your Snowflake instance. -# Example: Testing Subscription Counts in Snowflake +## Example: Testing Subscription Counts in Snowflake ```python import datetime @@ -10,7 +18,7 @@ from sql_mock.snowflake import column_mocks as col from sql_mock.snowflake.table_mocks import SnowflakeTableMock from sql_mock.table_mocks import table_meta -# Define mock tables for your data model that inherit from SnowflakeTableMock +# Define table mocks for your data model that inherit from SnowflakeTableMock @table_meta(table_ref="data.users") class UserTable(SnowflakeTableMock): user_id = col.INTEGER(default=1) diff --git a/docs/sql_mock.bigquery.html b/docs/sql_mock.bigquery.html deleted file mode 100644 index d736b7f..0000000 --- a/docs/sql_mock.bigquery.html +++ /dev/null @@ -1,263 +0,0 @@ - - - - - - - sql_mock.bigquery package — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

sql_mock.bigquery package

-
-

Submodules

-
-
-

sql_mock.bigquery.column_mocks module

-
-
-class sql_mock.bigquery.column_mocks.Array(inner_dtype, default, nullable=False)
-

Bases: BigQueryColumnMock

-
-
-use_quotes_for_casting = False
-
- -
- -
-
-class sql_mock.bigquery.column_mocks.BigQueryColumnMock(default=None, nullable=False)
-

Bases: ColumnMock

-
- -
-
-class sql_mock.bigquery.column_mocks.Date(default=None, nullable=False)
-

Bases: BigQueryColumnMock

-
-
-dtype = 'Date'
-
- -
- -
-
-class sql_mock.bigquery.column_mocks.Decimal(default, precision, scale, nullable=False)
-

Bases: BigQueryColumnMock

-
- -
-
-class sql_mock.bigquery.column_mocks.Float(default=None, nullable=False)
-

Bases: BigQueryColumnMock

-
-
-dtype = 'Float'
-
- -
- -
-
-class sql_mock.bigquery.column_mocks.Int(default=None, nullable=False)
-

Bases: BigQueryColumnMock

-
-
-dtype = 'Integer'
-
- -
- -
-
-class sql_mock.bigquery.column_mocks.String(default=None, nullable=False)
-

Bases: BigQueryColumnMock

-
-
-dtype = 'String'
-
- -
- -
-
-

sql_mock.bigquery.settings module

-
-
-class sql_mock.bigquery.settings.BigQuerySettings(_case_sensitive: bool | None = None, _env_prefix: str | None = None, _env_file: DotenvType | None = PosixPath('.'), _env_file_encoding: str | None = None, _env_nested_delimiter: str | None = None, _secrets_dir: str | Path | None = None, *, google_application_credentials: str)
-

Bases: BaseSettings

-
-
-google_application_credentials: str
-
- -
-
-model_config: ClassVar[SettingsConfigDict] = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'env_file': None, 'env_file_encoding': None, 'env_nested_delimiter': None, 'env_prefix': '', 'extra': 'forbid', 'protected_namespaces': ('model_', 'settings_'), 'secrets_dir': None, 'validate_default': True}
-

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

-
- -
-
-model_fields: ClassVar[dict[str, FieldInfo]] = {'google_application_credentials': FieldInfo(annotation=str, required=True)}
-

Metadata about the fields defined on the model, -mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

-

This replaces Model.__fields__ from Pydantic V1.

-
- -
- -
-
-

sql_mock.bigquery.table_mocks module

-
-
-class sql_mock.bigquery.table_mocks.BigQueryMockTable(*args, **kwargs)
-

Bases: BaseMockTable

-
- -
-
-

Module contents

-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/sql_mock.clickhouse.html b/docs/sql_mock.clickhouse.html deleted file mode 100644 index 65f5811..0000000 --- a/docs/sql_mock.clickhouse.html +++ /dev/null @@ -1,309 +0,0 @@ - - - - - - - sql_mock.clickhouse package — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

sql_mock.clickhouse package

-
-

Submodules

-
-
-

sql_mock.clickhouse.column_mocks module

-
-
-class sql_mock.clickhouse.column_mocks.Array(inner_dtype, default, nullable=False)
-

Bases: ClickhouseColumnMock

-
-
-use_quotes_for_casting = False
-
- -
- -
-
-class sql_mock.clickhouse.column_mocks.Boolean(default, nullable=False)
-

Bases: ClickhouseColumnMock

-
-
-dtype = 'Boolean'
-
- -
- -
-
-class sql_mock.clickhouse.column_mocks.ClickhouseColumnMock(default, nullable=False)
-

Bases: ColumnMock

-
- -
-
-class sql_mock.clickhouse.column_mocks.Date(default, nullable=False)
-

Bases: ClickhouseColumnMock

-
-
-dtype = 'Date'
-
- -
- -
-
-class sql_mock.clickhouse.column_mocks.Datetime(default, nullable=False)
-

Bases: ClickhouseColumnMock

-
-
-dtype = 'Datetime'
-
- -
- -
-
-class sql_mock.clickhouse.column_mocks.Datetime64(default, nullable=False)
-

Bases: ClickhouseColumnMock

-
-
-dtype = 'Datetime64'
-
- -
- -
-
-class sql_mock.clickhouse.column_mocks.Decimal(default, precision, scale, nullable=False)
-

Bases: ClickhouseColumnMock

-
- -
-
-class sql_mock.clickhouse.column_mocks.Float(default, nullable=False)
-

Bases: ClickhouseColumnMock

-
-
-dtype = 'Float'
-
- -
- -
-
-class sql_mock.clickhouse.column_mocks.Int(default, nullable=False)
-

Bases: ClickhouseColumnMock

-
-
-dtype = 'Integer'
-
- -
- -
-
-class sql_mock.clickhouse.column_mocks.String(default, nullable=False)
-

Bases: ClickhouseColumnMock

-
-
-dtype = 'String'
-
- -
- -
-
-

sql_mock.clickhouse.settings module

-
-
-class sql_mock.clickhouse.settings.ClickHouseSettings(_case_sensitive: bool | None = None, _env_prefix: str | None = None, _env_file: DotenvType | None = PosixPath('.'), _env_file_encoding: str | None = None, _env_nested_delimiter: str | None = None, _secrets_dir: str | Path | None = None, *, host: str, user: str, password: str, port: str)
-

Bases: BaseSettings

-
-
-host: str
-
- -
-
-model_config: ClassVar[SettingsConfigDict] = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'env_file': None, 'env_file_encoding': None, 'env_nested_delimiter': None, 'env_prefix': 'SQL_MOCK_CLICKHOUSE_', 'extra': 'forbid', 'protected_namespaces': ('model_', 'settings_'), 'secrets_dir': None, 'validate_default': True}
-

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

-
- -
-
-model_fields: ClassVar[dict[str, FieldInfo]] = {'host': FieldInfo(annotation=str, required=True), 'password': FieldInfo(annotation=str, required=True), 'port': FieldInfo(annotation=str, required=True), 'user': FieldInfo(annotation=str, required=True)}
-

Metadata about the fields defined on the model, -mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

-

This replaces Model.__fields__ from Pydantic V1.

-
- -
-
-password: str
-
- -
-
-port: str
-
- -
-
-user: str
-
- -
- -
-
-

sql_mock.clickhouse.table_mocks module

-
-
-class sql_mock.clickhouse.table_mocks.ClickHouseTableMock(*args, **kwargs)
-

Bases: BaseMockTable

-
- -
-
-

Module contents

-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/sql_mock.html b/docs/sql_mock.html deleted file mode 100644 index 4d51fed..0000000 --- a/docs/sql_mock.html +++ /dev/null @@ -1,600 +0,0 @@ - - - - - - - sql_mock package — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

sql_mock package

-
-

Subpackages

- -
-
-

Submodules

-
-
-

sql_mock.column_mocks module

-
-
-class sql_mock.column_mocks.ColumnMock(default=None, nullable=False)
-

Bases: object

-

Represents a mock column in a database table.

-
-
-dtype
-

The data type of the column.

-
-
Type:
-

str

-
-
-
- -
-
-nullable
-

Indicator whether the column can be null

-
- -
-
-default
-

The default value for the column.

-
- -
-
-use_quotes_for_casting
-

Indicator whether the value needs to be quoted (e.g. in the final cast)

-
-
Type:
-

bool

-
-
-
- -
-
-cast_field(column_name)
-
- -
-
-default = None
-
- -
-
-dtype = None
-
- -
-
-nullable = False
-
- -
-
-to_sql(column_name: str, value=<sql_mock.constants.NoInput object>) str
-
- -
-
-use_quotes_for_casting = True
-
- -
- -
-
-

sql_mock.constants module

-
-
-class sql_mock.constants.NoInput
-

Bases: object

-
- -
-
-

sql_mock.exceptions module

-
-
-exception sql_mock.exceptions.ValidationError
-

Bases: Exception

-
- -
-
-

sql_mock.table_mocks module

-
-
-class sql_mock.table_mocks.BaseMockTable(data: list[dict] = None, sql_mock_data: SQLMockData = None)
-

Bases: object

-

Represents a base class for creating mock database tables for testing. -When inheriting from this class you need to add column attributes for the table you would like to mock - e.g.:

-

col1 = Int(default=1)

-
-
-_sql_mock_data
-

A class that stores data which is for processing. This is automatcially created on instantiation.

-
-
Type:
-

SQLMockData

-
-
-
- -
-
-_sql_dialect
-

The sql dialect that the mock model uses. It will be leveraged by sqlglot.

-
-
Type:
-

str

-
-
-
- -
-
-as_sql_input()
-

Generate a UNION ALL SQL CTE that combines data from all rows.

-
-
Returns:
-

A SQL query that combines data from all rows.

-
-
Return type:
-

str

-
-
-
- -
-
-assert_cte_equal(cte_name, expected: [<class 'dict'>], ignore_missing_keys: bool = False, ignore_order: bool = True, print_query_on_fail: bool = True)
-

Assert that a CTE within the table mock’s query equals the provided expected data.

-
-
Parameters:
-
    -
  • cte_name (str) – Name of the CTE that should be compared against the expected results

  • -
  • expected (list of dicts) – Expected data to compare the class data against

  • -
  • ignore_missing_keys (bool) – If true, the comparison will only happen for the fields that are present in the -list of dictionaries of the expected argument.

  • -
  • ignore_order (bool) – If true, the order of dicts / rows will be ignored for comparison.

  • -
  • print_query_on_fail (bool) – If true, the tested query will be printed to the console output when the test fails.

  • -
-
-
-
- -
-
-assert_equal(expected: [<class 'dict'>], ignore_missing_keys: bool = False, ignore_order: bool = True, print_query_on_fail: bool = True)
-

Assert that the result of the table mock’s query equals the provided expected data.

-
-
Parameters:
-
    -
  • expected (list of dicts) – Expected data to compare the class data against

  • -
  • ignore_missing_keys (bool) – If true, the comparison will only happen for the fields that are present in the -list of dictionaries of the expected argument.

  • -
  • ignore_order (bool) – If true, the order of dicts / rows will be ignored for comparison.

  • -
  • print_query_on_fail (bool) – If true, the tested query will be printed to the console output when the test fails.

  • -
-
-
-
- -
-
-classmethod from_dicts(data: list[dict] = None)
-
- -
-
-classmethod from_mocks(input_data: list[BaseMockTable] = None, query_template_kwargs: dict = None, query: str = None)
-

Instantiate the mock table from input mocks. This runs the tables query with static data provided by the input mocks.

-
-
Parameters:
-
    -
  • input_data – List of MockTable instances that hold static data that should be used as inputs.

  • -
  • query_template_kwargs – Dictionary of Jinja template key-value pairs that should be used to render the query.

  • -
  • query – String of the SQL query that is used to generate the model. Can be a Jinja template. If provided, it overwrites the query on cls._sql_mock_meta.query.

  • -
-
-
-
- -
- -
-
-class sql_mock.table_mocks.MockTableMeta(*, default_inputs: List[BaseMockTable] = None, table_ref: str = None, query: str = None)
-

Bases: BaseModel

-

Class to store static metadata of BaseMockTable instances which is used during processing. -We use this class to avoid collision with field names of the table we want to mock.

-
-
-table_ref
-

String that represents the table reference to the original table.

-
-
Type:
-

string

-
-
-
- -
-
-query
-

Srting of the SQL query (can be in Jinja format).

-
-
Type:
-

string

-
-
-
- -
-
-property cte_name
-
- -
-
-default_inputs: List[BaseMockTable]
-
- -
-
-model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}
-

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

-
- -
-
-model_fields: ClassVar[dict[str, FieldInfo]] = {'default_inputs': FieldInfo(annotation=List[Annotated[BaseMockTable, SkipValidation]], required=False), 'query': FieldInfo(annotation=str, required=False), 'table_ref': FieldInfo(annotation=str, required=False)}
-

Metadata about the fields defined on the model, -mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

-

This replaces Model.__fields__ from Pydantic V1.

-
- -
-
-query: str
-
- -
-
-table_ref: str
-
- -
- -
-
-class sql_mock.table_mocks.SQLMockData(*, columns: dict[str, Type[ColumnMock]] = None, data: list[dict] = None, input_data: list[dict] = None, rendered_query: str = None, last_query: str = None)
-

Bases: BaseModel

-

Class to store data on BaseMockTable instances which is used during processing. -We use this class to avoid collision with field names of the table we want to mock.

-
-
-columns: dict[str, Type[ColumnMock]]
-
- -
-
-data: list[dict]
-
- -
-
-input_data: list[dict]
-
- -
-
-last_query: str
-
- -
-
-model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}
-

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

-
- -
-
-model_fields: ClassVar[dict[str, FieldInfo]] = {'columns': FieldInfo(annotation=dict[str, Type[ColumnMock]], required=False), 'data': FieldInfo(annotation=list[dict], required=False), 'input_data': FieldInfo(annotation=list[dict], required=False), 'last_query': FieldInfo(annotation=str, required=False), 'rendered_query': FieldInfo(annotation=str, required=False)}
-

Metadata about the fields defined on the model, -mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

-

This replaces Model.__fields__ from Pydantic V1.

-
- -
-
-rendered_query: str
-
- -
- -
-
-sql_mock.table_mocks.table_meta(table_ref: str = '', query_path: str = None, query: str = None, default_inputs: ['BaseMockTable'] = None)
-

Decorator that is used to define MockTable metadata

-
-
Parameters:
-
    -
  • table_ref (string) – String that represents the table reference to the original table.

  • -
  • query_path (string) – Path to a SQL query file that should be used to generate the model. Can be a Jinja template. Note only one of query_path or query can be provided.

  • -
  • query (string) – Srting of the SQL query (can be in Jinja format). Note only one of query_path or query can be provided.

  • -
  • default_inputs – List of default input mock instances that serve as default input if no other instance of that class is provided.

  • -
-
-
-
- -
-
-

Module contents

-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/sql_mock.redshift.html b/docs/sql_mock.redshift.html deleted file mode 100644 index bc32e3a..0000000 --- a/docs/sql_mock.redshift.html +++ /dev/null @@ -1,403 +0,0 @@ - - - - - - - sql_mock.redshift package — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

sql_mock.redshift package

-
-

Submodules

-
-
-

sql_mock.redshift.column_mocks module

-
-
-class sql_mock.redshift.column_mocks.BIGINT(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'BIGINT'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.BOOLEAN(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'BOOLEAN'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.CHAR(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'CHAR'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.DATE(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'DATE'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.DECIMAL(default, precision, scale, nullable=False)
-

Bases: RedshiftColumnMock

-
- -
-
-class sql_mock.redshift.column_mocks.DOUBLE_PRECISION(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'DOUBLE PRECISION'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.GEOGRAPHY(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'GEOGRAPHY'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.GEOMETRY(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'GEOMETRY'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.HLLSKETCH(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'HLLSKETCH'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.INTEGER(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'INTEGER'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.REAL(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'REAL'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.RedshiftColumnMock(default=None, nullable=False)
-

Bases: ColumnMock

-
- -
-
-class sql_mock.redshift.column_mocks.SMALLINT(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'SMALLINT'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.SUPER(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'SUPER'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.TIME(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'TIME'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.TIMESTAMP(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'TIMESTAMP'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.TIMESTAMPTZ(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'TIMESTAMPTZ'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.TIMETZ(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'TIMETZ'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.VARBYTE(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'VARBYTE'
-
- -
- -
-
-class sql_mock.redshift.column_mocks.VARCHAR(default=None, nullable=False)
-

Bases: RedshiftColumnMock

-
-
-dtype = 'VARCHAR'
-
- -
- -
-
-

sql_mock.redshift.settings module

-
-
-class sql_mock.redshift.settings.RedshiftSettings(_case_sensitive: bool | None = None, _env_prefix: str | None = None, _env_file: DotenvType | None = PosixPath('.'), _env_file_encoding: str | None = None, _env_nested_delimiter: str | None = None, _secrets_dir: str | Path | None = None, *, host: str, database: str, user: str, password: str = None, port: int = 5439)
-

Bases: BaseSettings

-
-
-database: str
-
- -
-
-host: str
-
- -
-
-model_config: ClassVar[SettingsConfigDict] = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'env_file': None, 'env_file_encoding': None, 'env_nested_delimiter': None, 'env_prefix': 'SQL_MOCK_REDSHIFT_', 'extra': 'forbid', 'protected_namespaces': ('model_', 'settings_'), 'secrets_dir': None, 'validate_default': True}
-

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

-
- -
-
-model_fields: ClassVar[dict[str, FieldInfo]] = {'database': FieldInfo(annotation=str, required=True), 'host': FieldInfo(annotation=str, required=True), 'password': FieldInfo(annotation=str, required=False), 'port': FieldInfo(annotation=int, required=False, default=5439), 'user': FieldInfo(annotation=str, required=True)}
-

Metadata about the fields defined on the model, -mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

-

This replaces Model.__fields__ from Pydantic V1.

-
- -
-
-password: str
-
- -
-
-port: int
-
- -
-
-user: str
-
- -
- -
-
-

sql_mock.redshift.table_mocks module

-
-
-class sql_mock.redshift.table_mocks.RedshiftMockTable(*args, **kwargs)
-

Bases: BaseMockTable

-
- -
-
-

Module contents

-
-
- - -
-
-
- -
- -
-

© Copyright 2023, DeepL, Thomas Schmidt.

-
- - Built with Sphinx using a - theme - provided by Read the Docs. - - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/docs/sql_mock.snowflake.html b/docs/sql_mock.snowflake.html deleted file mode 100644 index f4e8713..0000000 --- a/docs/sql_mock.snowflake.html +++ /dev/null @@ -1,376 +0,0 @@ - - - - - - - sql_mock.snowflake package — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

sql_mock.snowflake package

-
-

Submodules

-
-
-

sql_mock.snowflake.column_mocks module

-
-
-class sql_mock.snowflake.column_mocks.ARRAY(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'ARRAY'
-
- -
-
-use_quotes_for_casting = False
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.BINARY(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'BINARY'
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.BOOLEAN(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'BOOLEAN'
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.DATE(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'DATE'
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.DECIMAL(default, precision, scale, nullable=False)
-

Bases: SnowflakeColumnMock

-
- -
-
-class sql_mock.snowflake.column_mocks.FLOAT(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'FLOAT'
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.GEOGRAPHY(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'GEOGRAPHY'
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.INTEGER(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'INTEGER'
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.OBJECT(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'OBJECT'
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.STRING(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'STRING'
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.SnowflakeColumnMock(default=None, nullable=False)
-

Bases: ColumnMock

-
- -
-
-class sql_mock.snowflake.column_mocks.TEXT(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'TEXT'
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.TIME(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'TIME'
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.TIMESTAMP(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'TIMESTAMP'
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.TIMESTAMP_LTZ(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'TIMESTAMP_LTZ'
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.TIMESTAMP_NTZ(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'TIMESTAMP_NTZ'
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.TIMESTAMP_TZ(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'TIMESTAMP_TZ'
-
- -
- -
-
-class sql_mock.snowflake.column_mocks.VARIANT(default=None, nullable=False)
-

Bases: SnowflakeColumnMock

-
-
-dtype = 'VARIANT'
-
- -
- -
-
-

sql_mock.snowflake.settings module

-
-
-class sql_mock.snowflake.settings.SnowflakeSettings(_case_sensitive: bool | None = None, _env_prefix: str | None = None, _env_file: DotenvType | None = PosixPath('.'), _env_file_encoding: str | None = None, _env_nested_delimiter: str | None = None, _secrets_dir: str | Path | None = None, *, account: str, user: str, password: str)
-

Bases: BaseSettings

-
-
-account: str
-
- -
-
-model_config: ClassVar[SettingsConfigDict] = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'env_file': None, 'env_file_encoding': None, 'env_nested_delimiter': None, 'env_prefix': 'SQL_MOCK_SNOWFLAKE_', 'extra': 'forbid', 'protected_namespaces': ('model_', 'settings_'), 'secrets_dir': None, 'validate_default': True}
-

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

-
- -
-
-model_fields: ClassVar[dict[str, FieldInfo]] = {'account': FieldInfo(annotation=str, required=True), 'password': FieldInfo(annotation=str, required=True), 'user': FieldInfo(annotation=str, required=True)}
-

Metadata about the fields defined on the model, -mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

-

This replaces Model.__fields__ from Pydantic V1.

-
- -
-
-password: str
-
- -
-
-user: str
-
- -
- -
-
-

sql_mock.snowflake.table_mocks module

-
-
-class sql_mock.snowflake.table_mocks.SnowflakeMockTable(*args, **kwargs)
-

Bases: BaseMockTable

-
- -
-
-

Module contents

-
-
- - -
-
-
- -
- -
-

© Copyright 2023, DeepL, Thomas Schmidt.

-
- - Built with Sphinx using a - theme - provided by Read the Docs. - - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/bigquery/examples.html b/docs/usage/bigquery/examples.html deleted file mode 100644 index e31adc3..0000000 --- a/docs/usage/bigquery/examples.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - - - Example: Testing Subscription Counts in BigQuery — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-
-
-

Example: Testing Subscription Counts in BigQuery

-
import datetime
-from sql_mock.bigquery import column_mocks as col
-from sql_mock.bigquery.table_mocks import BigQueryMockTable
-from sql_mock.table_mocks import table_meta
-
-# Define mock tables for your data model that inherit from BigQueryMockTable
-@table_meta(table_ref='data.users')
-class UserTable(BigQueryMockTable):
-    user_id = col.Int(default=1)
-    user_name = col.String(default='Mr. T')
-
-
-@table_meta(table_ref='data.subscriptions')
-class SubscriptionTable(BigQueryMockTable):
-    subscription_id = col.Int(default=1)
-    period_start_date = col.Date(default=datetime.date(2023, 9, 5))
-    period_end_date = col.Date(default=datetime.date(2023, 9, 5))
-    user_id = col.Int(default=1)
-
-
-# Define a mock table for your expected results
-class SubscriptionCountTable(BigQueryMockTable):
-    subscription_count = col.Int(default=1)
-    user_id = col.Int(default=1)
-
-# Your original SQL query
-query = """
-SELECT
-    count(*) AS subscription_count,
-    user_id
-FROM data.users
-LEFT JOIN data.subscriptions USING(user_id)
-GROUP BY user_id
-"""
-
-# Create mock data for the 'data.users' and 'data.subscriptions' tables
-users = UserTable.from_dicts([{'user_id': 1}, {'user_id': 2}])
-subscriptions = SubscriptionTable.from_dicts([
-    {'subscription_id': 1, 'user_id': 1},
-    {'subscription_id': 2, 'user_id': 1},
-    {'subscription_id': 2, 'user_id': 2},
-])
-
-# Define your expected results
-expected = [
-    {'user_id': 1, 'subscription_count': 2}, 
-    {'user_id': 2, 'subscription_count': 1}
-]
-
-# Simulate the SQL query using SQL Mock
-res = SubscriptionCountTable.from_mocks(
-    query=query, 
-    input_data=[users, subscriptions]
-)
-
-# Assert the results
-res.assert_equal(expected)
-
-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/bigquery/index.html b/docs/usage/bigquery/index.html deleted file mode 100644 index 2c56674..0000000 --- a/docs/usage/bigquery/index.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - BigQuery — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

BigQuery

-

This section documents the specifics on how to use SQL Mock with BigQuery

- -
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/bigquery/settings.html b/docs/usage/bigquery/settings.html deleted file mode 100644 index 842441f..0000000 --- a/docs/usage/bigquery/settings.html +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - - Settings — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-
-
-

Settings

-

In order to use sql-mock with BigQuery, ensure you have the GOOGLE_APPLICATION_CREDENTIALS environment variable correctly set to point to a service account file.

-

You need to service account file in order to let SQL Mock connect to BigQuery while running the tests.

-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/clickhouse/examples.html b/docs/usage/clickhouse/examples.html deleted file mode 100644 index f26e851..0000000 --- a/docs/usage/clickhouse/examples.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - - Example: Testing Subscription Counts in ClickHouse — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-
-
-

Example: Testing Subscription Counts in ClickHouse

-
from sql_mock.clickhouse import column_mocks as col
-from sql_mock.clickhouse.table_mocks import ClickHouseTableMock
-from sql_mock.table_mocks import table_meta
-
-# Define mock tables for your data model that inherit from ClickHouseTableMock
-@table_meta(table_ref='data.users')
-class UserTable(ClickHouseTableMock):
-    user_id = col.Int(default=1)
-    user_name = col.String(default="Mr. T")
-
-@table_meta(table_ref='data.subscriptions')
-class SubscriptionTable(ClickHouseTableMock):
-    subscription_id = col.Int(default=1)
-    period_start_date = col.Date(default=datetime.date(2023, 9, 5))
-    period_end_date = col.Date(default=datetime.date(2023, 9, 5))
-    user_id = col.Int(default=1)
-
-# Define a mock table for your expected results
-class SubscriptionCountTable(ClickHouseTableMock):
-    subscription_count = col.Int(default=1)
-    user_id = col.Int(default=1)
-
-# Your original SQL query
-query = """
-SELECT
-    count(*) AS subscription_count,
-    user_id
-FROM data.users
-LEFT JOIN data.subscriptions USING(user_id)
-GROUP BY user_id
-"""
-
-# Create mock data for the 'data.users' and 'data.subscriptions' tables
-users = UserTable.from_dicts([{'user_id': 1}, {'user_id': 2}])
-subscriptions = SubscriptionTable.from_dicts([
-    {'subscription_id': 1, 'user_id': 1},
-    {'subscription_id': 2, 'user_id': 1},
-    {'subscription_id': 2, 'user_id': 2},
-])
-
-# Define your expected results
-expected = [
-    {'user_id': 1, 'subscription_count': 2}, 
-    {'user_id': 2, 'subscription_count': 1}
-]
-
-# Simulate the SQL query using SQL Mock
-res = SubscriptionCountTable.from_mocks(query=query, input_data=[users, subscriptions])
-
-# Assert the results
-res.assert_equal(expected)
-
-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/clickhouse/index.html b/docs/usage/clickhouse/index.html deleted file mode 100644 index 0ab1138..0000000 --- a/docs/usage/clickhouse/index.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - Clickhouse — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

Clickhouse

-

This section documents the specifics on how to use SQL Mock with Clickhouse

- -
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/clickhouse/settings.html b/docs/usage/clickhouse/settings.html deleted file mode 100644 index 9676175..0000000 --- a/docs/usage/clickhouse/settings.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - - Settings — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-
-
-

Settings

-

In order to use SQL Mock with Clickhouse, you need to provide the following environment variables when you run tests:

-
    -
  • SQL_MOCK_CLICKHOUSE_HOST: Host of your Clickhouse instance

  • -
  • SQL_MOCK_CLICKHOUSE_USER: User you want to use for the connection

  • -
  • SQL_MOCK_CLICKHOUSE_PASSWORD: Password of your user

  • -
  • SQL_MOCK_CLICKHOUSE_PORT: Port of your Clickhouse instance

  • -
-

Having those environment variables enables SQL Mock to connect to your Clickhouse instance.

-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/dbt.html b/docs/usage/dbt.html deleted file mode 100644 index 22b8cd5..0000000 --- a/docs/usage/dbt.html +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - - Use with dbt — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

Use with dbt

-
-

Introduction

-

This guide will provide a quick start on how to use SQLMock with dbt (data build tool). You can use it to mock dbt models, sources, and seed models. We’ll cover how to use these features effectively in your unit tests.

-
-
-

Prerequisites

-
    -
  • A working dbt project with a manifest.json file that has the latest compiled run. (make sure to run dbt compile).

  • -
  • The SQLMock library installed in your Python environment.

  • -
-
-
-

Configuration

-
-

Setting the dbt Manifest Path

-

Initialize your testing environment by setting the global path to your dbt manifest file:

-
from sql_mock.config import SQLMockConfig
-
-SQLMockConfig.set_dbt_manifest_path('/path/to/your/dbt/manifest.json')
-
-
-
-
-
-

Creating Mock Tables

-

SQLMock offers specialized decorators for different dbt entities: models, sources, and seeds.

-
-

dbt Model Mock Table

-

For dbt models, use the dbt_model_meta decorator from sql_mock.dbt. This decorator is suited for mocking the transformed data produced by dbt models.

-
from sql_mock.dbt import dbt_model_meta
-from sql_mock.bigquery.table_mocks import BigQueryMockTable
-
-@dbt_model_meta(model_name="your_dbt_model_name")
-class YourDBTModelTable(BigQueryMockTable):
-    # Define your table columns and other necessary attributes here
-    ...
-
-
-
-
-

dbt Source Mock Table

-

For dbt sources, use the dbt_source_meta decorator from sql_mock.dbt. This is ideal for mocking the raw data sources that dbt models consume.

-
from sql_mock.dbt import dbt_source_meta
-from sql_mock.bigquery.table_mocks import BigQueryMockTable
-
-@dbt_source_meta(source_name="your_source_name", table_name="your_source_table")
-class YourDBTSourceTable(BigQueryMockTable):
-    # Define your table columns and other necessary attributes here
-    ...
-
-
-
-
-

dbt Seed Mock Table

-

For dbt seeds, which are static data sets loaded into the database, use the dbt_seed_meta decorator from sql_mock.dbt.

-
from sql_mock.dbt import dbt_seed_meta
-from sql_mock.bigquery.table_mocks import BigQueryMockTable
-
-@dbt_seed_meta(seed_name="your_dbt_seed_name")
-class YourDBTSeedTable(BigQueryMockTable):
-    # Define your table columns and other necessary attributes here
-    ...
-
-
-
-
-
-

Example: Testing a dbt Model with Upstream Source and Seed Data

-

Let’s consider a dbt model named monthly_user_spend that aggregates data from a source user_transactions and a seed user_categories.

-
-

Step 1: Define Your Source and Seed Mock Tables

-
@dbt_source_meta(source_name="transactions", table_name="user_transactions")
-class UserTransactionsTable(BigQueryMockTable):
-    transaction_id = col.Int(default=1)
-    user_id = col.Int(default=1)
-    amount = col.Float(default=1.0)
-    transaction_date = col.Date(default='2023-12-24')
-
-@dbt_seed_meta(seed_name="user_categories")
-class UserCategoriesTable(BigQueryMockTable):
-    user_id = col.Int(default=1)
-    category = col.String(default='foo')
-
-
-
-
-

Step 2: Define Your Model Mock Table

-
@dbt_model_meta(model_name="monthly_user_spend")
-class MonthlyUserSpendTable(BigQueryMockTable):
-    user_id = col.Int(default=1)
-    month = col.String(default='foo')
-    total_spend = col.Float(default=1.0)
-    category = col.String(default='foo')
-
-
-
-
-

Step 3: Write Your Test Case

-
import datetime
-
-def test_monthly_user_spend_model():
-    # Mock input data for UserTransactionsTable and UserCategoriesTable
-    transactions_data = [
-        {"transaction_id": 1, "user_id": 1, "amount": 120.0, "transaction_date": datetime.date(2023, 1, 10)},
-        {"transaction_id": 2, "user_id": 2, "amount": 150.0, "transaction_date": datetime.date(2023, 1, 20)},
-    ]
-
-    categories_data = [
-        {"user_id": 1, "category": "Premium"},
-        {"user_id": 2, "category": "Standard"}
-    ]
-
-    transactions_table = UserTransactionsTable.from_dicts(transactions_data)
-    categories_table = UserCategoriesTable.from_dicts(categories_data)
-
-    # Expected result
-    expected_output = [
-        {"user_id": 1, "month": "2023-01", "total_spend": 120.0, "category": "Premium"},
-        {"user_id": 2, "month": "2023-01", "total_spend": 150.0, "category": "Standard"},
-    ]
-
-    monthly_spend_table = MonthlyUserSpendTable.from_mocks(input_data=[transactions_table, categories_table])
-
-    monthly_spend_table.assert_equal(expected_output)
-
-
-
-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/default_values.html b/docs/usage/default_values.html deleted file mode 100644 index 178edab..0000000 --- a/docs/usage/default_values.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - - Default values — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-
-
-

Default values

-

Testing SQL queries can often involve repetitive setup for mock tables. In SQLMock, one effective way to streamline this process is by using default values. By setting reasonable defaults, you can significantly reduce the boilerplate code in your tests, especially when dealing with multiple input tables or complex queries. Let’s explore how you can efficiently implement this.

-
-

Utilizing Default Values in MockTable Fields

-

Defining default values at the field level in your mock tables is straightforward. -The default argument in the field definition allows you to set default values consistency across all test scenarios in one step. -They are particularly useful for ensuring that joins and other query functionalities operate correctly.

-

Here’s an example:

-
@table_meta(table_ref="data.users")
-class UserTable(BigQueryMockTable):
-    user_id = col.Int(default=1)
-    user_name = col.String(default="Mr. T")
-
-# Create instances of the UserTable with various combinations of defaults and specified values
-users = UserTable.from_dicts([
-    {}, # Left empty {} uses default values --> {"user_id": 1, "user_name": "Mr. T"}
-    {"user_id": 2}, # Overrides user_id but uses default for user_name
-    {"user_id": 3, "user_name": "Nala"} # No defaults used here
-])
-
-
-
-
-

Setting Mock Defaults with table_meta

-

When defining your MockTable classes, the table_meta decorator accepts a default_inputs argument. -The Mock instances passed here, will be used as defaults in the from_mocks method.

-

Consider this example:

-
@table_meta(
-    query_path="./examples/test_query.sql",
-    default_inputs=[UserTable([]), SubscriptionTable([])] # We can provide defaults for the class if needed.
-)
-class MultipleSubscriptionUsersTable(BigQueryMockTable):
-    user_id = col.Int(default=1)
-
-# Setting up different scenarios to demonstrate the use of defaults
-users = UserTable.from_dicts([
-    {"user_id": 1}, 
-    {"user_id": 2}
-])
-subscriptions = SubscriptionTable.from_dicts(
-    [
-        {"subscription_id": 1, "user_id": 1},
-        {"subscription_id": 2, "user_id": 1},
-        {"subscription_id": 2, "user_id": 2},
-    ]
-)
-
-# Utilizing the default inputs set in the table_meta
-res = MultipleSubscriptionUsersTable.from_mocks(input_data=[])
-res = MultipleSubscriptionUsersTable.from_mocks(input_data=[users]) # Using only users, defaults for others
-res = MultipleSubscriptionUsersTable.from_mocks(input_data=[users, subscriptions]) # Overriding defaults
-
-
-
-
-

When is this useful?

-
    -
  • Safe time and code by changing only the data you need for your test case: You can only change single columns for the data you provide for a test case. The rest will be filled by defaults.

  • -
  • Simplifying Happy Path Testing: Validate basic functionality and syntax correctness of your SQL queries with minimal setup.

  • -
  • Testing Subset Logic: When certain tables in your query don’t require data, default values can help focus on specific test scenarios.

  • -
  • Provide reasonable defaults for joins: In tests with numerous input tables you can specify inputs that joins between tables work. For frequent addition of new tables, defaults can prevent the need for extensive refactoring.

  • -
-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/defining_table_mocks.html b/docs/usage/defining_table_mocks.html deleted file mode 100644 index 552f945..0000000 --- a/docs/usage/defining_table_mocks.html +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - - Defining table mocks — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-
-
-

Defining table mocks

-

When you want to provide mocked data to test your SQL model, you need to create MockTable classes for all upstream data that your model uses, as well as for the model you want to test. Those mock tables can be created by inheriting from a BaseMockTable class for the database provider you are using (e.g. BigQueryMockTable).

-

We recommend to have a central model.py file where you create those models that you can easily reuse them across your tests

-
# models.py
-
-from sql_mock.bigquery import column_mocks as col
-from sql_mock.bigquery.table_mocks import BigQueryMockTable, table_meta
-
-# The models you are goign to use as inputs need to have a `table_ref` specified
-@table_meta(table_ref='data.table1')
-class Table(BigQueryMockTable):
-    id = col.Int(default=1)
-    name = col.String(default='Peter')
-
-@table_meta(
-    table_ref='data.result_table', 
-    query_path='path/to/query_for_result_table.sql', 
-    default_inputs=[Table()] # You can provide default inputs on a class level
-)
-class ResultTable(BigQueryMockTable):
-    id = col.Int(default=1)
-
-
-

Some important things to mention:

-

The models you are goign to use as inputs need to have a table_ref specified. -The table_ref is how the table will be referenced in your production database (usually some pattern like <schema>.<table>)

-

The result model needs to have a query. -There are currently 2 ways to provide a query to the model:

-
    -
  1. Pass a path to your query file in the class definition using the table_meta decorator. This allows us to only specify it once.

    -
    @table_meta(table_ref='data.result_table', query_path='path/to/query_for_result_table.sql')
    -class ResultTable(BigQueryMockTable):
    -    ...
    -
    -
    -
  2. -
  3. Pass it as query argument to the from_mocks method when you are using the model in your test. This will also overwrite whatever query was read from the query_path in the table_meta decorator.

    -
    res = ResultTable.from_mocks(query='SELECT 1', input_data=[<your-input-mocks-table-instances>])
    -
    -
    -
  4. -
-

More details on how to handle queries can be found in the “Your SQL query to test” section

-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/examples.html b/docs/usage/examples.html deleted file mode 100644 index 9d890b4..0000000 --- a/docs/usage/examples.html +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - - Examples — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-
-
-

Examples

-

You can find some examples in the examples folder.

-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/redshift/examples.html b/docs/usage/redshift/examples.html deleted file mode 100644 index cc3bb3c..0000000 --- a/docs/usage/redshift/examples.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - - Example: Testing Subscription Counts in Redshift — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-
-
-

Example: Testing Subscription Counts in Redshift

-
import datetime
-from sql_mock.redshift import column_mocks as col
-from sql_mock.redshift.table_mocks import RedshiftMockTable
-from sql_mock.table_mocks import table_meta
-
-# Define mock tables for your data model that inherit from RedshiftMockTable
-@table_meta(table_ref="data.users")
-class UserTable(RedshiftMockTable):
-    user_id = col.INTEGER(default=1)
-    user_name = col.VARCHAR(default="Mr. T")
-
-
-@table_meta(table_ref="data.subscriptions")
-class SubscriptionTable(RedshiftMockTable):
-    subscription_id = col.INTEGER(default=1)
-    period_start_date = col.DATE(default=datetime.date(2023, 9, 5))
-    period_end_date = col.DATE(default=datetime.date(2023, 9, 5))
-    user_id = col.INTEGER(default=1)
-
-# Define a mock table for your expected results
-class SubscriptionCountTable(RedshiftMockTable):
-    subscription_count = col.INTEGER(default=1)
-    user_id = col.INTEGER(default=1)
-
-# Your original SQL query
-query = """
-SELECT
-    count(*) AS subscription_count,
-    user_id
-FROM data.users
-LEFT JOIN data.subscriptions USING(user_id)
-GROUP BY user_id
-"""
-
-# Create mock data for the 'data.users' and 'data.subscriptions' tables
-users = UserTable.from_dicts([{'user_id': 1}, {'user_id': 2}])
-subscriptions = SubscriptionTable.from_dicts([
-    {'subscription_id': 1, 'user_id': 1},
-    {'subscription_id': 2, 'user_id': 1},
-    {'subscription_id': 2, 'user_id': 2},
-])
-
-# Define your expected results
-expected = [
-    {'user_id': 1, 'subscription_count': 2},
-    {'user_id': 2, 'subscription_count': 1}
-]
-
-# Simulate the SQL query using SQL Mock
-res = SubscriptionCountTable.from_mocks(query=query, input_data=[users, subscriptions])
-
-# Assert the results
-res.assert_equal(expected)
-
-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/redshift/index.html b/docs/usage/redshift/index.html deleted file mode 100644 index 31ec563..0000000 --- a/docs/usage/redshift/index.html +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - - Redshift — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

Redshift

-

This section documents the specifics on how to use SQL Mock with Redshift

- -
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/redshift/settings.html b/docs/usage/redshift/settings.html deleted file mode 100644 index b75d5a3..0000000 --- a/docs/usage/redshift/settings.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - Settings — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-
-
-

Settings

-

In order to use SQL Mock with Redshift, you need to provide the following environment variables when you run tests:

-
    -
  • SQL_MOCK_REDSHIFT_HOST: The host of your Redshift instance

  • -
  • SQL_MOCK_REDSHIFT_USER: The user of your Redshift instance

  • -
  • SQL_MOCK_REDSHIFT_PASSWORD: The password of your Redshift instance

  • -
  • SQL_MOCK_REDSHIFT_PORT: The port of your Redshift instance

  • -
-

Having those environment variables enables SQL Mock to connect to your Redshift instance.

-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/result_assertion.html b/docs/usage/result_assertion.html deleted file mode 100644 index 4c2e7f0..0000000 --- a/docs/usage/result_assertion.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - - - - Result assertion — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-
-
-

Result assertion

-

There are 2 ways how you can check the output of your query given the mocked input data on your Table Mock instance:

-
    -
  1. assert_equal method: Assert the normal result of the query (running the full query with your input mocks)

  2. -
  3. assert_cte_equal method: Assert the result of a CTE in your query. A lot of times when we built more complicated data models, they include a bunch of CTEs that map to separate logical steps. In those cases, when we unit test our models, we want to be able to not only check the final result but also the single steps. To do this, you can use the assert_cte_equal method.

  4. -
-

Let’s assume we have the following query:

-
WITH subscriptions_per_user AS (
-    SELECT
-        count(sub.user_id) AS subscription_count,
-        users.user_id
-    FROM data.users AS users
-    LEFT JOIN data.subscriptions AS sub ON sub.user_id = users.user_id
-    GROUP BY user_id
-),
-
-users_with_multiple_subs AS (
-    SELECT 
-        *
-    FROM subscriptions_per_user
-    WHERE subscription_count >= 2
-)
-
-SELECT user_id FROM users_with_multiple_subs
-
-
-

… and we define the following mock tables:

-
import datetime
-
-from sql_mock.bigquery import column_mocks as col
-from sql_mock.bigquery.table_mocks import BigQueryMockTable
-from sql_mock.table_mocks import table_meta
-
-@table_meta(table_ref="data.users")
-class UserTable(BigQueryMockTable):
-    user_id = col.Int(default=1)
-    user_name = col.String(default="Mr. T")
-
-
-@table_meta(table_ref="data.subscriptions")
-class SubscriptionTable(BigQueryMockTable):
-    subscription_id = col.Int(default=1)
-    period_start_date = col.Date(default=datetime.date(2023, 9, 5))
-    period_end_date = col.Date(default=datetime.date(2023, 9, 5))
-    user_id = col.Int(default=1)
-
-
-@table_meta(query_path="./examples/test_query.sql")
-class MultipleSubscriptionUsersTable(BigQueryMockTable):
-    user_id = col.Int(default=1)
-
-
-

Now we can use the different testing methods the following way:

-
def test_model():
-    users = UserTable.from_dicts([{"user_id": 1}, {"user_id": 2}])
-    subscriptions = SubscriptionTable.from_dicts(
-        [
-            {"subscription_id": 1, "user_id": 1},
-            {"subscription_id": 2, "user_id": 1},
-            {"subscription_id": 2, "user_id": 2},
-        ]
-    )
-
-    subscriptions_per_user__expected = [{"user_id": 1, "subscription_count": 2}, {"user_id": 2, "subscription_count": 1}]
-    users_with_multiple_subs__expected = [{"user_id": 1, "subscription_count": 2}]
-    end_result__expected = [{"user_id": 1}]
-
-    res = MultipleSubscriptionUsersTable.from_mocks(input_data=[users, subscriptions])
-
-    # Check the results of the subscriptions_per_user CTE
-    res.assert_cte_equal('subscriptions_per_user', subscriptions_per_user__expected)
-    # Check the results of the users_with_multiple_subs CTE
-    res.assert_cte_equal('users_with_multiple_subs', users_with_multiple_subs__expected)
-    # Check the end result
-    res.assert_equal(end_result__expected)
-
-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/snowflake/examples.html b/docs/usage/snowflake/examples.html deleted file mode 100644 index 467b936..0000000 --- a/docs/usage/snowflake/examples.html +++ /dev/null @@ -1,196 +0,0 @@ - - - - - - - Example: Testing Subscription Counts in Snowflake — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-
-
-

Example: Testing Subscription Counts in Snowflake

-
import datetime
-from sql_mock.snowflake import column_mocks as col
-from sql_mock.snowflake.table_mocks import SnowflakeMockTable
-from sql_mock.table_mocks import table_meta
-
-# Define mock tables for your data model that inherit from SnowflakeMockTable
-@table_meta(table_ref="data.users")
-class UserTable(SnowflakeMockTable):
-    user_id = col.INTEGER(default=1)
-    user_name = col.STRING(default="Mr. T")
-
-
-@table_meta(table_ref="data.subscriptions")
-class SubscriptionTable(SnowflakeMockTable):
-    subscription_id = col.INTEGER(default=1)
-    period_start_date = col.DATE(default=datetime.date(2023, 9, 5))
-    period_end_date = col.DATE(default=datetime.date(2023, 9, 5))
-    user_id = col.INTEGER(default=1)
-
-
-# Define a mock table for your expected results
-class SubscriptionCountTable(SnowflakeMockTable):
-    subscription_count = col.INTEGER(default=1)
-    user_id = col.INTEGER(default=1)
-
-# Your original SQL query
-query = """
-SELECT
-    count(*) AS subscription_count,
-    user_id
-FROM data.users
-LEFT JOIN data.subscriptions USING(user_id)
-GROUP BY user_id
-"""
-
-def test_something():
-  # Create mock data for the 'data.users' and 'data.subscriptions' tables
-  users = UserTable.from_dicts([{'user_id': 1}, {'user_id': 2}])
-  subscriptions = SubscriptionTable.from_dicts([
-      {'subscription_id': 1, 'user_id': 1},
-      {'subscription_id': 2, 'user_id': 1},
-      {'subscription_id': 2, 'user_id': 2},
-  ])
-
-  # Define your expected results
-  expected = [
-      {"USER_ID": 1, "SUBSCRIPTION_COUNT": 2},
-      {"USER_ID": 2, "SUBSCRIPTION_COUNT": 1},
-  ]
-
-  # Simulate the SQL query using SQL Mock
-  res = SubscriptionCountTable.from_mocks(query=query, input_data=[users, subscriptions])
-
-  # Assert the results
-  res.assert_equal(expected)
-
-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/snowflake/index.html b/docs/usage/snowflake/index.html deleted file mode 100644 index 726bda3..0000000 --- a/docs/usage/snowflake/index.html +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - - Snowflake — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

Snowflake

-

This section documents the specifics on how to use SQL Mock with Snowflake

- -
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/snowflake/settings.html b/docs/usage/snowflake/settings.html deleted file mode 100644 index 3cfee40..0000000 --- a/docs/usage/snowflake/settings.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - - Settings — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-
-
-

Settings

-

In order to use SQL Mock with Snowflake, you need to provide the following environment variables when you run tests:

-
    -
  • SQL_MOCK_SNOWFLAKE_ACCOUNT: The name of your Snowflake account

  • -
  • SQL_MOCK_SNOWFLAKE_USER: The name of your Snowflake user

  • -
  • SQL_MOCK_SNOWFLAKE_PASSWORD: The password for your Snowflake user

  • -
-

Having those environment variables enables SQL Mock to connect to your Snowflake instance.

-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/usage/your_sql_query_to_test.html b/docs/usage/your_sql_query_to_test.html deleted file mode 100644 index 6bb84d3..0000000 --- a/docs/usage/your_sql_query_to_test.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - - Your SQL query to test — SQL Mock 0.3.0 documentation - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

Your SQL query to test

-

There are multiple ways on how you can provide the SQL query that you want to test. Let’s walk through them and also cover some specifics.

-
-

Ways to provide your SQL query to be tested

- -
-

Option 2: Pass the query in the .from_mocks call

-

You can also pass your query in your test case when you call the from_mocks method.

-
res = ResultTable.from_mocks(query='SELECT 1', input_data=[<your-input-mocks-table-instances>])
-
-
-

Note that this will overwride whatever was specified by using the table_meta decorator.

-
-
-
-

Queries with Jinja templates

-

Sometimes we need to test queries that use jinja templates (e.g. for dbt). -In those cases, you can provide the necessary context for rendering your query using the from_mocks call.

-

Example:

-

Let’s assume the following jinja template query:

-
SELECT * FROM data.users 
-WHERE created_at > {{ creation_date }}
-
-
-

We can provide the creation_date variable in a dictionary using the query_template_kwargs argument:

-
res = ResultTable.from_mocks(input_data=[your_input_mock_instances], query_template_kwargs={'creation_date': '2023-09-05'})
-
-
-

This will automatically render your query using the given input.

-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/docsource/usage/your_sql_query_to_test.md b/docs/your_sql_query_to_test.md similarity index 98% rename from docsource/usage/your_sql_query_to_test.md rename to docs/your_sql_query_to_test.md index e662f95..2fc6f18 100644 --- a/docsource/usage/your_sql_query_to_test.md +++ b/docs/your_sql_query_to_test.md @@ -27,7 +27,7 @@ The advantage of that option is that you only need to define your Table Mock cla You can also pass your query in your test case when you call the `from_mocks` method. -```python +```python res = ResultTable.from_mocks(query='SELECT 1', input_data=[]) ``` @@ -43,7 +43,7 @@ In those cases, you can provide the necessary context for rendering your query u Let's assume the following jinja template query: ```jinja -SELECT * FROM data.users +SELECT * FROM data.users WHERE created_at > {{ creation_date }} ``` diff --git a/docsource/.nojekyll b/docsource/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/docsource/conf.py b/docsource/conf.py deleted file mode 100644 index 999482f..0000000 --- a/docsource/conf.py +++ /dev/null @@ -1,57 +0,0 @@ -import os -import sys - -sys.path.insert(0, os.path.abspath("../src")) - -# Configuration file for the Sphinx documentation builder. -# -# For the full list of built-in configuration values, see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Project information ----------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information - -project = "SQL Mock" -copyright = "2023, DeepL, Thomas Schmidt" -author = "DeepL, Thomas Schmidt" -release = "0.3.0" - -# -- General configuration --------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration - -extensions = ["sphinx.ext.autodoc", "sphinx.ext.autosummary", "sphinx.ext.napoleon", "myst_parser", "sphinx_sitemap"] - -templates_path = ["_templates"] -exclude_patterns = [] -source_suffix = { - ".rst": "restructuredtext", - ".txt": "markdown", - ".md": "markdown", -} - - -autodoc_inherit_docstrings = True -autosummary_generate = True - -# -- Options for HTML output ------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output - -html_theme = "sphinx_rtd_theme" -html_static_path = ["_static"] -html_extra_path = ["_static"] -html_sidebars = { - "**": [ - "globaltoc.html", - "relations.html", # needs 'show_related': True option to display - "sourcelink.html", - "searchbox.html", - ] -} -html_context = { - "display_github": True, # Integrate GitHub - "github_user": "DeepLcom", # Username - "github_repo": "sql-mock", # Repo name - "github_version": "master", # Version - "conf_py_path": "/docsource/", # Path in the checkout to the docs root -} -html_baseurl = "https://deeplcom.github.io/sql-mock/" diff --git a/docsource/faq.md b/docsource/faq.md deleted file mode 100644 index b306d16..0000000 --- a/docsource/faq.md +++ /dev/null @@ -1,61 +0,0 @@ - -# FAQ - -## My database system is not supported yet but I want to use SQL Mock. What should I do? - -We are planning to add more and more supported database systems. However, if your system is not supported yet, you can still use SQL Mock. There are only 2 things you need to do: - -### Create your `TableMock` class - -First, you need to create a `TableMock` class for your database system that inherits from `sql_mock.table_mocks.BaseTableMock`. - -That class needs to implement the `_get_results` method which should make sure to fetch the results of a query (e.g. produced by `self._generate_query()`) and return it as list of dictionaries. - -Look at one of the existing client libraries to see how this could work (e.g. [BigQueryTableMock](https://github.com/DeepLcom/sql-mock/blob/main/src/sql_mock/bigquery/table_mocks.py)). - -You might want to create a settings class as well in case you need some specific connection settings to be available within the `_get_results` method. - -### Create your `ColumnMocks` - -Your database system might support specific database types. In order to make them available as column types, you can use the `sql_mock.column_mocks.BaseColumnMock` class as a base and inherit your specific column types from it. -For most of your column mocks you might only need to specify the `dtype` that should be used to parse the inputs. - -A good practise is to create a `BaseColumnMock` class that is specific to your database and inherit all your column types from it, e.g.: - -```python -from sql_mock.column_mocks import BaseColumnMock - -class MyFanceDatabaseColumnMock(BaseColumnMock): - # In case you need some specific logic that overwrites the default behavior, you can do so here - pass - -class Int(MyFanceDatabaseColumnMock): - dtype = "Integer" - -class String(MyFanceDatabaseColumnMock): - dtype = "String" -``` - -### Contribute your database setup - -There will definitely be folks in the community that are in the need of support for the database you just created all the setup for. -Feel free to create a PR on this repository that we can start supporting your database system! - -## I am missing a specific BaseColumnMock type for my model fields - -We implemented some basic column types but it could happen that you don't find the one you need. -Luckily, you can easily create those with the tools provided. -The only thing you need to do is to inherit from the `BaseColumnMock` that is specific to your database system (e.g. `BigQueryColumnMock`) and write classes for the column mocks you are missing. Usually you only need to set the correct `dtype`. This would later be used in the `cast(col to )` expression. - -```python -# Replace the import with the database system you are using -from sql_mock.bigquery.column_mock import BigQueryColumnMock - -class MyFancyMissingColType(BigQueryColumnMock): - dtype = "FancyMissingColType" - - # In case you need to implement additional logic for casting, you can do so here - ... -``` - -**Don't forget to create a PR in case you feel that your column mock type could be useful for the community**! diff --git a/docsource/getting_started/installation.md b/docsource/getting_started/installation.md deleted file mode 100644 index 0a36650..0000000 --- a/docsource/getting_started/installation.md +++ /dev/null @@ -1,39 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Installation - -The library can be installed from [PyPI](https://pypi.org/project/sql-mock/) using pip: - -```shell -# BigQuery -pip install --upgrade "sql-mock[bigquery]" - -# Clickhouse -pip install --upgrade "sql-mock[clickhouse]" - -# Redshift -pip install --upgrade "sql-mock[redshift]" - -# Snowflake -pip install --upgrade "sql-mock[snowflake]" -``` - -If you need to modify this source code, install the dependencies using poetry: - -```shell -poetry install --all-extras -``` - - -## Recommended Setup for Pytest -If you are using pytest, make sure to add a `conftest.py` file to the root of your project. -In the file add the following lines: -```python -import pytest -pytest.register_assert_rewrite('sql_mock') -``` -This allows you to get a rich comparison when using the `.assert_equal` method on the table mock instances. - -We also recommend using [pytest-icdiff](https://github.com/hjwp/pytest-icdiff) for better visibility on diffs of failed tests. diff --git a/docsource/getting_started/quickstart.md b/docsource/getting_started/quickstart.md deleted file mode 100644 index 34d692e..0000000 --- a/docsource/getting_started/quickstart.md +++ /dev/null @@ -1,84 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Quickstart - -Before diving into specific database scenarios, let's start with a simplified example of how SQL Mock works behind the scenes. - -1. You have an original SQL query, for instance: - - ```sql - -- path/to/query_for_result_table.sql - SELECT id FROM data.table1 - ``` - -2. Using SQL Mock, you define mock tables. You can use the built-in column types provided by SQL Mock. Available column types include `Int`, `String`, `Date`, and more. Each database type has their own column types. Define your tables by subclassing a mock table class that fits your database (e.g. `BigQueryTableMock`) and specifying the column types along with default values. In our example we use the `ClickHouseTableMock` class - - ```python - from sql_mock.clickhouse import column_mocks as col - from sql_mock.clickhouse.table_mocks import ClickHouseTableMock - from sql_mock.table_mocks import table_meta - - @table_meta(table_ref='data.table1') - class Table(ClickHouseTableMock): - id = col.Int(default=1) - name = col.String(default='Peter') - - @table_meta(table_ref='data.result_table', query_path='path/to/query_for_result_table.sql') - class ResultTable(ClickHouseTableMock): - id = col.Int(default=1) - ``` - -3. **Creating mock data:** Define mock data for your tables using dictionaries. Each dictionary represents a row in the table, with keys corresponding to column names. Table column keys that don't get a value will use the default. - - ```python - user_data = [ - {}, # This will use the defaults for both id and name - {'id': 2, 'name': 'Martin'}, - {'id': 3}, # This will use defaults for the name - ] - - input_table_mock = Table.from_dicts(user_data) - ``` - -4. **Getting results for a table mock:** Use the `from_mocks` method of the table mock object to generate mock query results based on your mock data. - - ```python - res = ResultTable.from_mocks(input_data=[input_table_mock]) - ``` - -5. Behind the scene SQL Mock replaces table references (e.g. `data.table1`) in your query with Common Table Expressions (CTEs) filled with dummy data. It can roughly be compared to something like this: - - ```sql - WITH data__table1 AS ( - -- Mocked inputs - SELECT - cast('1' AS 'String') AS id, - cast('Peter' AS 'String') AS name - UNION ALL - SELECT - cast('2' AS 'String') AS id, - cast('Martin' AS 'String') AS name - UNION ALL - SELECT - cast('3' AS 'String') AS id, - cast('Peter' AS 'String') AS name - ) - - result AS ( - -- Original query with replaced references - SELECT id FROM data__table1 - ) - - SELECT - cast(id AS 'String') AS id - FROM result - ``` - -6. Finally, you can compare your results to some expected results using the `assert_equal` method. - - ```python - expected = [{'id': '1'},{'id': '2'},{'id': '3'}] - res.assert_equal(expected) - ``` diff --git a/docsource/index.rst b/docsource/index.rst deleted file mode 100644 index b78bacb..0000000 --- a/docsource/index.rst +++ /dev/null @@ -1,60 +0,0 @@ -.. SQL Mock documentation master file, created by - sphinx-quickstart on Wed Nov 1 07:36:03 2023. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to SQL Mock's documentation! -==================================== - -The primary purpose of this library is to simplify the testing of SQL data models and queries by allowing users to mock input data and create tests for various scenarios. -It provides a consistent and convenient way to test the execution of your query without the need to process a massive amount of data. - -.. meta:: - :google-site-verification: ohDOHPn1YMLYMaWQpFmqQfPW_KRZXNK9Gq47pP57VQM - -.. automodule:: sql_mock - :members: - :undoc-members: - :show-inheritance: - -.. toctree:: - :maxdepth: 3 - :caption: Getting Started - - getting_started/installation - getting_started/quickstart - faq - -.. toctree:: - :maxdepth: 3 - :caption: Basic Usage - - usage/defining_table_mocks - usage/dbt - usage/your_sql_query_to_test - usage/result_assertion - usage/default_values - usage/examples - -.. toctree:: - :maxdepth: 3 - :caption: Database Specifics - - usage/bigquery/index - usage/clickhouse/index - usage/redshift/index - usage/snowflake/index - -.. toctree:: - :maxdepth: 3 - :caption: API Reference - - API Reference - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docsource/modules.rst b/docsource/modules.rst deleted file mode 100644 index f4baeab..0000000 --- a/docsource/modules.rst +++ /dev/null @@ -1,8 +0,0 @@ -sql_mock -======== - -.. toctree:: - :maxdepth: 4 - :hidden: - - sql_mock diff --git a/docsource/robots.txt b/docsource/robots.txt deleted file mode 100644 index 7557cc5..0000000 --- a/docsource/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -User-agent: * - -Sitemap: https://deeplcom.github.io/sql-mock/sitemap.xml diff --git a/docsource/sql_mock.bigquery.rst b/docsource/sql_mock.bigquery.rst deleted file mode 100644 index 0ec2aea..0000000 --- a/docsource/sql_mock.bigquery.rst +++ /dev/null @@ -1,37 +0,0 @@ -sql\_mock.bigquery package -========================== - -Submodules ----------- - -sql\_mock.bigquery.column\_mocks module ---------------------------------------- - -.. automodule:: sql_mock.bigquery.column_mocks - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.bigquery.settings module ----------------------------------- - -.. automodule:: sql_mock.bigquery.settings - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.bigquery.table\_mocks module --------------------------------------- - -.. automodule:: sql_mock.bigquery.table_mocks - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: sql_mock.bigquery - :members: - :undoc-members: - :show-inheritance: diff --git a/docsource/sql_mock.clickhouse.rst b/docsource/sql_mock.clickhouse.rst deleted file mode 100644 index d8577e0..0000000 --- a/docsource/sql_mock.clickhouse.rst +++ /dev/null @@ -1,37 +0,0 @@ -sql\_mock.clickhouse package -============================ - -Submodules ----------- - -sql\_mock.clickhouse.column\_mocks module ------------------------------------------ - -.. automodule:: sql_mock.clickhouse.column_mocks - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.clickhouse.settings module ------------------------------------- - -.. automodule:: sql_mock.clickhouse.settings - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.clickhouse.table\_mocks module ----------------------------------------- - -.. automodule:: sql_mock.clickhouse.table_mocks - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: sql_mock.clickhouse - :members: - :undoc-members: - :show-inheritance: diff --git a/docsource/sql_mock.redshift.rst b/docsource/sql_mock.redshift.rst deleted file mode 100644 index 1a3a286..0000000 --- a/docsource/sql_mock.redshift.rst +++ /dev/null @@ -1,37 +0,0 @@ -sql\_mock.redshift package -========================== - -Submodules ----------- - -sql\_mock.redshift.column\_mocks module ---------------------------------------- - -.. automodule:: sql_mock.redshift.column_mocks - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.redshift.settings module ----------------------------------- - -.. automodule:: sql_mock.redshift.settings - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.redshift.table\_mocks module --------------------------------------- - -.. automodule:: sql_mock.redshift.table_mocks - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: sql_mock.redshift - :members: - :undoc-members: - :show-inheritance: diff --git a/docsource/sql_mock.rst b/docsource/sql_mock.rst deleted file mode 100644 index 407d078..0000000 --- a/docsource/sql_mock.rst +++ /dev/null @@ -1,54 +0,0 @@ -sql\_mock package -================= - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - sql_mock.bigquery - sql_mock.clickhouse - -Submodules ----------- - -sql\_mock.column\_mocks module ------------------------------- - -.. automodule:: sql_mock.column_mocks - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.constants module --------------------------- - -.. automodule:: sql_mock.constants - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.exceptions module ---------------------------- - -.. automodule:: sql_mock.exceptions - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.table\_mocks module ------------------------------ - -.. automodule:: sql_mock.table_mocks - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: sql_mock - :members: - :undoc-members: - :show-inheritance: diff --git a/docsource/sql_mock.snowflake.rst b/docsource/sql_mock.snowflake.rst deleted file mode 100644 index ba3ca51..0000000 --- a/docsource/sql_mock.snowflake.rst +++ /dev/null @@ -1,37 +0,0 @@ -sql\_mock.snowflake package -=========================== - -Submodules ----------- - -sql\_mock.snowflake.column\_mocks module ----------------------------------------- - -.. automodule:: sql_mock.snowflake.column_mocks - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.snowflake.settings module ------------------------------------ - -.. automodule:: sql_mock.snowflake.settings - :members: - :undoc-members: - :show-inheritance: - -sql\_mock.snowflake.table\_mocks module ---------------------------------------- - -.. automodule:: sql_mock.snowflake.table_mocks - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: sql_mock.snowflake - :members: - :undoc-members: - :show-inheritance: diff --git a/docsource/usage/bigquery/index.rst b/docsource/usage/bigquery/index.rst deleted file mode 100644 index 5af047d..0000000 --- a/docsource/usage/bigquery/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -BigQuery -===================== - -This section documents the specifics on how to use SQL Mock with BigQuery - -.. toctree:: - :maxdepth: 4 - - ./settings.md - ./examples.md diff --git a/docsource/usage/bigquery/settings.md b/docsource/usage/bigquery/settings.md deleted file mode 100644 index 9e261ad..0000000 --- a/docsource/usage/bigquery/settings.md +++ /dev/null @@ -1,9 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Settings - -In order to use sql-mock with BigQuery, ensure you have the `GOOGLE_APPLICATION_CREDENTIALS` environment variable correctly set to point to a service account file. - -You need to service account file in order to let SQL Mock connect to BigQuery while running the tests. diff --git a/docsource/usage/clickhouse/examples.md b/docsource/usage/clickhouse/examples.md deleted file mode 100644 index d0a5c1b..0000000 --- a/docsource/usage/clickhouse/examples.md +++ /dev/null @@ -1,59 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Example: Testing Subscription Counts in ClickHouse - -```python -from sql_mock.clickhouse import column_mocks as col -from sql_mock.clickhouse.table_mocks import ClickHouseTableMock -from sql_mock.table_mocks import table_meta - -# Define mock tables for your data model that inherit from ClickHouseTableMock -@table_meta(table_ref='data.users') -class UserTable(ClickHouseTableMock): - user_id = col.Int(default=1) - user_name = col.String(default="Mr. T") - -@table_meta(table_ref='data.subscriptions') -class SubscriptionTable(ClickHouseTableMock): - subscription_id = col.Int(default=1) - period_start_date = col.Date(default=datetime.date(2023, 9, 5)) - period_end_date = col.Date(default=datetime.date(2023, 9, 5)) - user_id = col.Int(default=1) - -# Define a mock table for your expected results -class SubscriptionCountTable(ClickHouseTableMock): - subscription_count = col.Int(default=1) - user_id = col.Int(default=1) - -# Your original SQL query -query = """ -SELECT - count(*) AS subscription_count, - user_id -FROM data.users -LEFT JOIN data.subscriptions USING(user_id) -GROUP BY user_id -""" - -# Create mock data for the 'data.users' and 'data.subscriptions' tables -users = UserTable.from_dicts([{'user_id': 1}, {'user_id': 2}]) -subscriptions = SubscriptionTable.from_dicts([ - {'subscription_id': 1, 'user_id': 1}, - {'subscription_id': 2, 'user_id': 1}, - {'subscription_id': 2, 'user_id': 2}, -]) - -# Define your expected results -expected = [ - {'user_id': 1, 'subscription_count': 2}, - {'user_id': 2, 'subscription_count': 1} -] - -# Simulate the SQL query using SQL Mock -res = SubscriptionCountTable.from_mocks(query=query, input_data=[users, subscriptions]) - -# Assert the results -res.assert_equal(expected) -``` diff --git a/docsource/usage/clickhouse/index.rst b/docsource/usage/clickhouse/index.rst deleted file mode 100644 index 4bca7b1..0000000 --- a/docsource/usage/clickhouse/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -Clickhouse -===================== - -This section documents the specifics on how to use SQL Mock with Clickhouse - -.. toctree:: - :maxdepth: 4 - - ./settings.md - ./examples.md diff --git a/docsource/usage/clickhouse/settings.md b/docsource/usage/clickhouse/settings.md deleted file mode 100644 index 8e9d6fb..0000000 --- a/docsource/usage/clickhouse/settings.md +++ /dev/null @@ -1,13 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Settings - -In order to use SQL Mock with Clickhouse, you need to provide the following environment variables when you run tests: -* `SQL_MOCK_CLICKHOUSE_HOST`: Host of your Clickhouse instance -* `SQL_MOCK_CLICKHOUSE_USER`: User you want to use for the connection -* `SQL_MOCK_CLICKHOUSE_PASSWORD`: Password of your user -* `SQL_MOCK_CLICKHOUSE_PORT`: Port of your Clickhouse instance - -Having those environment variables enables SQL Mock to connect to your Clickhouse instance. diff --git a/docsource/usage/examples.md b/docsource/usage/examples.md deleted file mode 100644 index 39763e6..0000000 --- a/docsource/usage/examples.md +++ /dev/null @@ -1,7 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Examples - -You can find some examples in the [examples folder](https://github.com/DeepLcom/sql-mock/tree/main/examples). diff --git a/docsource/usage/redshift/index.rst b/docsource/usage/redshift/index.rst deleted file mode 100644 index b2f7caa..0000000 --- a/docsource/usage/redshift/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -Redshift -===================== - -This section documents the specifics on how to use SQL Mock with Redshift - -.. toctree:: - :maxdepth: 4 - - ./settings.md - ./examples.md diff --git a/docsource/usage/redshift/settings.md b/docsource/usage/redshift/settings.md deleted file mode 100644 index fdf1ba0..0000000 --- a/docsource/usage/redshift/settings.md +++ /dev/null @@ -1,14 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Settings - -In order to use SQL Mock with Redshift, you need to provide the following environment variables when you run tests: - -* `SQL_MOCK_REDSHIFT_HOST`: The host of your Redshift instance -* `SQL_MOCK_REDSHIFT_USER`: The user of your Redshift instance -* `SQL_MOCK_REDSHIFT_PASSWORD`: The password of your Redshift instance -* `SQL_MOCK_REDSHIFT_PORT`: The port of your Redshift instance - -Having those environment variables enables SQL Mock to connect to your Redshift instance. diff --git a/docsource/usage/snowflake/index.rst b/docsource/usage/snowflake/index.rst deleted file mode 100644 index 6c143df..0000000 --- a/docsource/usage/snowflake/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -Snowflake -===================== - -This section documents the specifics on how to use SQL Mock with Snowflake - -.. toctree:: - :maxdepth: 4 - - ./settings.md - ./examples.md diff --git a/docsource/usage/snowflake/settings.md b/docsource/usage/snowflake/settings.md deleted file mode 100644 index 2c9143d..0000000 --- a/docsource/usage/snowflake/settings.md +++ /dev/null @@ -1,13 +0,0 @@ -```{toctree} -:maxdepth: 2 -``` - -# Settings - -In order to use SQL Mock with Snowflake, you need to provide the following environment variables when you run tests: - -* `SQL_MOCK_SNOWFLAKE_ACCOUNT`: The name of your Snowflake account -* `SQL_MOCK_SNOWFLAKE_USER`: The name of your Snowflake user -* `SQL_MOCK_SNOWFLAKE_PASSWORD`: The password for your Snowflake user - -Having those environment variables enables SQL Mock to connect to your Snowflake instance. diff --git a/poetry.lock b/poetry.lock index e1ad615..f817ce1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,16 +1,5 @@ # This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. -[[package]] -name = "alabaster" -version = "0.7.13" -description = "A configurable sidebar-enabled Sphinx theme" -optional = false -python-versions = ">=3.6" -files = [ - {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, - {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, -] - [[package]] name = "annotated-types" version = "0.6.0" @@ -33,20 +22,6 @@ files = [ {file = "asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c"}, ] -[[package]] -name = "babel" -version = "2.14.0" -description = "Internationalization utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, - {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, -] - -[package.extras] -dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] - [[package]] name = "beautifulsoup4" version = "4.12.2" @@ -132,13 +107,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.14" +version = "1.34.19" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">= 3.8" files = [ - {file = "botocore-1.34.14-py3-none-any.whl", hash = "sha256:3b592f50f0406e236782a3a0a9ad1c3976060fdb2e04a23d18c3df5b7dfad3e0"}, - {file = "botocore-1.34.14.tar.gz", hash = "sha256:041bed0852649cab7e4dcd4d87f9d1cc084467fb846e5b60015e014761d96414"}, + {file = "botocore-1.34.19-py3-none-any.whl", hash = "sha256:a4a39c7092960f5da2439efc5f6220730dab634aaff4c1444bbd1dfa43bc28cc"}, + {file = "botocore-1.34.19.tar.gz", hash = "sha256:64352b2f05de5c6ab025c1d5232880c22775356dcc5a53d798a6f65db847e826"}, ] [package.dependencies] @@ -548,17 +523,6 @@ files = [ {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, ] -[[package]] -name = "docutils" -version = "0.18.1" -description = "Docutils -- Python Documentation Utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"}, - {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"}, -] - [[package]] name = "exceptiongroup" version = "1.2.0" @@ -629,13 +593,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] [[package]] name = "google-auth" -version = "2.26.1" +version = "2.26.2" description = "Google Authentication Library" optional = true python-versions = ">=3.7" files = [ - {file = "google-auth-2.26.1.tar.gz", hash = "sha256:54385acca5c0fbdda510cd8585ba6f3fcb06eeecf8a6ecca39d3ee148b092590"}, - {file = "google_auth-2.26.1-py2.py3-none-any.whl", hash = "sha256:2c8b55e3e564f298122a02ab7b97458ccfcc5617840beb5d0ac757ada92c9780"}, + {file = "google-auth-2.26.2.tar.gz", hash = "sha256:97327dbbf58cccb58fc5a1712bba403ae76668e64814eb30f7316f7e27126b81"}, + {file = "google_auth-2.26.2-py2.py3-none-any.whl", hash = "sha256:3f445c8ce9b61ed6459aad86d8ccdba4a9afed841b2d1451a11ef4db08957424"}, ] [package.dependencies] @@ -652,13 +616,13 @@ requests = ["requests (>=2.20.0,<3.0.0.dev0)"] [[package]] name = "google-cloud-bigquery" -version = "3.14.1" +version = "3.16.0" description = "Google BigQuery API client library" optional = true python-versions = ">=3.7" files = [ - {file = "google-cloud-bigquery-3.14.1.tar.gz", hash = "sha256:aa15bd86f79ea76824c7d710f5ae532323c4b3ba01ef4abff42d4ee7a2e9b142"}, - {file = "google_cloud_bigquery-3.14.1-py2.py3-none-any.whl", hash = "sha256:a8ded18455da71508db222b7c06197bc12b6dbc6ed5b0b64e7007b76d7016957"}, + {file = "google-cloud-bigquery-3.16.0.tar.gz", hash = "sha256:1d6abf4b1d740df17cb43a078789872af8059a0b1dd999f32ea69ebc6f7ba7ef"}, + {file = "google_cloud_bigquery-3.16.0-py2.py3-none-any.whl", hash = "sha256:8bac7754f92bf87ee81f38deabb7554d82bb9591fbe06a5c82f33e46e5a482f9"}, ] [package.dependencies] @@ -849,36 +813,6 @@ files = [ {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, ] -[[package]] -name = "imagesize" -version = "1.4.1" -description = "Getting image size from png/jpeg/jpeg2000/gif file" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, - {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, -] - -[[package]] -name = "importlib-metadata" -version = "7.0.1" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, - {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, -] - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] - [[package]] name = "iniconfig" version = "2.0.0" @@ -906,13 +840,13 @@ colors = ["colorama (>=0.4.6)"] [[package]] name = "jinja2" -version = "3.1.2" +version = "3.1.3" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, + {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, + {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, ] [package.dependencies] @@ -934,99 +868,89 @@ files = [ [[package]] name = "lxml" -version = "5.0.1" +version = "5.1.0" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" -files = [ - {file = "lxml-5.0.1-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1d78e91cbffe733ff325e0d258bb64702c8d91f8f652db088bd2989c6a8f90cc"}, - {file = "lxml-5.0.1-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:19251f782ea51a4841e747158195312ef63e06b47889e159dc5f1b2e5d668465"}, - {file = "lxml-5.0.1-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b6bb5a0a87ab1e01f086cbb418be9e409719cd216954aa38b1cceee36a561ce1"}, - {file = "lxml-5.0.1-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:4b49a1569ed6d05808f4d163a316e7bf4a230e0c36855b59f56020ae27ae586a"}, - {file = "lxml-5.0.1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:dbff288e1869db78f8731ca257553dd699edef07e173b35e71b1122b630d6008"}, - {file = "lxml-5.0.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:0f70e5de6b3e24ababeca597f776e5f37973f05d28a4d9f467aa5b45745af762"}, - {file = "lxml-5.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:32a135d4ef8f966bc087d450d641df73fc6874f04cf6608111541b50090e6f13"}, - {file = "lxml-5.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:b4eef43c5dc5c579d0804e55a32dd1bacbd008c8191ed4d65be278bbb11ddc61"}, - {file = "lxml-5.0.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:7febf50135363e981097eeada84781eeae92bfc3c203495f63d6b542a7132ba7"}, - {file = "lxml-5.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0a79eca2ef5e032c8ed9da07f84a07a29105f220b777613dfe7fc31445691ee3"}, - {file = "lxml-5.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8de180f748a17382dd695b3999be03a647d09af16ae589c4e9c37138ddb6d4c6"}, - {file = "lxml-5.0.1-cp310-cp310-win32.whl", hash = "sha256:6af86081c888ce81ca7e361ed7fa2ba1678e2a86eb5a059c96d5a719364d319e"}, - {file = "lxml-5.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:0dc36ec06514fe8848c4733d47f96a0636f82d9ca3eaa2132373426bc03f178f"}, - {file = "lxml-5.0.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:f56e6a38c64a79e228d48344bb3bec265ac035fc1277ce8c049445bb18e4cd41"}, - {file = "lxml-5.0.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4d58af4ebd711dad40f1c024a779950d9918d04d74f49230edf5d271dcd33c28"}, - {file = "lxml-5.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:00bfccab28f710bb13f7f644c980ad50ce3e5b6a412b5bb9a6c30136b298fb2c"}, - {file = "lxml-5.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:45e747b4e82390ffd802528b9e7b39333c1ce71423057bf5961b30ec0d52f76f"}, - {file = "lxml-5.0.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:03c977ffc9a4bf17b3e0f8db0451dc38e9f4ec92cfdb5df462d38fbe6e6e0825"}, - {file = "lxml-5.0.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d0047c90e0ebd0d8f3c1e6636e10f597b8f25e4ef9e6416dd2e5c4c0960270cc"}, - {file = "lxml-5.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff29353c12f0abc9cb3395899b7192a970d5a63f80ac1e7f0c3247ed83f5dcd4"}, - {file = "lxml-5.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2ec9fa65e0638551a5ad31cb9fa160b321f19632e5ec517fe68d7b4110133e69"}, - {file = "lxml-5.0.1-cp311-cp311-win32.whl", hash = "sha256:9a4eff4d8ad0bbc9f470a9be19c5e718af4baf47111d7c2d9b036b9986107e7c"}, - {file = "lxml-5.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:3714f339449d2738b4fadd078a6022704a2af3cab06bec9627b19eaa4205090d"}, - {file = "lxml-5.0.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:473f2d0511dd84697326ee9362b0c0c2e9f99a433dcb1fbb5aa8df3d1b2185db"}, - {file = "lxml-5.0.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:62a3c0fdf70f785cd29824666d1dcea88c207f0b73ddbc28fb7a6a1a5bbb1af7"}, - {file = "lxml-5.0.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:83ff41e1bc0666f31acda52407d869ea257f232c2d9394806647a0e7454de73e"}, - {file = "lxml-5.0.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:42069ce16dab9755b381b90defd846ca407b9ead05dc20732fd5502b5cc49b87"}, - {file = "lxml-5.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:737a4dba9f7ee842c6597f719dda2eabeeaefe42443f7f24de20c262f88527cd"}, - {file = "lxml-5.0.1-cp312-cp312-win32.whl", hash = "sha256:67ddff0272905a0b78a2c3ea01487e0551cc38094cd5994f73af370f355ecb47"}, - {file = "lxml-5.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a28eab2d9ea79b830be50e3350d827ae8abf5b23e278e14929824d5ab2069008"}, - {file = "lxml-5.0.1-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3013823b0069cb4bd9b558e87076a18142703c6d2ac3a5d5521dd35734d23a72"}, - {file = "lxml-5.0.1-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b005101a257c494e84d36ecb62b02ba195b02b7f8892f57b1f5aaa352ed44467"}, - {file = "lxml-5.0.1-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:f9464ff2fd1f2ba4d0d246a560d369ee7e7213c556a30db9ae9426850ce1baf9"}, - {file = "lxml-5.0.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:9e8a4782ecaaacf8e9355f39179b1f00e7f27b774306eccbe80f6215724be4cd"}, - {file = "lxml-5.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcb25128c9e7f01c00ad116d2c762c3942724981a35c6e5c551ab55d4c2bfcfe"}, - {file = "lxml-5.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:39a3cf581e9040e66aaa719b2f338b2b7eb43ce1db059089c82ae72e0fd48b47"}, - {file = "lxml-5.0.1-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:6cdd0fb749c80ffcf408f659b209e82333f10b517786083a3dd3c3b5adc60111"}, - {file = "lxml-5.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfdac95815d3025e4c9edce2ef2ebe4e034edc35a2c44a606dd846554387ae38"}, - {file = "lxml-5.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c21e60c017cab3a7e7786185cc8853b8614b01ccd69cc8b24608e5356784631b"}, - {file = "lxml-5.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:5892cff0a6817743fe470b7402677310ffc8514a74de14d4e591cecdc457ff61"}, - {file = "lxml-5.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:57f5c362cbd9d688fb1fa07c8955cec26d5c066fbcb4163aa341ff751eba7587"}, - {file = "lxml-5.0.1-cp36-cp36m-win32.whl", hash = "sha256:8a70c47c14f89b8bfb430f85b608aa460204fe7c005545d79afd31b925cc6669"}, - {file = "lxml-5.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8ba56c3686fa60cc04191d22d1733aad484c9cbc153cdc3e8eb9bdfcad30f704"}, - {file = "lxml-5.0.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c4eaa83b610595ef9f20aa69b96053d5b7f3f70c67c7a3af8f433136a9d315ab"}, - {file = "lxml-5.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:ae3a0ec0f1b6cf1e8bca41bc86cd64ba02e31c71716efbf149a0f7ebc168cf0b"}, - {file = "lxml-5.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c5b23f63fcec652bf1e775eca5e03a713a4994d2a7ce2e70a91e964a26220e0d"}, - {file = "lxml-5.0.1-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:d05cf827f160340f67c25ce6f271689a844605aa123849f1a80e21c9bd21f00b"}, - {file = "lxml-5.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bcded868b05583d41ab0b024f39f90a04e486a2349a9b493d8d17024f1433aa6"}, - {file = "lxml-5.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:821fb791565536617b058c2cd5b8d28a1285b3375eecc5bd6b5c6d87add0d3dd"}, - {file = "lxml-5.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1546fa25a6dde5698271e19787062446f433c98ca7eab35545f665dde2c1bd34"}, - {file = "lxml-5.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:31362b900b8fd2a026b9d24695ebe5449ea8f0c948af2445d7880b738d9fc368"}, - {file = "lxml-5.0.1-cp37-cp37m-win32.whl", hash = "sha256:0963de4fe463caff48e6ce4d83d19a3c099126874185d10cf490c29057ca518d"}, - {file = "lxml-5.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:b7bb0010c2969c23bf3d2b3892e638a7cb83e7daeb749e3db5f3c002fd191e11"}, - {file = "lxml-5.0.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:e2bd8faf6a9682ca385e4bca1a38a057be716dc303f16ddec9e4c9cf01b7d722"}, - {file = "lxml-5.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:0fb55d77e685def5218701d5d296fca62f595752c88402404da685864b06b67e"}, - {file = "lxml-5.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:73e71b95c5215310a92e560369ac1f0e2cd018d5a36be182da88958f3d6084f5"}, - {file = "lxml-5.0.1-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:0ecc0f1e1d901b66f2f68edff85b8ff421fa9683d02eaea6742a42c145d741b6"}, - {file = "lxml-5.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f36c3103a6f2641777b64f1da860f37cbaa718ce3feea621583627269e68eb03"}, - {file = "lxml-5.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:dcc7dc4b9b65f185aa8533abc78f0a3b2ac38fe075bb23d3c1590ba0990f6c80"}, - {file = "lxml-5.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1215c8e57a25ad68488abb83a36734f6c6b3f0ccd880f0c68da98682d463ef09"}, - {file = "lxml-5.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:070469a23f2ef3a9e72165af7e0b12eca9a6e47c3a8ec1cad60d14fb2f2c3aa8"}, - {file = "lxml-5.0.1-cp38-cp38-win32.whl", hash = "sha256:b889c0b9be774466308c3590e093ce9a6f9115c78fc8624aa6ba8dfeaf5188ab"}, - {file = "lxml-5.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:0499310df9afc0ce634ce14cacbb333d62f561038ea4db640494e4a22ac4f2e9"}, - {file = "lxml-5.0.1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:18b456f1bfb338be94a916166ac5507e73b9eb9f6e1f0fbd1c8caff2f3fa5535"}, - {file = "lxml-5.0.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:60974986aa80a8bb883da5663f90bc632bd4ce0d0508e66a9132412facec65f6"}, - {file = "lxml-5.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:d6d3ce5638cd4ed3fa684507f164e7039e1b07475bc8f37ba6e12271c1a2e9e0"}, - {file = "lxml-5.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e97c74725e86d84a477df081eef69b70f048128afee841dbd8c690a9e3d2e8e0"}, - {file = "lxml-5.0.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:387c5416b8bb4b8ad7306797cb2719a841f5f3836b3c39fcaa56b9af5448dd2a"}, - {file = "lxml-5.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:feb1102d9e5de08120d46a1011110c43b2547ecb3ae80030801e0e2dacd1ee18"}, - {file = "lxml-5.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:745383c124f096cc03fb942c8a05ea1e8cb4f44c5b28887adce6224e4540808e"}, - {file = "lxml-5.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4ae66b6b0f82e7839b6b8d009182c652d48e7d2ea21a6709f3033ce5fbf199c4"}, - {file = "lxml-5.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:430780608d16b3bb96ef99a67a1a0626c8a295193af53ce9c4d5ec3fef2fbc79"}, - {file = "lxml-5.0.1-cp39-cp39-win32.whl", hash = "sha256:331237209fe76951450c1119af0879f04f32d1b07b21e83a34ba439520492feb"}, - {file = "lxml-5.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:c32a4fbae218b336d547bc626897325202e4e9f1794ac5f4d0bb3caacf41df21"}, - {file = "lxml-5.0.1-pp310-pypy310_pp73-macosx_11_0_x86_64.whl", hash = "sha256:96c2abcbcb24f850f00f279c4660ce6498cae16ff1659845838d752c26890748"}, - {file = "lxml-5.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:99b5ca5775435aa296d32ea711e194aaae871b21dbf0d57cb7d4431e5d3ad699"}, - {file = "lxml-5.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a99dae826c80cf0a21dd21eb66db16310d1f58ac4c27c804da980212fbcabe2"}, - {file = "lxml-5.0.1-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:4df6be79be4d7574e9e4002aeb6aa03d3f3809582db07abb166df7fc6e7438af"}, - {file = "lxml-5.0.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:49dc4dcf14a08f160bb3f5f571f63514d918b8933a25c221536571a5fc010271"}, - {file = "lxml-5.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:47f46a2ebade07f3afa47695882e7725440c49bf77cba39c3762a42597e5aad3"}, - {file = "lxml-5.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:18caa0d3925902949cb060fe5f2da70c953d60bd9ef78657bd389f6db30533cc"}, - {file = "lxml-5.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:8991837fdf8086486f1c300d936bacd757e2e5398be84cd54a1fba0e6b6d5591"}, - {file = "lxml-5.0.1-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:d64e543b07964ff73b4eb994bee894803a80e19fd3b29a5ffbe3c637fe43e788"}, - {file = "lxml-5.0.1-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:d80d9f4d986bb6ad65bae86f07391152f7b6c65cfc63d118616b18b0be2e79da"}, - {file = "lxml-5.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ea5e4b3eff9029a02fe7736540675ab8fca44277232f0027397b0d7111d04b1c"}, - {file = "lxml-5.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e2388a792f9c239510d62a9e615662b8202e4ca275aafcc9c4af154654462a14"}, - {file = "lxml-5.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3ffc56d68b9782919d69ae9a6fac99efd7547f2666ccb7ecfd12871564d16133"}, - {file = "lxml-5.0.1.tar.gz", hash = "sha256:4432a1d89a9b340bc6bd1201aef3ba03112f151d3f340d9218247dc0c85028ab"}, +python-versions = ">=3.6" +files = [ + {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:704f5572ff473a5f897745abebc6df40f22d4133c1e0a1f124e4f2bd3330ff7e"}, + {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d3c0f8567ffe7502d969c2c1b809892dc793b5d0665f602aad19895f8d508da"}, + {file = "lxml-5.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5fcfbebdb0c5d8d18b84118842f31965d59ee3e66996ac842e21f957eb76138c"}, + {file = "lxml-5.1.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f37c6d7106a9d6f0708d4e164b707037b7380fcd0b04c5bd9cae1fb46a856fb"}, + {file = "lxml-5.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2befa20a13f1a75c751f47e00929fb3433d67eb9923c2c0b364de449121f447c"}, + {file = "lxml-5.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22b7ee4c35f374e2c20337a95502057964d7e35b996b1c667b5c65c567d2252a"}, + {file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bf8443781533b8d37b295016a4b53c1494fa9a03573c09ca5104550c138d5c05"}, + {file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82bddf0e72cb2af3cbba7cec1d2fd11fda0de6be8f4492223d4a268713ef2147"}, + {file = "lxml-5.1.0-cp310-cp310-win32.whl", hash = "sha256:b66aa6357b265670bb574f050ffceefb98549c721cf28351b748be1ef9577d93"}, + {file = "lxml-5.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:4946e7f59b7b6a9e27bef34422f645e9a368cb2be11bf1ef3cafc39a1f6ba68d"}, + {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:14deca1460b4b0f6b01f1ddc9557704e8b365f55c63070463f6c18619ebf964f"}, + {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed8c3d2cd329bf779b7ed38db176738f3f8be637bb395ce9629fc76f78afe3d4"}, + {file = "lxml-5.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:436a943c2900bb98123b06437cdd30580a61340fbdb7b28aaf345a459c19046a"}, + {file = "lxml-5.1.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acb6b2f96f60f70e7f34efe0c3ea34ca63f19ca63ce90019c6cbca6b676e81fa"}, + {file = "lxml-5.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af8920ce4a55ff41167ddbc20077f5698c2e710ad3353d32a07d3264f3a2021e"}, + {file = "lxml-5.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cfced4a069003d8913408e10ca8ed092c49a7f6cefee9bb74b6b3e860683b45"}, + {file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9e5ac3437746189a9b4121db2a7b86056ac8786b12e88838696899328fc44bb2"}, + {file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4c9bda132ad108b387c33fabfea47866af87f4ea6ffb79418004f0521e63204"}, + {file = "lxml-5.1.0-cp311-cp311-win32.whl", hash = "sha256:bc64d1b1dab08f679fb89c368f4c05693f58a9faf744c4d390d7ed1d8223869b"}, + {file = "lxml-5.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5ab722ae5a873d8dcee1f5f45ddd93c34210aed44ff2dc643b5025981908cda"}, + {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9aa543980ab1fbf1720969af1d99095a548ea42e00361e727c58a40832439114"}, + {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6f11b77ec0979f7e4dc5ae081325a2946f1fe424148d3945f943ceaede98adb8"}, + {file = "lxml-5.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a36c506e5f8aeb40680491d39ed94670487ce6614b9d27cabe45d94cd5d63e1e"}, + {file = "lxml-5.1.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f643ffd2669ffd4b5a3e9b41c909b72b2a1d5e4915da90a77e119b8d48ce867a"}, + {file = "lxml-5.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16dd953fb719f0ffc5bc067428fc9e88f599e15723a85618c45847c96f11f431"}, + {file = "lxml-5.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16018f7099245157564d7148165132c70adb272fb5a17c048ba70d9cc542a1a1"}, + {file = "lxml-5.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:82cd34f1081ae4ea2ede3d52f71b7be313756e99b4b5f829f89b12da552d3aa3"}, + {file = "lxml-5.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:19a1bc898ae9f06bccb7c3e1dfd73897ecbbd2c96afe9095a6026016e5ca97b8"}, + {file = "lxml-5.1.0-cp312-cp312-win32.whl", hash = "sha256:13521a321a25c641b9ea127ef478b580b5ec82aa2e9fc076c86169d161798b01"}, + {file = "lxml-5.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:1ad17c20e3666c035db502c78b86e58ff6b5991906e55bdbef94977700c72623"}, + {file = "lxml-5.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:24ef5a4631c0b6cceaf2dbca21687e29725b7c4e171f33a8f8ce23c12558ded1"}, + {file = "lxml-5.1.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d2900b7f5318bc7ad8631d3d40190b95ef2aa8cc59473b73b294e4a55e9f30f"}, + {file = "lxml-5.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:601f4a75797d7a770daed8b42b97cd1bb1ba18bd51a9382077a6a247a12aa38d"}, + {file = "lxml-5.1.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4b68c961b5cc402cbd99cca5eb2547e46ce77260eb705f4d117fd9c3f932b95"}, + {file = "lxml-5.1.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:afd825e30f8d1f521713a5669b63657bcfe5980a916c95855060048b88e1adb7"}, + {file = "lxml-5.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:262bc5f512a66b527d026518507e78c2f9c2bd9eb5c8aeeb9f0eb43fcb69dc67"}, + {file = "lxml-5.1.0-cp36-cp36m-win32.whl", hash = "sha256:e856c1c7255c739434489ec9c8aa9cdf5179785d10ff20add308b5d673bed5cd"}, + {file = "lxml-5.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:c7257171bb8d4432fe9d6fdde4d55fdbe663a63636a17f7f9aaba9bcb3153ad7"}, + {file = "lxml-5.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b9e240ae0ba96477682aa87899d94ddec1cc7926f9df29b1dd57b39e797d5ab5"}, + {file = "lxml-5.1.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a96f02ba1bcd330807fc060ed91d1f7a20853da6dd449e5da4b09bfcc08fdcf5"}, + {file = "lxml-5.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e3898ae2b58eeafedfe99e542a17859017d72d7f6a63de0f04f99c2cb125936"}, + {file = "lxml-5.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61c5a7edbd7c695e54fca029ceb351fc45cd8860119a0f83e48be44e1c464862"}, + {file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3aeca824b38ca78d9ee2ab82bd9883083d0492d9d17df065ba3b94e88e4d7ee6"}, + {file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8f52fe6859b9db71ee609b0c0a70fea5f1e71c3462ecf144ca800d3f434f0764"}, + {file = "lxml-5.1.0-cp37-cp37m-win32.whl", hash = "sha256:d42e3a3fc18acc88b838efded0e6ec3edf3e328a58c68fbd36a7263a874906c8"}, + {file = "lxml-5.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:eac68f96539b32fce2c9b47eb7c25bb2582bdaf1bbb360d25f564ee9e04c542b"}, + {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae15347a88cf8af0949a9872b57a320d2605ae069bcdf047677318bc0bba45b1"}, + {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c26aab6ea9c54d3bed716b8851c8bfc40cb249b8e9880e250d1eddde9f709bf5"}, + {file = "lxml-5.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:342e95bddec3a698ac24378d61996b3ee5ba9acfeb253986002ac53c9a5f6f84"}, + {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:725e171e0b99a66ec8605ac77fa12239dbe061482ac854d25720e2294652eeaa"}, + {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d184e0d5c918cff04cdde9dbdf9600e960161d773666958c9d7b565ccc60c45"}, + {file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:98f3f020a2b736566c707c8e034945c02aa94e124c24f77ca097c446f81b01f1"}, + {file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d48fc57e7c1e3df57be5ae8614bab6d4e7b60f65c5457915c26892c41afc59e"}, + {file = "lxml-5.1.0-cp38-cp38-win32.whl", hash = "sha256:7ec465e6549ed97e9f1e5ed51c657c9ede767bc1c11552f7f4d022c4df4a977a"}, + {file = "lxml-5.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:b21b4031b53d25b0858d4e124f2f9131ffc1530431c6d1321805c90da78388d1"}, + {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:52427a7eadc98f9e62cb1368a5079ae826f94f05755d2d567d93ee1bc3ceb354"}, + {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a2a2c724d97c1eb8cf966b16ca2915566a4904b9aad2ed9a09c748ffe14f969"}, + {file = "lxml-5.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:843b9c835580d52828d8f69ea4302537337a21e6b4f1ec711a52241ba4a824f3"}, + {file = "lxml-5.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b99f564659cfa704a2dd82d0684207b1aadf7d02d33e54845f9fc78e06b7581"}, + {file = "lxml-5.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f8b0c78e7aac24979ef09b7f50da871c2de2def043d468c4b41f512d831e912"}, + {file = "lxml-5.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9bcf86dfc8ff3e992fed847c077bd875d9e0ba2fa25d859c3a0f0f76f07f0c8d"}, + {file = "lxml-5.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:49a9b4af45e8b925e1cd6f3b15bbba2c81e7dba6dce170c677c9cda547411e14"}, + {file = "lxml-5.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:280f3edf15c2a967d923bcfb1f8f15337ad36f93525828b40a0f9d6c2ad24890"}, + {file = "lxml-5.1.0-cp39-cp39-win32.whl", hash = "sha256:ed7326563024b6e91fef6b6c7a1a2ff0a71b97793ac33dbbcf38f6005e51ff6e"}, + {file = "lxml-5.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:8d7b4beebb178e9183138f552238f7e6613162a42164233e2bda00cb3afac58f"}, + {file = "lxml-5.1.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9bd0ae7cc2b85320abd5e0abad5ccee5564ed5f0cc90245d2f9a8ef330a8deae"}, + {file = "lxml-5.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c1d679df4361408b628f42b26a5d62bd3e9ba7f0c0e7969f925021554755aa"}, + {file = "lxml-5.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2ad3a8ce9e8a767131061a22cd28fdffa3cd2dc193f399ff7b81777f3520e372"}, + {file = "lxml-5.1.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:304128394c9c22b6569eba2a6d98392b56fbdfbad58f83ea702530be80d0f9df"}, + {file = "lxml-5.1.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d74fcaf87132ffc0447b3c685a9f862ffb5b43e70ea6beec2fb8057d5d2a1fea"}, + {file = "lxml-5.1.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:8cf5877f7ed384dabfdcc37922c3191bf27e55b498fecece9fd5c2c7aaa34c33"}, + {file = "lxml-5.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:877efb968c3d7eb2dad540b6cabf2f1d3c0fbf4b2d309a3c141f79c7e0061324"}, + {file = "lxml-5.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f14a4fb1c1c402a22e6a341a24c1341b4a3def81b41cd354386dcb795f83897"}, + {file = "lxml-5.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:25663d6e99659544ee8fe1b89b1a8c0aaa5e34b103fab124b17fa958c4a324a6"}, + {file = "lxml-5.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8b9f19df998761babaa7f09e6bc169294eefafd6149aaa272081cbddc7ba4ca3"}, + {file = "lxml-5.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e53d7e6a98b64fe54775d23a7c669763451340c3d44ad5e3a3b48a1efbdc96f"}, + {file = "lxml-5.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c3cd1fc1dc7c376c54440aeaaa0dcc803d2126732ff5c6b68ccd619f2e64be4f"}, + {file = "lxml-5.1.0.tar.gz", hash = "sha256:3eea6ed6e6c918e468e693c41ef07f3c3acc310b70ddd9cc72d9ef84bc9564ca"}, ] [package.extras] @@ -1035,30 +959,6 @@ html5 = ["html5lib"] htmlsoup = ["BeautifulSoup4"] source = ["Cython (>=3.0.7)"] -[[package]] -name = "markdown-it-py" -version = "3.0.0" -description = "Python port of markdown-it. Markdown parsing, done right!" -optional = false -python-versions = ">=3.8" -files = [ - {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, - {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, -] - -[package.dependencies] -mdurl = ">=0.1,<1.0" - -[package.extras] -benchmarking = ["psutil", "pytest", "pytest-benchmark"] -code-style = ["pre-commit (>=3.0,<4.0)"] -compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] -linkify = ["linkify-it-py (>=1,<3)"] -plugins = ["mdit-py-plugins"] -profiling = ["gprof2dot"] -rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - [[package]] name = "markupsafe" version = "2.1.3" @@ -1139,36 +1039,6 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] -[[package]] -name = "mdit-py-plugins" -version = "0.4.0" -description = "Collection of plugins for markdown-it-py" -optional = false -python-versions = ">=3.8" -files = [ - {file = "mdit_py_plugins-0.4.0-py3-none-any.whl", hash = "sha256:b51b3bb70691f57f974e257e367107857a93b36f322a9e6d44ca5bf28ec2def9"}, - {file = "mdit_py_plugins-0.4.0.tar.gz", hash = "sha256:d8ab27e9aed6c38aa716819fedfde15ca275715955f8a185a8e1cf90fb1d2c1b"}, -] - -[package.dependencies] -markdown-it-py = ">=1.0.0,<4.0.0" - -[package.extras] -code-style = ["pre-commit"] -rtd = ["myst-parser", "sphinx-book-theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - -[[package]] -name = "mdurl" -version = "0.1.2" -description = "Markdown URL utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, -] - [[package]] name = "mypy-extensions" version = "1.0.0" @@ -1180,32 +1050,6 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] -[[package]] -name = "myst-parser" -version = "2.0.0" -description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," -optional = false -python-versions = ">=3.8" -files = [ - {file = "myst_parser-2.0.0-py3-none-any.whl", hash = "sha256:7c36344ae39c8e740dad7fdabf5aa6fc4897a813083c6cc9990044eb93656b14"}, - {file = "myst_parser-2.0.0.tar.gz", hash = "sha256:ea929a67a6a0b1683cdbe19b8d2e724cd7643f8aa3e7bb18dd65beac3483bead"}, -] - -[package.dependencies] -docutils = ">=0.16,<0.21" -jinja2 = "*" -markdown-it-py = ">=3.0,<4.0" -mdit-py-plugins = ">=0.4,<1.0" -pyyaml = "*" -sphinx = ">=6,<8" - -[package.extras] -code-style = ["pre-commit (>=3.0,<4.0)"] -linkify = ["linkify-it-py (>=2.0,<3.0)"] -rtd = ["ipython", "pydata-sphinx-theme (==v0.13.0rc4)", "sphinx-autodoc2 (>=0.4.2,<0.5.0)", "sphinx-book-theme (==1.0.0rc2)", "sphinx-copybutton", "sphinx-design2", "sphinx-pyscript", "sphinx-tippy (>=0.3.1)", "sphinx-togglebutton", "sphinxext-opengraph (>=0.8.2,<0.9.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"] -testing = ["beautifulsoup4", "coverage[toml]", "pytest (>=7,<8)", "pytest-cov", "pytest-param-files (>=0.3.4,<0.4.0)", "pytest-regressions", "sphinx-pytest"] -testing-docutils = ["pygments", "pytest (>=7,<8)", "pytest-param-files (>=0.3.4,<0.4.0)"] - [[package]] name = "nodeenv" version = "1.8.0" @@ -1416,22 +1260,22 @@ virtualenv = ">=20.10.0" [[package]] name = "protobuf" -version = "4.25.1" +version = "4.25.2" description = "" optional = true python-versions = ">=3.8" files = [ - {file = "protobuf-4.25.1-cp310-abi3-win32.whl", hash = "sha256:193f50a6ab78a970c9b4f148e7c750cfde64f59815e86f686c22e26b4fe01ce7"}, - {file = "protobuf-4.25.1-cp310-abi3-win_amd64.whl", hash = "sha256:3497c1af9f2526962f09329fd61a36566305e6c72da2590ae0d7d1322818843b"}, - {file = "protobuf-4.25.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:0bf384e75b92c42830c0a679b0cd4d6e2b36ae0cf3dbb1e1dfdda48a244f4bcd"}, - {file = "protobuf-4.25.1-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:0f881b589ff449bf0b931a711926e9ddaad3b35089cc039ce1af50b21a4ae8cb"}, - {file = "protobuf-4.25.1-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:ca37bf6a6d0046272c152eea90d2e4ef34593aaa32e8873fc14c16440f22d4b7"}, - {file = "protobuf-4.25.1-cp38-cp38-win32.whl", hash = "sha256:abc0525ae2689a8000837729eef7883b9391cd6aa7950249dcf5a4ede230d5dd"}, - {file = "protobuf-4.25.1-cp38-cp38-win_amd64.whl", hash = "sha256:1484f9e692091450e7edf418c939e15bfc8fc68856e36ce399aed6889dae8bb0"}, - {file = "protobuf-4.25.1-cp39-cp39-win32.whl", hash = "sha256:8bdbeaddaac52d15c6dce38c71b03038ef7772b977847eb6d374fc86636fa510"}, - {file = "protobuf-4.25.1-cp39-cp39-win_amd64.whl", hash = "sha256:becc576b7e6b553d22cbdf418686ee4daa443d7217999125c045ad56322dda10"}, - {file = "protobuf-4.25.1-py3-none-any.whl", hash = "sha256:a19731d5e83ae4737bb2a089605e636077ac001d18781b3cf489b9546c7c80d6"}, - {file = "protobuf-4.25.1.tar.gz", hash = "sha256:57d65074b4f5baa4ab5da1605c02be90ac20c8b40fb137d6a8df9f416b0d0ce2"}, + {file = "protobuf-4.25.2-cp310-abi3-win32.whl", hash = "sha256:b50c949608682b12efb0b2717f53256f03636af5f60ac0c1d900df6213910fd6"}, + {file = "protobuf-4.25.2-cp310-abi3-win_amd64.whl", hash = "sha256:8f62574857ee1de9f770baf04dde4165e30b15ad97ba03ceac65f760ff018ac9"}, + {file = "protobuf-4.25.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:2db9f8fa64fbdcdc93767d3cf81e0f2aef176284071507e3ede160811502fd3d"}, + {file = "protobuf-4.25.2-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:10894a2885b7175d3984f2be8d9850712c57d5e7587a2410720af8be56cdaf62"}, + {file = "protobuf-4.25.2-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:fc381d1dd0516343f1440019cedf08a7405f791cd49eef4ae1ea06520bc1c020"}, + {file = "protobuf-4.25.2-cp38-cp38-win32.whl", hash = "sha256:33a1aeef4b1927431d1be780e87b641e322b88d654203a9e9d93f218ee359e61"}, + {file = "protobuf-4.25.2-cp38-cp38-win_amd64.whl", hash = "sha256:47f3de503fe7c1245f6f03bea7e8d3ec11c6c4a2ea9ef910e3221c8a15516d62"}, + {file = "protobuf-4.25.2-cp39-cp39-win32.whl", hash = "sha256:5e5c933b4c30a988b52e0b7c02641760a5ba046edc5e43d3b94a74c9fc57c1b3"}, + {file = "protobuf-4.25.2-cp39-cp39-win_amd64.whl", hash = "sha256:d66a769b8d687df9024f2985d5137a337f957a0916cf5464d1513eee96a63ff0"}, + {file = "protobuf-4.25.2-py3-none-any.whl", hash = "sha256:a8b7a98d4ce823303145bf3c1a8bdb0f2f4642a414b196f04ad9853ed0c8f830"}, + {file = "protobuf-4.25.2.tar.gz", hash = "sha256:fe599e175cb347efc8ee524bcd4b902d11f7262c0e569ececcb89995c15f0a5e"}, ] [[package]] @@ -1643,21 +1487,6 @@ files = [ {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, ] -[[package]] -name = "pygments" -version = "2.17.2" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, - {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, -] - -[package.extras] -plugins = ["importlib-metadata"] -windows-terminal = ["colorama (>=0.4.6)"] - [[package]] name = "pyjwt" version = "2.8.0" @@ -1963,17 +1792,6 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] -[[package]] -name = "snowballstemmer" -version = "2.2.0" -description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -optional = false -python-versions = "*" -files = [ - {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, - {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, -] - [[package]] name = "snowflake-connector-python" version = "3.6.0" @@ -2050,201 +1868,15 @@ files = [ {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, ] -[[package]] -name = "sphinx" -version = "7.2.6" -description = "Python documentation generator" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinx-7.2.6-py3-none-any.whl", hash = "sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560"}, - {file = "sphinx-7.2.6.tar.gz", hash = "sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5"}, -] - -[package.dependencies] -alabaster = ">=0.7,<0.8" -babel = ">=2.9" -colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.18.1,<0.21" -imagesize = ">=1.3" -importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} -Jinja2 = ">=3.0" -packaging = ">=21.0" -Pygments = ">=2.14" -requests = ">=2.25.0" -snowballstemmer = ">=2.0" -sphinxcontrib-applehelp = "*" -sphinxcontrib-devhelp = "*" -sphinxcontrib-htmlhelp = ">=2.0.0" -sphinxcontrib-jsmath = "*" -sphinxcontrib-qthelp = "*" -sphinxcontrib-serializinghtml = ">=1.1.9" - -[package.extras] -docs = ["sphinxcontrib-websupport"] -lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy (>=0.990)", "ruff", "sphinx-lint", "types-requests"] -test = ["cython (>=3.0)", "filelock", "html5lib", "pytest (>=4.6)", "setuptools (>=67.0)"] - -[[package]] -name = "sphinx-rtd-theme" -version = "1.3.0" -description = "Read the Docs theme for Sphinx" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" -files = [ - {file = "sphinx_rtd_theme-1.3.0-py2.py3-none-any.whl", hash = "sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0"}, - {file = "sphinx_rtd_theme-1.3.0.tar.gz", hash = "sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931"}, -] - -[package.dependencies] -docutils = "<0.19" -sphinx = ">=1.6,<8" -sphinxcontrib-jquery = ">=4,<5" - -[package.extras] -dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"] - -[[package]] -name = "sphinx-sitemap" -version = "2.5.1" -description = "Sitemap generator for Sphinx" -optional = false -python-versions = "*" -files = [ - {file = "sphinx-sitemap-2.5.1.tar.gz", hash = "sha256:984bef068bbdbc26cfae209a8b61392e9681abc9191b477cd30da406e3a60ee5"}, - {file = "sphinx_sitemap-2.5.1-py3-none-any.whl", hash = "sha256:0b7bce2835f287687f75584d7695e4eb8efaec028e5e7b36e9f791de3c344686"}, -] - -[package.dependencies] -sphinx = ">=1.2" - -[[package]] -name = "sphinxcontrib-applehelp" -version = "1.0.7" -description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_applehelp-1.0.7-py3-none-any.whl", hash = "sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d"}, - {file = "sphinxcontrib_applehelp-1.0.7.tar.gz", hash = "sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa"}, -] - -[package.dependencies] -Sphinx = ">=5" - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-devhelp" -version = "1.0.5" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_devhelp-1.0.5-py3-none-any.whl", hash = "sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f"}, - {file = "sphinxcontrib_devhelp-1.0.5.tar.gz", hash = "sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212"}, -] - -[package.dependencies] -Sphinx = ">=5" - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-htmlhelp" -version = "2.0.4" -description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_htmlhelp-2.0.4-py3-none-any.whl", hash = "sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9"}, - {file = "sphinxcontrib_htmlhelp-2.0.4.tar.gz", hash = "sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a"}, -] - -[package.dependencies] -Sphinx = ">=5" - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["html5lib", "pytest"] - -[[package]] -name = "sphinxcontrib-jquery" -version = "4.1" -description = "Extension to include jQuery on newer Sphinx releases" -optional = false -python-versions = ">=2.7" -files = [ - {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"}, - {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"}, -] - -[package.dependencies] -Sphinx = ">=1.8" - -[[package]] -name = "sphinxcontrib-jsmath" -version = "1.0.1" -description = "A sphinx extension which renders display math in HTML via JavaScript" -optional = false -python-versions = ">=3.5" -files = [ - {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, - {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, -] - -[package.extras] -test = ["flake8", "mypy", "pytest"] - -[[package]] -name = "sphinxcontrib-qthelp" -version = "1.0.6" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_qthelp-1.0.6-py3-none-any.whl", hash = "sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4"}, - {file = "sphinxcontrib_qthelp-1.0.6.tar.gz", hash = "sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d"}, -] - -[package.dependencies] -Sphinx = ">=5" - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-serializinghtml" -version = "1.1.9" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_serializinghtml-1.1.9-py3-none-any.whl", hash = "sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1"}, - {file = "sphinxcontrib_serializinghtml-1.1.9.tar.gz", hash = "sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54"}, -] - -[package.dependencies] -Sphinx = ">=5" - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - [[package]] name = "sqlglot" -version = "20.7.1" +version = "20.8.0" description = "An easily customizable SQL parser and transpiler" optional = false python-versions = ">=3.7" files = [ - {file = "sqlglot-20.7.1-py3-none-any.whl", hash = "sha256:e7a792578fc68ead866ab724fdd4ae39f3e6b0e1cdc2664eeb8527f9a013fcdb"}, - {file = "sqlglot-20.7.1.tar.gz", hash = "sha256:657e37bba1ef0209bd558f545f38e29456b312a3a1d5211698ffb9ac6699c21f"}, + {file = "sqlglot-20.8.0-py3-none-any.whl", hash = "sha256:cb73b81a26da462c34b12b98cf193d679d4b5693703d309db236d9784cef60bb"}, + {file = "sqlglot-20.8.0.tar.gz", hash = "sha256:5636e97fab9efdb4a8690c0e32bbd2d657fe91eb650f10e913a56b4bd979faef"}, ] [package.extras] @@ -2348,21 +1980,6 @@ platformdirs = ">=3.9.1,<5" docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] -[[package]] -name = "zipp" -version = "3.17.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.8" -files = [ - {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, - {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] - [extras] bigquery = ["google-cloud-bigquery"] clickhouse = ["clickhouse-driver"] @@ -2372,4 +1989,4 @@ snowflake = ["snowflake-connector-python"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "fd148fa065ad96cae78f4e3253e16a0884c084379fdadfd91f6a6c014ee5e3a2" +content-hash = "37ad23f4fa90cc838f46291f75a5e16a1d23f04b4d62f383020960f5691a4cdc" diff --git a/pyproject.toml b/pyproject.toml index 268d6bd..a3ac3d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,12 +69,6 @@ pre-commit = "^3.5.0" black = "^23.9.1" isort = "^5.12.0" flake8 = "^6.1.0" -sphinx-sitemap = "^2.5.1" - -[tool.poetry.group.dev.dependencies] -sphinx = "^7.2.6" -sphinx-rtd-theme = "^1.3.0" -myst-parser = "^2.0.0" [build-system] requires = ["poetry-core>=1.0.0"]