diff --git a/docs_compiled/.buildinfo b/docs_compiled/.buildinfo
new file mode 100644
index 00000000000..617bec45f58
--- /dev/null
+++ b/docs_compiled/.buildinfo
@@ -0,0 +1,4 @@
+# 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: 4b5b798c218be8b525555109e783a46f
+tags: 645f666f9bcd5a90fca523b33c5a78b7
diff --git a/docsrc/Connecting_and_queries.rst b/docsrc/Connecting_and_queries.rst
index ca9444af31b..0536ff6d50f 100644
--- a/docsrc/Connecting_and_queries.rst
+++ b/docsrc/Connecting_and_queries.rst
@@ -3,19 +3,22 @@
Connecting and running queries
###############################
-This topic provides a walkthrough and examples for how to use the Firebolt Python SDK to connect to Firebolt resources to run commands and query data.
+This topic provides a walkthrough and examples for how to use the Firebolt Python SDK to
+connect to Firebolt resources to run commands and query data.
Setting up a connection
=========================
-To connect to a Firebolt database to run queries or command, you must provide your account credentials through a connection request.
+To connect to a Firebolt database to run queries or command, you must provide your account
+credentials through a connection request.
To get started, follow the steps below:
**1. Import modules**
- The Firebolt Python SDK requires you to import the following modules before making any command or query requests to your Firebolt database.
+ The Firebolt Python SDK requires you to import the following modules before making
+ any command or query requests to your Firebolt database.
.. _required_connection_imports:
@@ -50,9 +53,11 @@ To get started, follow the steps below:
* **Set credentials manually**
- You can manually include your account information in a connection object in your code for any queries you want to request.
+ You can manually include your account information in a connection object in
+ your code for any queries you want to request.
- Replace the values in the example code below with your Firebolt account credentials as appropriate.
+ Replace the values in the example code below with your Firebolt account
+ credentials as appropriate.
::
@@ -73,7 +78,9 @@ To get started, follow the steps below:
* **Use an .env file**
- Consolidating all of your Firebolt credentials into a ``.env`` file can help protect sensitive information from exposure. Create an ``.env`` file with the following key-value pairs, and replace the values with your information.
+ Consolidating all of your Firebolt credentials into a ``.env`` file can help
+ protect sensitive information from exposure. Create an ``.env`` file with the
+ following key-value pairs, and replace the values with your information.
::
@@ -84,7 +91,10 @@ To get started, follow the steps below:
Be sure to place this ``.env`` file into your root directory.
- Your connection script can load these environmental variables from the ``.env`` file by using the `python-dotenv `_ package. Note that the example below imports the ``os`` and ``dotenv`` modules in order to load the environmental variables.
+ Your connection script can load these environmental variables from the ``.env``
+ file by using the `python-dotenv `_
+ package. Note that the example below imports the ``os`` and ``dotenv`` modules
+ in order to load the environmental variables.
::
@@ -94,10 +104,10 @@ To get started, follow the steps below:
load_dotenv()
connection = connect(
- username=os.getenv('FIREBOLT_USER'),
- password=os.getenv('FIREBOLT_PASSWORD'),
- engine_name=os.getenv('FIREBOLT_ENGINE'),
- database=os.getenv('FIREBOLT_DB')
+ username=os.getenv('FIREBOLT_USER'),
+ password=os.getenv('FIREBOLT_PASSWORD'),
+ engine_name=os.getenv('FIREBOLT_ENGINE'),
+ database=os.getenv('FIREBOLT_DB')
)
cursor = connection.cursor()
@@ -105,10 +115,11 @@ To get started, follow the steps below:
**3. Execute commands using the cursor**
- The ``cursor`` object can be used to send queries and commands to your Firebolt database and engine. See below for examples of functions using the ``cursor`` object.
+ The ``cursor`` object can be used to send queries and commands to your Firebolt
+ database and engine. See below for examples of functions using the ``cursor`` object.
Server-side synchronous command and query examples
-============================
+==================================================
This section includes Python examples of various SQL commands and queries.
@@ -118,42 +129,48 @@ Inserting and selecting data
.. _basic_execute_example:
-The example below uses ``cursor`` to create a new table called ``test_table``, insert rows into it, and then select the table's contents.
+The example below uses ``cursor`` to create a new table called ``test_table``, insert
+rows into it, and then select the table's contents.
-The engine attached to your specified database must be started before executing any queries. For help, see :ref:`starting an engine`.
+The engine attached to your specified database must be started before executing any
+queries. For help, see :ref:`managing_resources:starting an engine`.
::
cursor.execute(
- '''CREATE FACT TABLE IF NOT EXISTS test_table (
- id INT,
- name TEXT
- )
- PRIMARY INDEX id;'''
- )
+ """
+ CREATE FACT TABLE IF NOT EXISTS test_table (
+ id INT,
+ name TEXT
+ )
+ PRIMARY INDEX id;
+ """
+ )
cursor.execute(
- '''INSERT INTO test_table VALUES
- (1, 'hello'),
- (2, 'world'),
- (3, '!');'''
- )
+ """
+ INSERT INTO test_table VALUES
+ (1, 'hello'),
+ (2, 'world'),
+ (3, '!');
+ """
+ )
- cursor.execute(
- '''SELECT * FROM test_table;'''
- )
+ cursor.execute("SELECT * FROM test_table;")
cursor.close()
.. note::
- For reference documentation on ``cursor`` functions, see :ref:`Db.cursor`
+ For reference documentation on ``cursor`` functions, see :ref:`cursor `.
Fetching query results
-----------------------
-After running a query, you can fetch the results using a ``cursor`` object. The examples below use the data queried from ``test_table`` created in the :ref:`Inserting and selecting data`.
+After running a query, you can fetch the results using a ``cursor`` object. The examples
+below use the data queried from ``test_table`` created in the
+:ref:`connecting_and_queries:Inserting and selecting data`.
.. _fetch_example:
@@ -181,45 +198,53 @@ Executing parameterized queries
.. _parameterized_query_execute_example:
-Parameterized queries (also known as “prepared statements”) format a SQL query with placeholders and then pass values into those placeholders when the query is run. This protects against SQL injection attacks and also helps manage dynamic queries that are likely to change, such as filter UIs or access control.
+Parameterized queries (also known as “prepared statements”) format a SQL query with
+placeholders and then pass values into those placeholders when the query is run. This
+protects against SQL injection attacks and also helps manage dynamic queries that are
+likely to change, such as filter UIs or access control.
-To run a parameterized query, use the ``execute()`` cursor method. Add placeholders to your statement using question marks ``?``, and in the second argument pass a tuple of parameters equal in length to the number of ``?`` in the statement.
+To run a parameterized query, use the ``execute()`` cursor method. Add placeholders to
+your statement using question marks ``?``, and in the second argument pass a tuple of
+parameters equal in length to the number of ``?`` in the statement.
::
cursor.execute(
- '''CREATE FACT TABLE IF NOT EXISTS test_table2 (
- id INT,
- name TEXT,
- date_value DATE
- )
- PRIMARY INDEX id;'''
- )
+ """
+ CREATE FACT TABLE IF NOT EXISTS test_table2 (
+ id INT,
+ name TEXT,
+ date_value DATE
+ )
+ PRIMARY INDEX id;"""
+ )
::
cursor.execute(
- "INSERT INTO test_table2 VALUES (?, ?, ?)",
- (1, "apple", "2018-01-01"),
- )
+ "INSERT INTO test_table2 VALUES (?, ?, ?)",
+ (1, "apple", "2018-01-01"),
+ )
cursor.close()
.. _parameterized_query_executemany_example:
-If you need to run the same statement multiple times with different parameter inputs, you can use the ``executemany()`` cursor method. This allows multiple tuples to be passed as values in the second argument.
+If you need to run the same statement multiple times with different parameter inputs,
+you can use the ``executemany()`` cursor method. This allows multiple tuples to be passed
+as values in the second argument.
::
cursor.executemany(
- "INSERT INTO test_table2 VALUES (?, ?, ?)",
- (
- (2, "banana", "2019-01-01"),
- (3, "carrot", "2020-01-01"),
- (4, "donut", "2021-01-01")
- )
+ "INSERT INTO test_table2 VALUES (?, ?, ?)",
+ (
+ (2, "banana", "2019-01-01"),
+ (3, "carrot", "2020-01-01"),
+ (4, "donut", "2021-01-01")
+ )
)
cursor.close()
@@ -229,16 +254,18 @@ If you need to run the same statement multiple times with different parameter in
Executing multiple-statement queries
--------------------------------------
-Multiple-statement queries allow you to run a series of SQL statements sequentially with just one method call. Statements are separated using a semicolon ``;``, similar to making SQL statements in the Firebolt UI.
+Multiple-statement queries allow you to run a series of SQL statements sequentially with
+just one method call. Statements are separated using a semicolon ``;``, similar to making
+SQL statements in the Firebolt UI.
::
cursor.execute(
- """
- SELECT * FROM test_table WHERE id < 4;
- SELECT * FROM test_table WHERE id > 2;
- """
- )
+ """
+ SELECT * FROM test_table WHERE id < 4;
+ SELECT * FROM test_table WHERE id > 2;
+ """
+ )
print("First query: ", cursor.fetchall())
assert cursor.nextset()
print("Second query: ", cursor.fetchall())
@@ -250,8 +277,11 @@ Multiple-statement queries allow you to run a series of SQL statements sequentia
::
- First query: [[2, 'banana', datetime.date(2019, 1, 1)], [3, 'carrot', datetime.date(2020, 1, 1)], [1, 'apple', datetime.date(2018, 1, 1)]]
- Second query: [[3, 'carrot', datetime.date(2020, 1, 1)], [4, 'donut', datetime.date(2021, 1, 1)]]
+ First query: [[2, 'banana', datetime.date(2019, 1, 1)],
+ [3, 'carrot', datetime.date(2020, 1, 1)],
+ [1, 'apple', datetime.date(2018, 1, 1)]]
+ Second query: [[3, 'carrot', datetime.date(2020, 1, 1)],
+ [4, 'donut', datetime.date(2021, 1, 1)]]
.. note::
@@ -262,75 +292,96 @@ Multiple-statement queries allow you to run a series of SQL statements sequentia
Server-side asynchronous query execution
==========================================
-Server-side asynchronous query execution allows you to run a long query in the background while executing other asynchronous or synchronous queries. An additional benefit of server-side async execution that can free up a connection, close a connection while running a query, or potentially even spin down an entire service (such as AWS Lambda) while a long-running database job is still underway. Note that it is not possible to retrieve the results of a server-side asynchronous query, so these queries are best used for running DMLs and DDLs. SELECTs should be used only for warming the cache.
+In addition to :ref:`asynchronous API calls `, which allow `client-side`
+execution to continue while waiting for API responses, the Python SDK provides `server-side`
+asynchronous query execution. When a query is executed asynchronously the only response
+from the server is a query ID. The status of the query can then be retrieved by polling
+the server at a later point. This frees the connection to do other queries or even be
+closed while the query continues to run. And entire service, such as AWS Lamdba, could
+potentially even be spun down an entire while a long-running database job is still underway.
-Running DDL commands
------------------------------
+Note, however, that it is not possible to retrieve the results of a server-side asynchronous
+query, so these queries are best used for running DMLs and DDLs and ``SELECT``\ s should be used
+only for warming the cache.
-.. _basic_execute_example:
+Executing asynchronous DDL commands
+------------------------------------
+
+.. _ddl_execution_example:
-Running queries server-side asynchronously is similar to running server-side asynchronous queries, but the ``execute()`` command receives an extra parameter, ``async_execution=True``. The example below uses ``cursor`` to create a new table called ``test_table``. ``execute(query, async_execution=True)`` will return a query ID, which can subsequently be used to check the query status.
+Executing queries server-side asynchronously is similar to executing server-side synchronous
+queries, but the ``execute()`` command receives an extra parameter, ``async_execution=True``.
+The example below uses ``cursor`` to create a new table called ``test_table``.
+``execute(query, async_execution=True)`` will return a query ID, which can subsequently
+be used to check the query status.
::
- query_id = cursor.execute(
- '''CREATE FACT TABLE IF NOT EXISTS test_table (
- id INT,
- name TEXT
- )
- PRIMARY INDEX id;''',
- async_execution=True
- )
+ query_id = cursor.execute(
+ """
+ CREATE FACT TABLE IF NOT EXISTS test_table (
+ id INT,
+ name TEXT
+ )
+ PRIMARY INDEX id;
+ """,
+ async_execution=True
+ )
-To check the status of a query, send the query ID to ```get_status()``` to receive a QueryStatus enumeration object. Possible statuses are:
+To check the status of a query, send the query ID to ```get_status()``` to receive a
+QueryStatus enumeration object. Possible statuses are:
- * ``RUNNING``
- * ``ENDED_SUCCESSFULLY``
- * ``ENDED_UNSUCCESSFULLY``
- * ``NOT_READY``
- * ``STARTED_EXECUTION``
- * ``PARSE_ERROR``
- * ``CANCELED_EXECUTION``
- * ``EXECUTION_ERROR``
+ * ``RUNNING``
+ * ``ENDED_SUCCESSFULLY``
+ * ``ENDED_UNSUCCESSFULLY``
+ * ``NOT_READY``
+ * ``STARTED_EXECUTION``
+ * ``PARSE_ERROR``
+ * ``CANCELED_EXECUTION``
+ * ``EXECUTION_ERROR``
-Once the status of the table creation is ``ENDED_SUCCESSFULLY`` created, data can be inserted into it:
+Once the status of the table creation is ``ENDED_SUCCESSFULLY``, data can be inserted into it:
::
- from firebolt.async_db.cursor import QueryStatus
+ from firebolt.async_db.cursor import QueryStatus
- query_status = cursor.get_status(query_id)
+ query_status = cursor.get_status(query_id)
- if query_status == QueryStatus.ENDED_SUCCESSFULLY:
- cursor.execute(
- '''INSERT INTO test_table VALUES
- (1, 'hello'),
- (2, 'world'),
- (3, '!');'''
- )
+ if query_status == QueryStatus.ENDED_SUCCESSFULLY:
+ cursor.execute(
+ """
+ INSERT INTO test_table VALUES
+ (1, 'hello'),
+ (2, 'world'),
+ (3, '!');
+ """
+ )
In addition, server-side asynchronous queries can be cancelled calling ``cancel()``.
::
- query_id = cursor.execute(
- '''CREATE FACT TABLE IF NOT EXISTS test_table (
- id INT,
- name TEXT
- )
- PRIMARY INDEX id;''',
- async_execution=True
- )
+ query_id = cursor.execute(
+ """
+ CREATE FACT TABLE IF NOT EXISTS test_table (
+ id INT,
+ name TEXT
+ )
+ PRIMARY INDEX id;
+ """,
+ async_execution=True
+ )
- cursor.cancel(query_id)
+ cursor.cancel(query_id)
- query_status = cursor.get_status(query_id)
+ query_status = cursor.get_status(query_id)
- print(query_status)
+ print(query_status)
**Returns**: ``CANCELED_EXECUTION``
@@ -339,13 +390,16 @@ In addition, server-side asynchronous queries can be cancelled calling ``cancel(
Using DATE and DATETIME values
==============================
-DATE, DATETIME and TIMESTAMP values used in SQL insertion statements must be provided in a specific format; otherwise they could be read incorrectly.
+DATE, DATETIME and TIMESTAMP values used in SQL insertion statements must be provided in
+a specific format; otherwise they could be read incorrectly.
* DATE values should be formatted as **YYYY-MM-DD**
* DATETIME and TIMESTAMP values should be formatted as **YYYY-MM-DD HH:MM:SS.SSSSSS**
-The `datetime `_ module from the Python standard library contains various classes and methods to format DATE, TIMESTAMP and DATETIME data types.
+The `datetime `_ module from the Python
+standard library contains various classes and methods to format DATE, TIMESTAMP and
+DATETIME data types.
You can import this module as follows:
diff --git a/docsrc/Managing_resources.rst b/docsrc/Managing_resources.rst
index 4e2e9051b8f..f74fc120889 100644
--- a/docsrc/Managing_resources.rst
+++ b/docsrc/Managing_resources.rst
@@ -2,23 +2,26 @@
Managing engines and databases
#####################################
-This topic provides a walkthrough and examples for using the Firebolt Python SDK to create and modify Firebolt databases and engines.
+This topic provides a walkthrough and examples for using the Firebolt Python SDK to
+create and modify Firebolt databases and engines.
Setting up a ResourceManager object
====================================
-You can perform various functions on Firebolt databases and engines by calling a ``ResourceManager`` object, which must be configured with its own user credentials through the imported ``Settings`` class.
+You can perform various functions on Firebolt databases and engines by calling a
+``ResourceManager`` object, which must be configured with its own user credentials
+through the imported ``Settings`` class.
-To get started, follow the steps below:
+To get started, follow the steps below:
**1. Import modules**
- To initialize a ``ResourceManager`` object, import the modules shown below.
+ To initialize a ``ResourceManager`` object, import the modules shown below.
.. _required_resourcemanager_imports:
- ::
+ ::
from firebolt.service.manager import ResourceManager
from firebolt.common import Settings
@@ -26,9 +29,10 @@ To get started, follow the steps below:
**2. Initialize a Settings object**
- A Settings object contains the user credentials and other information needed to manage Firebolt databases and engines.
+ A Settings object contains the user credentials and other information needed to
+ manage Firebolt databases and engines.
- The Settings object uses the following parameters:
+ The Settings object uses the following parameters:
+---------------------+-----------------------------------------------------------------------------------------------------------------------------+
| ``user`` | The email address associated with your Firebolt user profile. |
@@ -44,31 +48,32 @@ To get started, follow the steps below:
- A ``Settings`` object can be configured with parameters by multiple methods.
+ A ``Settings`` object can be configured with parameters by multiple methods.
- * Add the parameters manually in your command script:
+ * Add the parameters manually in your command script:
- ::
+ ::
settings = Settings(
- user="your_username",
- password="your_password",
- server="api.app.firebolt.io"
- default_region="your_region"
- )
+ user="your_username",
+ password="your_password",
+ server="api.app.firebolt.io"
+ default_region="your_region"
+ )
- * Use a ``.env`` file located in your root directory containing the following parameters:
+ * Use a ``.env`` file located in your root directory containing the following parameters:
- ::
+ ::
FIREBOLT_USER="your_username",
FIREBOLT_PASSWORD="your_password",
FIREBOLT_SERVER="api.app.firebolt.io"
FIREBOLT_DEFAULT_REGION="your_region"
- In your application file, the ``Settings`` object can read the values from the ``.env`` file if it is set to ``None`` instead of having values, as shown below:
+ In your application file, the ``Settings`` object can read the values from the
+ ``.env`` file if it is set to ``None`` instead of having values, as shown below:
- ::
+ ::
settings = None
@@ -76,32 +81,36 @@ To get started, follow the steps below:
**3. Initialize a ResourceManager object**
- After the ``Settings`` are configured, create a ``ResourceManager`` object, which is given the variable name ``rm`` in the example below.
+ After the ``Settings`` are configured, create a ``ResourceManager`` object, which is
+ given the variable name ``rm`` in the example below.
- ::
+ ::
rm = ResourceManager(settings=settings)
- .. note::
-
- Subsequent examples on this page use the ``rm`` object for database and engine functions.
+ .. note::
+
+ Subsequent examples on this page use the ``rm`` object for database and engine functions.
Database function examples
====================================
-This section includes Python examples of various common functions for creating and managing Firebolt resources.
+This section includes Python examples of various common functions for creating and managing
+Firebolt resources.
-Listing out databases
+Listing out databases
------------------------
-List out the names of all databases under your account by using the ``get_many`` function.
+List out the names of all databases under your account by using the ``get_many`` function.
- **List out all databases and their metadata**
+ **List out all databases and their metadata**
- This produces an inventory of all databases and their metadata from your account. The Python `devtools `_ module used in the example below helps format the metadata to be more readable.
+ This produces an inventory of all databases and their metadata from your account.
+ The Python `devtools `_ module used in the
+ example below helps format the metadata to be more readable.
::
@@ -112,49 +121,53 @@ List out the names of all databases under your account by using the ``get_many``
**Listing out databases by name**
- This function call lists out the names of your databases, but it can be modified to list out other attributes. This is helpful for tracking down a particular database in your account.
+ This function call lists out the names of your databases, but it can be modified
+ to list out other attributes. This is helpful for tracking down a particular
+ database in your account.
- ::
+ ::
all_dbs = rm.databases.get_many()
all_db_names = [d.name for d in all_dbs]
- for db in db_names:
- print(db)
+ for db in db_names:
+ print(db)
.. note::
- For a list of all database attributes, see :ref:`model.database`.
+ For a list of all database attributes, see :ref:`model-database`.
Creating a new database
-------------------------
-Launch a new database and use it to create a ``database`` object.
+Launch a new database and use it to create a ``database`` object.
-A newly created database uses the default region from your Settings unless you specify a different region as a parameter.
+A newly created database uses the default region from your Settings unless you specify a different region as a parameter.
::
database = rm.databases.create(name="database_name", region="us-east-1")
- .. note::
+ .. note::
- For a list of all database parameters, see :ref:`Service.database`
+ For a list of all database parameters, see :ref:`service-database`
Locating a database
---------------------
-Find a specific Firebolt database by using its name or ID. These functions are useful as a starting point to create a ``database`` object that can be called in other database functions.
+Find a specific Firebolt database by using its name or ID. These functions are useful as
+a starting point to create a ``database`` object that can be called in other database functions.
-In the examples below, replace the values for ``database_name`` and ``database_id`` with your database name or ID.
+In the examples below, replace the values for ``database_name`` and ``database_id`` with
+your database name or ID.
**Locating by name**
- ::
+ ::
database = rm.databases.get_by_name(name="database_name")
@@ -168,10 +181,12 @@ In the examples below, replace the values for ``database_name`` and ``database_i
Getting database status
-------------------------
-Use the Python `devtools `_ module to format metadata from a ``database`` object. This is a helpful command to run after a database operation to check if its execution was successful.
+Use the Python `devtools `_ module to format metadata
+from a ``database`` object. This is a helpful command to run after a database operation to
+check if its execution was successful.
+
+ ::
- ::
-
from devtools import debug
debug(database)
@@ -179,33 +194,36 @@ Use the Python `devtools `_ module to format
Dropping a database
-----------------------
-Delete a database by calling the ``delete`` function. The database is deleted along with all of its tables.
+Delete a database by calling the ``delete`` function. The database is deleted along with
+all of its tables.
+
+ ::
- ::
-
database.delete()
Engine function examples
====================================
-This section includes Python examples of various common functions for creating and managing Firebolt engines.
+This section includes Python examples of various common functions for creating and managing
+Firebolt engines.
Creating an engine
--------------------
-Launch a new Firebolt engine and create an ``engine`` object. The created engine uses the default region included in your Settings unless you specify a different region as a parameter.
+Launch a new Firebolt engine and create an ``engine`` object. The created engine uses the
+default region included in your Settings unless you specify a different region as a parameter.
- ::
+ ::
engine = rm.engines.create(name="engine_name")
-.. note::
+.. note::
- For a list of all engine parameters, see :ref:`Service.engine`
+ For a list of all engine parameters, see :ref:`service-engine`
@@ -216,7 +234,9 @@ List out the names of all engines under your account by using the ``get_many`` f
**List out all engines and metadata**
- This produces an inventory of all engines and their metadata from your account. The Python `devtools `_ module used in the example below helps format the metadata to be more readable.
+ This produces an inventory of all engines and their metadata from your account.
+ The Python `devtools `_ module used in the
+ example below helps format the metadata to be more readable.
::
@@ -226,26 +246,30 @@ List out the names of all engines under your account by using the ``get_many`` f
**List out engines by name**
- This function call lists out the names of your engines, but it can be modified to list out other attributes. This is helpful for tracking down a particular engine in your account.
+ This function call lists out the names of your engines, but it can be modified to
+ list out other attributes. This is helpful for tracking down a particular engine
+ in your account.
::
all_engines = rm.engines.get_many()
all_engine_names = [e.name for e in all_engines]
- for name in all_engine_names:
- print(name)
+ for name in all_engine_names:
+ print(name)
- .. note::
+ .. note::
- For a list of all engine attributes, see :ref:`Model.engine`
+ For a list of all engine attributes, see :ref:`model-engine`
Locating an engine
--------------------
-Find a specific Firebolt engine by using its name or ID. These functions are useful as a starting point to create an ``engine`` object that can be called in other engine functions.
+Find a specific Firebolt engine by using its name or ID. These functions are useful as a
+starting point to create an ``engine`` object that can be called in other engine functions.
-In the examples below, replace the values for ``engine_name`` and ``engine_id`` with your engine name or ID.
+In the examples below, replace the values for ``engine_name`` and ``engine_id`` with your
+engine name or ID.
**Locating by name**
@@ -263,20 +287,23 @@ In the examples below, replace the values for ``engine_name`` and ``engine_id``
Attaching an engine
---------------------
-Attach an engine to a database. An engine must be attached to a database and started before it can run SQL commands or queries.
+Attach an engine to a database. An engine must be attached to a database and started before
+it can run SQL commands or queries.
- ::
+ ::
engine = rm.engines.get_by_name(name="engine_name")
engine.attach_to_database(
- database=rm.databases.get_by_name(name="database_name"))
+ database=rm.databases.get_by_name(name="database_name")
+ )
Dropping an engine
--------------------
-Delete an engine by calling the ``delete`` function. The engine is removed from its attached database and deleted.
+Delete an engine by calling the ``delete`` function. The engine is removed from its attached
+database and deleted.
::
@@ -286,18 +313,20 @@ Delete an engine by calling the ``delete`` function. The engine is removed from
Starting an engine
-------------------
-Start an engine by calling the ``start`` function on an ``engine`` object. An engine must be attached to a database and started before it can run SQL commands or queries.
+Start an engine by calling the ``start`` function on an ``engine`` object. An engine must
+be attached to a database and started before it can run SQL commands or queries.
::
- engine.start()
+ engine.start()
Stopping an engine
--------------------
-Stop an engine by calling the ``stop`` function. When stopped, an engine is not available to run queries and does not accrue additional usage time on your account.
+Stop an engine by calling the ``stop`` function. When stopped, an engine is not available
+to run queries and does not accrue additional usage time on your account.
::
@@ -306,7 +335,8 @@ Stop an engine by calling the ``stop`` function. When stopped, an engine is not
Updating an engine
---------------------
-Update an engine to change its specifications, returning an updated version of the engine. The engine must be stopped in order to be updated.
+Update an engine to change its specifications, returning an updated version of the engine.
+The engine must be stopped in order to be updated.
For a list of engine parameters that can be updated, see :meth:`~firebolt.model.engine.Engine.update`
@@ -317,10 +347,12 @@ For a list of engine parameters that can be updated, see :meth:`~firebolt.model.
Getting engine status
----------------------
-Use the Python `devtools `_ module to format metadata from an ``engine`` object. This is a helpful command to run after an engine operation to check if its execution was successful.
+Use the Python `devtools `_ module to format metadata
+from an ``engine`` object. This is a helpful command to run after an engine operation to
+check if its execution was successful.
+
+ ::
- ::
-
from devtools import debug
debug(engine)
diff --git a/docsrc/conf.py b/docsrc/conf.py
index 244adc12792..83db51471f5 100644
--- a/docsrc/conf.py
+++ b/docsrc/conf.py
@@ -42,6 +42,7 @@
"sphinx.ext.napoleon",
"sphinx.ext.autosectionlabel",
]
+autosectionlabel_prefix_document = True
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
diff --git a/docsrc/firebolt.async_db.rst b/docsrc/firebolt.async_db.rst
index ef952c49cd3..cc1cbf4a9bc 100644
--- a/docsrc/firebolt.async_db.rst
+++ b/docsrc/firebolt.async_db.rst
@@ -1,16 +1,16 @@
==========================
-Async DB
+Async db
==========================
-The Async DB package enables connecting to a Firebolt database for `client-side` asynchronous queries. For running queries in `server-side` asynchronous mode see :ref:`server-side asynchronous query execution`.
+The async_db package enables asynchronous API calls to a Firebolt database, allowing
+client-side processes to continue to run while waiting for API responses. For executing
+queries asynchronously `server-side` see
+:ref:`connecting_and_queries:server-side asynchronous query execution`.
-Connect
+connect
------------------------------------
-.. automodule:: firebolt.async_db.connect
- :members:
- :undoc-members:
- :show-inheritance:
+.. autofunction:: firebolt.async_db.connection.connect
Connection
------------------------------------
@@ -21,7 +21,7 @@ Connection
.. automodule:: firebolt.async_db.connection
:members:
:inherited-members:
- :exclude-members: BaseConnection, async_connect_factory, OverriddenHttpBackend
+ :exclude-members: BaseConnection, async_connect_factory, OverriddenHttpBackend, connect
:undoc-members:
:show-inheritance:
@@ -34,12 +34,10 @@ Cursor
:undoc-members:
:show-inheritance:
-..
-
- Util
- ------------------------------
+Util
+------------------------------
- .. automodule:: firebolt.async_db.util
- :members:
- :undoc-members:
- :show-inheritance:
+.. automodule:: firebolt.async_db.util
+ :members:
+ :undoc-members:
+ :show-inheritance:
diff --git a/docsrc/firebolt.common.rst b/docsrc/firebolt.common.rst
index d7d2a1c6849..d2c022d7f6b 100644
--- a/docsrc/firebolt.common.rst
+++ b/docsrc/firebolt.common.rst
@@ -4,21 +4,12 @@ Common
The common package contains settings parameters and error exceptions.
-..
-
- Exception
- --------------------------------
-
- .. automodule:: firebolt.common.exception
- :members:
- :undoc-members:
- :show-inheritance:
-
Settings
-------------------------------
.. automodule:: firebolt.common.settings
- :exclude-members: Config, access_token, account_name, auth, default_region, mutual_exclusive_with_creds, password, server, use_token_cache, user
+ :exclude-members: Config, access_token, account_name, auth, default_region,
+ mutual_exclusive_with_creds, password, server, use_token_cache, user
:members:
:undoc-members:
:show-inheritance:
@@ -31,29 +22,27 @@ Exception
:undoc-members:
:show-inheritance:
-..
-
- URLs
- ---------------------------
+URLs
+---------------------------
- .. automodule:: firebolt.common.urls
- :members:
- :undoc-members:
- :show-inheritance:
+.. automodule:: firebolt.common.urls
+ :members:
+ :undoc-members:
+ :show-inheritance:
- Storage
- -------------------------------------
+Storage
+-------------------------------------
- .. automodule:: firebolt.common.token_storage
- :members:
- :undoc-members:
- :show-inheritance:
+.. automodule:: firebolt.common.token_storage
+ :members:
+ :undoc-members:
+ :show-inheritance:
- Util
- ---------------------------
+Util
+---------------------------
- .. automodule:: firebolt.common.util
- :exclude-members: async_to_sync, cached_property, fix_url_schema, mixin_for, prune_dict
- :members:
- :undoc-members:
- :show-inheritance:
+.. automodule:: firebolt.common.util
+ :exclude-members: async_to_sync, cached_property, fix_url_schema, mixin_for, prune_dict
+ :members:
+ :undoc-members:
+ :show-inheritance:
diff --git a/docsrc/firebolt.db.rst b/docsrc/firebolt.db.rst
index d9e0db3300b..5bc47346258 100644
--- a/docsrc/firebolt.db.rst
+++ b/docsrc/firebolt.db.rst
@@ -1,17 +1,13 @@
===================
-DB
+db
===================
The DB package enables connecting to a Firebolt database for synchronous queries.
-Connect
+connect
-----------------------------
-.. automodule:: firebolt.db.connect
- :members:
- :inherited-members:
- :undoc-members:
- :show-inheritance:
+.. autofunction:: firebolt.db.connection.connect
Connection
-----------------------------
diff --git a/docsrc/firebolt.model.rst b/docsrc/firebolt.model.rst
index 0d97fc8c62b..02c1ab9c891 100644
--- a/docsrc/firebolt.model.rst
+++ b/docsrc/firebolt.model.rst
@@ -4,6 +4,8 @@ Model
The model package contains various classes and functions for managing Firebolt engines and databases.
+.. _model-database:
+
Database
------------------------------
@@ -13,6 +15,8 @@ Database
:undoc-members:
:show-inheritance:
+.. _model-engine:
+
Engine
----------------------------
diff --git a/docsrc/firebolt.service.rst b/docsrc/firebolt.service.rst
index b99603b757c..946f994504f 100644
--- a/docsrc/firebolt.service.rst
+++ b/docsrc/firebolt.service.rst
@@ -16,6 +16,8 @@ The service package enables launching and cataloging Firebolt engines and databa
:undoc-members:
:show-inheritance:
+.. _service-database:
+
Database
--------------------------------
@@ -24,6 +26,8 @@ Database
:undoc-members:
:show-inheritance:
+.. _service-engine:
+
Engine
------------------------------
@@ -55,7 +59,7 @@ Manager
:undoc-members:
:show-inheritance:
-Service.provider
+provider
--------------------------------
.. automodule:: firebolt.service.provider
diff --git a/docsrc/index.rst b/docsrc/index.rst
index 6d9aaaaddce..4691e2e0b68 100644
--- a/docsrc/index.rst
+++ b/docsrc/index.rst
@@ -7,13 +7,15 @@
**Firebolt-python-sdk**
########################
-The Firebolt Python SDK enables connecting to Firebolt, managing Firebolt resources and executing queries using a library of Python classes and functions.
+The Firebolt Python SDK enables connecting to Firebolt, managing Firebolt resources and
+executing queries using a library of Python classes and functions.
========================
Prerequisites
========================
-* Python version 3.7 or later along with the pip package installer. For more information, see the `Python `_ web page.
+* Python version 3.7 or later along with the pip package installer. For more information,
+ see the `Python `_ web page.
* A Firebolt account and login credentials.
@@ -29,7 +31,10 @@ Use pip to install the Firebolt Python SDK from the command line as shown in the
Optional features
^^^^^^^^^^^^^^^^^^^
-By default, the Firebolt Python SDK uses the ``datetime`` module to parse date and datetime values. For large operations involving date and datetime values, the Python SDK can achieve faster results by using the `ciso8601 `_ package, however this can cause installation issues in some cases.
+By default, the Firebolt Python SDK uses the ``datetime`` module to parse date and datetime
+values. For large operations involving date and datetime values, the Python SDK can achieve
+faster results by using the `ciso8601 `_ package,
+however this can cause installation issues in some cases.
To install firebolt-python-sdk with ``ciso8601`` support, run ``pip install "firebolt-sdk[ciso8601]"``.
@@ -37,18 +42,23 @@ To install firebolt-python-sdk with ``ciso8601`` support, run ``pip install "fir
Release notes
^^^^^^^^^^^^^^
-For information about changes in the latest version of the Firebolt Python SDK, see the `release notes `_
+For information about changes in the latest version of the Firebolt Python SDK, see the
+`release notes `_
Contributing
^^^^^^^^^^^^^^
-For procedures and requirements for contributing to this SDK, see the `contributing `_ page on Github.
+For procedures and requirements for contributing to this SDK, see the
+`contributing `_
+page on Github.
License
^^^^^^^^
-The Firebolt DB API is licensed under the `Apache License Version 2.0 `_ software license.
+The Firebolt DB API is licensed under the
+`Apache License Version 2.0 `_
+software license.
.. note::
diff --git a/src/firebolt/async_db/connection.py b/src/firebolt/async_db/connection.py
index 9c802e40d3f..1061fb07b9d 100644
--- a/src/firebolt/async_db/connection.py
+++ b/src/firebolt/async_db/connection.py
@@ -356,7 +356,7 @@ async def _aclose(self) -> None:
@property
def closed(self) -> bool:
- """`True if connection is closed; False otherwise."""
+ """`True` if connection is closed; `False` otherwise."""
return self._is_closed
def _remove_cursor(self, cursor: Cursor) -> None:
diff --git a/src/firebolt/async_db/util.py b/src/firebolt/async_db/util.py
index 50dfdafdbe4..ad36cb76d19 100644
--- a/src/firebolt/async_db/util.py
+++ b/src/firebolt/async_db/util.py
@@ -11,7 +11,12 @@
async def is_db_available(connection: Connection, database_name: str) -> bool:
- """Verify if the database exists."""
+ """
+ Verify that the database exists.
+
+ Args:
+ connection (firebolt.async_db.connection.Connection)
+ """
resp = await _filter_request(
connection, DATABASES_URL, {"filter.name_contains": database_name}
)
@@ -19,9 +24,14 @@ async def is_db_available(connection: Connection, database_name: str) -> bool:
async def is_engine_running(connection: Connection, engine_url: str) -> bool:
- """Verify if the engine is running."""
- # Url is not always guaranteed to be of this structure
- # but for the sake of error check this is sufficient
+ """
+ Verify that the engine is running.
+
+ Args:
+ connection (firebolt.async_db.connection.Connection): connection.
+ """
+ # Url is not guaranteed to be of this structure,
+ # but for the sake of error checking this is sufficient.
engine_name = URL(engine_url).host.split(".")[0]
resp = await _filter_request(
connection,
@@ -38,7 +48,7 @@ async def _filter_request(
connection: Connection, endpoint: str, filters: dict
) -> Response:
resp = await connection._client.request(
- # Full URL overrides the client url, which contains engine as a prefix
+ # Full url overrides the client url, which contains engine as a prefix.
url=connection.api_endpoint + endpoint,
method="GET",
params=filters,
diff --git a/src/firebolt/model/engine.py b/src/firebolt/model/engine.py
index c2894a48562..82201734062 100644
--- a/src/firebolt/model/engine.py
+++ b/src/firebolt/model/engine.py
@@ -187,7 +187,7 @@ def get_connection(self) -> Connection:
"""Get a connection to the attached database for running queries.
Returns:
- Connection: engine connection instance
+ firebolt.db.connection.Connection: engine connection instance
"""
return connect(
diff --git a/src/firebolt/service/database.py b/src/firebolt/service/database.py
index 32efd35199b..71d58450017 100644
--- a/src/firebolt/service/database.py
+++ b/src/firebolt/service/database.py
@@ -58,7 +58,7 @@ def get_many(
attached_engine_name_contains: Filter for databases by engines with a
name containing this substring
order_by: Method by which to order the results.
- See :py:class:`firebolt.service.types.DatabaseOrder`
+ See :py:class:`firebolt.service.types.DatabaseOrder`
Returns:
A list of databases matching the filters
diff --git a/tests/integration/dbapi/async/test_queries_async.py b/tests/integration/dbapi/async/test_queries_async.py
index 7cdb777e97d..3efb333d926 100644
--- a/tests/integration/dbapi/async/test_queries_async.py
+++ b/tests/integration/dbapi/async/test_queries_async.py
@@ -8,6 +8,13 @@
from firebolt.async_db._types import ColType, Column
from firebolt.async_db.cursor import QueryStatus
+VALS_TO_INSERT = ",".join([f"({i},'{val}')" for (i, val) in enumerate(range(1, 360))])
+LONG_INSERT = f"INSERT INTO test_tbl VALUES {VALS_TO_INSERT}"
+CREATE_TEST_TABLE = (
+ "CREATE DIMENSION TABLE IF NOT EXISTS test_tbl (id int, name string)"
+)
+DROP_TEST_TABLE = "DROP TABLE IF EXISTS test_tbl"
+
CREATE_EXTERNAL_TABLE = """CREATE EXTERNAL TABLE IF NOT EXISTS ex_lineitem (
l_orderkey LONG,
l_partkey LONG,
@@ -420,59 +427,52 @@ async def test_server_side_async_execution_query(connection: Connection) -> None
), "Invalid query id was returned from server-side async query."
-async def test_server_side_async_execution_cancel(connection: Connection) -> None:
+async def test_server_side_async_execution_cancel(
+ create_drop_test_table_setup_teardown_async,
+) -> None:
"""Test cancel."""
- with connection.cursor() as c:
- try:
- await c.execute(CREATE_TEST_TABLE)
- query_id = await c.execute(
- LONG_INSERT,
- async_execution=True,
- )
- # Cancel, then check that status is cancelled.
- await c.cancel(query_id)
- await status_loop(
- query_id,
- "cancel",
- c,
- final_status=QueryStatus.CANCELED_EXECUTION,
- )
- finally:
- await c.execute(DROP_TEST_TABLE)
+ c = create_drop_test_table_setup_teardown_async
+ query_id = await c.execute(
+ LONG_INSERT,
+ async_execution=True,
+ )
+ # Cancel, then check that status is cancelled.
+ await c.cancel(query_id)
+ await status_loop(
+ query_id,
+ "cancel",
+ c,
+ final_status=QueryStatus.CANCELED_EXECUTION,
+ )
-async def test_server_side_async_execution_get_status(connection: Connection) -> None:
+async def test_server_side_async_execution_get_status(
+ create_drop_test_table_setup_teardown_async,
+) -> None:
"""
Test get_status(). Test for three ending conditions: PARSE_ERROR,
STARTED_EXECUTION, ENDED_EXECUTION.
"""
- with connection.cursor() as c:
- try:
- await c.execute(CREATE_TEST_TABLE)
- # A long insert so we can check for STARTED_EXECUTION.
- query_id = await c.execute(
- LONG_INSERT,
- async_execution=True,
- )
- await status_loop(
- query_id, "get status", c, final_status=QueryStatus.STARTED_EXECUTION
- )
- # Now a check for ENDED_SUCCESSFULLY status of last query.
- await status_loop(
- query_id,
- "get status",
- c,
- start_status=QueryStatus.STARTED_EXECUTION,
- final_status=QueryStatus.ENDED_SUCCESSFULLY,
- )
- # Now, check for PARSE_ERROR. '1' will fail, as id is int.
- query_id = await c.execute(
- """INSERT INTO test_tbl ('1', 'a')""",
- async_execution=True,
- )
- await status_loop(
- query_id, "get status", c, final_status=QueryStatus.PARSE_ERROR
- )
-
- finally:
- await c.execute(DROP_TEST_TABLE)
+ c = create_drop_test_table_setup_teardown_async
+ # A long insert so we can check for STARTED_EXECUTION.
+ query_id = await c.execute(
+ LONG_INSERT,
+ async_execution=True,
+ )
+ await status_loop(
+ query_id, "get status", c, final_status=QueryStatus.STARTED_EXECUTION
+ )
+ # Now a check for ENDED_SUCCESSFULLY status of last query.
+ await status_loop(
+ query_id,
+ "get status",
+ c,
+ start_status=QueryStatus.STARTED_EXECUTION,
+ final_status=QueryStatus.ENDED_SUCCESSFULLY,
+ )
+ # Now, check for PARSE_ERROR. '1' will fail, as id is int.
+ query_id = await c.execute(
+ """INSERT INTO test_tbl ('1', 'a')""",
+ async_execution=True,
+ )
+ await status_loop(query_id, "get status", c, final_status=QueryStatus.PARSE_ERROR)
diff --git a/tests/integration/dbapi/conftest.py b/tests/integration/dbapi/conftest.py
index 7c7e4dec897..c339ea32b55 100644
--- a/tests/integration/dbapi/conftest.py
+++ b/tests/integration/dbapi/conftest.py
@@ -7,7 +7,7 @@
from firebolt.async_db._types import ColType
from firebolt.async_db.cursor import Column
-from firebolt.db import ARRAY, DATETIME64, DECIMAL
+from firebolt.db import ARRAY, DATETIME64, DECIMAL, Connection
LOGGER = getLogger(__name__)
@@ -19,6 +19,22 @@
DROP_TEST_TABLE = "DROP TABLE IF EXISTS test_tbl"
+@fixture
+def create_drop_test_table_setup_teardown(connection: Connection) -> None:
+ with connection.cursor() as c:
+ c.execute(CREATE_TEST_TABLE)
+ yield c
+ c.execute(DROP_TEST_TABLE)
+
+
+@fixture
+async def create_drop_test_table_setup_teardown_async(connection: Connection) -> None:
+ with connection.cursor() as c:
+ await c.execute(CREATE_TEST_TABLE)
+ yield c
+ await c.execute(DROP_TEST_TABLE)
+
+
@fixture
def all_types_query() -> str:
return (
diff --git a/tests/integration/dbapi/sync/test_queries.py b/tests/integration/dbapi/sync/test_queries.py
index 4b85e15a2e6..bab4cb558cf 100644
--- a/tests/integration/dbapi/sync/test_queries.py
+++ b/tests/integration/dbapi/sync/test_queries.py
@@ -1,12 +1,27 @@
from datetime import date, datetime
from decimal import Decimal
+from threading import Thread
from typing import Any, List
from pytest import mark, raises
from firebolt.async_db._types import ColType, Column
from firebolt.async_db.cursor import QueryStatus
-from firebolt.db import Connection, Cursor, DataError, OperationalError
+from firebolt.client.auth import UsernamePassword
+from firebolt.db import (
+ Connection,
+ Cursor,
+ DataError,
+ OperationalError,
+ connect,
+)
+
+VALS_TO_INSERT = ",".join([f"({i},'{val}')" for (i, val) in enumerate(range(1, 360))])
+LONG_INSERT = f"INSERT INTO test_tbl VALUES {VALS_TO_INSERT}"
+CREATE_TEST_TABLE = (
+ "CREATE DIMENSION TABLE IF NOT EXISTS test_tbl (id int, name string)"
+)
+DROP_TEST_TABLE = "DROP TABLE IF EXISTS test_tbl"
def assert_deep_eq(got: Any, expected: Any, msg: str) -> bool:
@@ -410,57 +425,49 @@ def test_server_side_async_execution_query(connection: Connection) -> None:
), "Invalid query id was returned from server-side async query."
-def test_server_side_async_execution_cancel(connection: Connection) -> None:
+def test_server_side_async_execution_cancel(
+ create_drop_test_table_setup_teardown,
+) -> None:
"""Test cancel."""
- with connection.cursor() as c:
- try:
- c.execute(CREATE_TEST_TABLE)
- query_id = c.execute(
- LONG_INSERT,
- async_execution=True,
- )
- # Cancel, then check that status is cancelled.
- c.cancel(query_id)
- status_loop(
- query_id,
- "cancel",
- c,
- final_status=QueryStatus.CANCELED_EXECUTION,
- )
- finally:
- c.execute(DROP_TEST_TABLE)
+ c = create_drop_test_table_setup_teardown
+ query_id = c.execute(
+ LONG_INSERT,
+ async_execution=True,
+ )
+ # Cancel, then check that status is cancelled.
+ c.cancel(query_id)
+ status_loop(
+ query_id,
+ "cancel",
+ c,
+ final_status=QueryStatus.CANCELED_EXECUTION,
+ )
-def test_server_side_async_execution_get_status(connection: Connection) -> None:
+def test_server_side_async_execution_get_status(
+ create_drop_test_table_setup_teardown,
+) -> None:
"""
Test get_status(). Test for three ending conditions: PARSE_ERROR,
STARTED_EXECUTION, ENDED_EXECUTION.
"""
- with connection.cursor() as c:
- try:
- c.execute(CREATE_TEST_TABLE)
- # A long insert so we can check for STARTED_EXECUTION.
- query_id = c.execute(
- LONG_INSERT,
- async_execution=True,
- )
- status_loop(
- query_id, "get status", c, final_status=QueryStatus.STARTED_EXECUTION
- )
- # Now a check for ENDED_SUCCESSFULLY status of last query.
- status_loop(
- query_id,
- "get status",
- c,
- start_status=QueryStatus.STARTED_EXECUTION,
- final_status=QueryStatus.ENDED_SUCCESSFULLY,
- )
- # Now, check for PARSE_ERROR. '1' will fail, as id is int.
- query_id = c.execute(
- """INSERT INTO test_tbl ('1', 'a')""",
- async_execution=True,
- )
- status_loop(query_id, "get status", c, final_status=QueryStatus.PARSE_ERROR)
-
- finally:
- c.execute(DROP_TEST_TABLE)
+ c = create_drop_test_table_setup_teardown
+ query_id = c.execute(
+ LONG_INSERT,
+ async_execution=True,
+ )
+ status_loop(query_id, "get status", c, final_status=QueryStatus.STARTED_EXECUTION)
+ # Now a check for ENDED_SUCCESSFULLY status of last query.
+ status_loop(
+ query_id,
+ "get status",
+ c,
+ start_status=QueryStatus.STARTED_EXECUTION,
+ final_status=QueryStatus.ENDED_SUCCESSFULLY,
+ )
+ # Now, check for PARSE_ERROR. '1' will fail, as id is int.
+ query_id = c.execute(
+ """INSERT INTO test_tbl ('1', 'a')""",
+ async_execution=True,
+ )
+ status_loop(query_id, "get status", c, final_status=QueryStatus.PARSE_ERROR)