diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
new file mode 100644
index 00000000..07b7645f
--- /dev/null
+++ b/.github/workflows/docs.yml
@@ -0,0 +1,18 @@
+name: Deploy Sphinx documentation to Github Pages
+
+on:
+ push:
+ branches: [main] # branch to trigger deployment
+
+jobs:
+ pages:
+ runs-on: ubuntu-20.04
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ permissions:
+ pages: write
+ id-token: write
+ steps:
+ - id: deployment
+ uses: sphinx-notes/pages@v3
\ No newline at end of file
diff --git a/README.md b/README.md
index cfc57eb2..db7c3de2 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,12 @@ YDB Python SDK
Officially supported Python client for YDB.
+---
+
+**Documentation**: https://ydb-platform.github.io/ydb-python-sdk
+
+---
+
## Quickstart
### Prerequisites
diff --git a/docs/_static/logo.svg b/docs/_static/logo.svg
new file mode 100644
index 00000000..0a813215
--- /dev/null
+++ b/docs/_static/logo.svg
@@ -0,0 +1,4 @@
+
diff --git a/docs/apireference.rst b/docs/apireference.rst
new file mode 100644
index 00000000..1d6a2821
--- /dev/null
+++ b/docs/apireference.rst
@@ -0,0 +1,244 @@
+YDB API Reference
+=================
+
+.. toctree::
+ :caption: Contents:
+
+
+.. module:: ydb
+
+Driver
+------
+
+DriverConfig
+^^^^^^^^^^^^
+
+.. autoclass:: ydb.DriverConfig
+ :members:
+ :inherited-members:
+ :undoc-members:
+ :exclude-members: database, ca_cert, channel_options, secure_channel, endpoint, endpoints, credentials, use_all_nodes, root_certificates, certificate_chain, private_key, grpc_keep_alive_timeout, table_client_settings, primary_user_agent
+
+
+Driver
+^^^^^^
+
+.. autoclass:: ydb.Driver
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+
+Driver (AsyncIO)
+^^^^^^^^^^^^^^^
+
+.. autoclass:: ydb.aio.Driver
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+------------------------
+
+Common
+-------------
+
+BaseRequestSettings
+^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: ydb.BaseRequestSettings
+ :members:
+ :inherited-members:
+ :undoc-members:
+ :exclude-members: trace_id, request_type, timeout, cancel_after, operation_timeout, compression, need_rpc_auth, headers, make_copy, tracer
+
+
+RetrySettings
+^^^^^^^^^^^^^
+
+.. autoclass:: ydb.RetrySettings
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+
+Result Sets
+^^^^^^^^^^^
+
+.. autoclass:: ydb.convert._ResultSet
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+
+------------------------
+
+Query Service
+-------------
+
+QueryClientSettings
+^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: ydb.QueryClientSettings
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+
+QuerySessionPool
+^^^^^^^^^^^^^^^^
+
+.. autoclass:: ydb.QuerySessionPool
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+QuerySession
+^^^^^^^^^^^^
+
+.. autoclass:: ydb.QuerySession
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+
+QueryTxContext
+^^^^^^^^^^^^^^
+
+.. autoclass:: ydb.QueryTxContext
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+
+QuerySessionPool (AsyncIO)
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: ydb.aio.QuerySessionPool
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+
+QuerySession (AsyncIO)
+^^^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: ydb.aio.QuerySession
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+
+QueryTxContext (AsyncIO)
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: ydb.aio.QueryTxContext
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+
+Query Tx Mode
+^^^^^^^^^^^^^
+
+.. autoclass:: ydb.BaseQueryTxMode
+ :members:
+ :inherited-members:
+ :undoc-members:
+ :exclude-members: name, to_proto
+
+
+.. autoclass:: ydb.QueryOnlineReadOnly
+ :members:
+ :inherited-members:
+ :undoc-members:
+ :exclude-members: name, to_proto
+
+
+.. autoclass:: ydb.QuerySerializableReadWrite
+ :members:
+ :inherited-members:
+ :undoc-members:
+ :exclude-members: name, to_proto
+
+
+.. autoclass:: ydb.QuerySnapshotReadOnly
+ :members:
+ :inherited-members:
+ :undoc-members:
+ :exclude-members: name, to_proto
+
+
+.. autoclass:: ydb.QueryStaleReadOnly
+ :members:
+ :inherited-members:
+ :undoc-members:
+ :exclude-members: name, to_proto
+
+
+------------------------
+
+Table Service
+-------------
+
+TableClient
+^^^^^^^^^^^
+.. autoclass:: ydb.TableClient
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+TableClientSettings
+^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: ydb.TableClientSettings
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+Session Pool
+^^^^^^^^^^^^
+
+.. autoclass:: ydb.SessionPool
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+Session
+^^^^^^^
+
+.. autoclass:: ydb.Session
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+Transaction Context
+^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: ydb.TxContext
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+DataQuery
+^^^^^^^^^
+
+.. autoclass:: ydb.DataQuery
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+--------------------------
+
+Scheme
+------
+
+SchemeClient
+^^^^^^^^^^^^
+
+.. autoclass:: ydb.SchemeClient
+ :members:
+ :inherited-members:
+ :undoc-members:
+
+------------------
+
diff --git a/docs/conf.py b/docs/conf.py
index f8cc5f6d..13d7e22d 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -20,7 +20,7 @@
# -- Project information -----------------------------------------------------
project = 'ydb'
-copyright = '2021, yandex'
+copyright = '2024, yandex'
author = 'yandex'
# The short X.Y version
@@ -39,11 +39,12 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
- 'sphinx.ext.autodoc',
- 'sphinx.ext.viewcode',
- 'sphinx.ext.todo',
- 'sphinx.ext.napoleon',
- 'sphinx.ext.coverage',
+ 'sphinx.ext.autodoc',
+ 'sphinx.ext.viewcode',
+ 'sphinx.ext.todo',
+ 'sphinx.ext.napoleon',
+ 'sphinx.ext.coverage',
+ 'sphinx_copybutton',
]
# Add any paths that contain templates here, relative to this directory.
@@ -79,15 +80,20 @@
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
-html_theme = 'alabaster'
+html_theme = 'sphinx_rtd_theme'
html_theme_options = {
- 'fixed_sidebar': True,
- 'page_width': '1140px',
- 'show_related': True,
- 'show_powered_by': False
+ 'fixed_sidebar': True,
+ 'page_width': '1140px',
+ 'show_related': True,
+ 'show_powered_by': False
}
+html_logo = '_static/logo.svg'
+html_favicon = '_static/logo.svg'
+
+html_show_sourcelink = False
+
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
@@ -97,7 +103,7 @@
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['.static']
+html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
diff --git a/docs/examples.rst b/docs/examples.rst
index 920d1292..4f8dee84 100644
--- a/docs/examples.rst
+++ b/docs/examples.rst
@@ -1,67 +1,155 @@
Examples
===============
-ydb
-^^^
+Basic example
+^^^^^^^^^^^^^
+
+All examples in this section are parts of `basic example `_.
+
+For deeper upderstanding it is better to read the whole example.
Create table
------------
-::
-
- ... create an instance of Driver ...
-
- description = (
- ydb.TableDescription()
- .with_primary_keys('key1', 'key2')
- .with_columns(
- ydb.Column('key1', ydb.OptionalType(ydb.PrimitiveType.Uint64)),
- ydb.Column('key2', ydb.OptionalType(ydb.PrimitiveType.Uint64)),
- ydb.Column('value', ydb.OptionalType(ydb.PrimitiveType.Utf8))
- )
- .with_profile(
- ydb.TableProfile()
- .with_partitioning_policy(
- ydb.PartitioningPolicy()
- .with_explicit_partitions(
- ydb.ExplicitPartitions(
- (
- ydb.KeyBound((100, )),
- ydb.KeyBound((300, 100)),
- ydb.KeyBound((400, )),
- )
- )
- )
- )
- )
- )
-
- session = driver.table_client.session().create()
- session.create_table('/my/table/', description)
-
-
-Read table
+.. code-block:: python
+
+ def create_tables(pool: ydb.QuerySessionPool):
+ print("\nCreating table series...")
+ pool.execute_with_retries(
+ """
+ CREATE table `series` (
+ `series_id` Int64,
+ `title` Utf8,
+ `series_info` Utf8,
+ `release_date` Date,
+ PRIMARY KEY (`series_id`)
+ )
+ """
+ )
+
+ print("\nCreating table seasons...")
+ pool.execute_with_retries(
+ """
+ CREATE table `seasons` (
+ `series_id` Int64,
+ `season_id` Int64,
+ `title` Utf8,
+ `first_aired` Date,
+ `last_aired` Date,
+ PRIMARY KEY (`series_id`, `season_id`)
+ )
+ """
+ )
+
+ print("\nCreating table episodes...")
+ pool.execute_with_retries(
+ """
+ CREATE table `episodes` (
+ `series_id` Int64,
+ `season_id` Int64,
+ `episode_id` Int64,
+ `title` Utf8,
+ `air_date` Date,
+ PRIMARY KEY (`series_id`, `season_id`, `episode_id`)
+ )
+ """
+ )
+
+
+Upsert Simple
+-------------
+
+.. code-block:: python
+
+ def upsert_simple(pool: ydb.QuerySessionPool):
+ print("\nPerforming UPSERT into episodes...")
+
+ pool.execute_with_retries(
+ """
+ UPSERT INTO episodes (series_id, season_id, episode_id, title) VALUES (2, 6, 1, "TBD");
+ """
+ )
+
+
+Simple Select
----------
-::
-
- .... initialize driver and session ....
-
- key_prefix_type = ydb.TupleType().add_element(
- ydb.OptionalType(ydb.PrimitiveType.Uint64).add_element(
- ydb.OptionalType(ydb.PrimitiveType.Utf8))
- async_table_iterator = session.read_table(
- '/my/table',
- columns=('KeyColumn0', 'KeyColumn1', 'ValueColumn'),
- ydb.KeyRange(
- ydb.KeyBound((100, 'hundred'), key_prefix_type)
- ydb.KeyBound((200, 'two-hundreds'), key_prefix_type)
- )
+
+.. code-block:: python
+
+ def select_simple(pool: ydb.QuerySessionPool):
+ print("\nCheck series table...")
+ result_sets = pool.execute_with_retries(
+ """
+ SELECT
+ series_id,
+ title,
+ release_date
+ FROM series
+ WHERE series_id = 1;
+ """,
+ )
+ first_set = result_sets[0]
+ for row in first_set.rows:
+ print(
+ "series, id: ",
+ row.series_id,
+ ", title: ",
+ row.title,
+ ", release date: ",
+ row.release_date,
)
- while True:
- try:
- chunk_future = next(table_iterator)
- chunk = chunk_future.result() # or any other way to await
- ... additional data processing ...
- except StopIteration:
- break
+ return first_set
+
+Select With Parameters
+----------------------
+
+.. code-block:: python
+
+ def select_with_parameters(pool: ydb.QuerySessionPool, series_id, season_id, episode_id):
+ result_sets = pool.execute_with_retries(
+ """
+ DECLARE $seriesId AS Int64;
+ DECLARE $seasonId AS Int64;
+ DECLARE $episodeId AS Int64;
+
+ SELECT
+ title,
+ air_date
+ FROM episodes
+ WHERE series_id = $seriesId AND season_id = $seasonId AND episode_id = $episodeId;
+ """,
+ {
+ "$seriesId": series_id, # could be defined implicit
+ "$seasonId": (season_id, ydb.PrimitiveType.Int64), # could be defined via tuple
+ "$episodeId": ydb.TypedValue(episode_id, ydb.PrimitiveType.Int64), # could be defined via special class
+ },
+ )
+
+ print("\n> select_with_parameters:")
+ first_set = result_sets[0]
+ for row in first_set.rows:
+ print("episode title:", row.title, ", air date:", row.air_date)
+
+ return first_set
+
+Huge Select
+-----------
+
+.. code-block:: python
+
+ def huge_select(pool: ydb.QuerySessionPool):
+ def callee(session: ydb.QuerySessionSync):
+ query = """SELECT * from episodes;"""
+
+ with session.transaction().execute(
+ query,
+ commit_tx=True,
+ ) as result_sets:
+ print("\n> Huge SELECT call")
+ for result_set in result_sets:
+ for row in result_set.rows:
+ print("episode title:", row.title, ", air date:", row.air_date)
+
+ return pool.retry_operation_sync(callee)
+
diff --git a/docs/index.rst b/docs/index.rst
index 9a69b2bc..184a35ab 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -3,16 +3,16 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
-Welcome to ydb's documentation!
+YDB Python SDK
===============================
.. toctree::
- :maxdepth: 10
-
- ydb.rst
- examples.rst
-
+ :maxdepth: 3
+ overview
+ quickstart
+ examples
+ apireference
Indices and tables
diff --git a/docs/overview.rst b/docs/overview.rst
new file mode 100644
index 00000000..81abf94d
--- /dev/null
+++ b/docs/overview.rst
@@ -0,0 +1,21 @@
+Overview
+========
+
+Project Homepage
+----------------
+
+YDB Python SDK is hosted on GitHub at https://github.com/ydb-platform/ydb-python-sdk under the ydb-platform organization.
+
+Releases and project status are available on Pypi at https://pypi.org/project/ydb.
+
+The most recent published version of this documentation should be at https://ydb-platform.github.io/ydb-python-sdk.
+
+
+Community
+---------
+
+You can ask your questions in official Telegram chats: `EN `_ | `RU `_.
+
+Bugs and feature enhancements to YDB Python SDK should be reported on the `GitHub
+issue tracker
+`_.
\ No newline at end of file
diff --git a/docs/quickstart.rst b/docs/quickstart.rst
new file mode 100644
index 00000000..cb1d1062
--- /dev/null
+++ b/docs/quickstart.rst
@@ -0,0 +1,119 @@
+Quick Start
+===========
+
+Installation
+------------
+
+Prerequisites
+^^^^^^^^^^^^^
+
+* Python 3.8 or higher;
+* ``pip`` version 9.0.1 or higher;
+
+If necessary, upgrade your version of ``pip``::
+
+ python -m pip install --upgrade pip
+
+If you cannot upgrade `pip` due to a system-owned installation, you can run the example in a virtualenv::
+
+ python -m pip install virtualenv
+ virtualenv venv
+ source venv/bin/activate
+ python -m pip install --upgrade pip
+
+Installation via Pypi
+^^^^^^^^^^^^^^^^^^^^^
+
+To install YDB Python SDK through Pypi execute the following command::
+
+ pip install ydb
+
+Usage
+-----
+
+Import Package
+^^^^^^^^^^^^^^
+
+.. code-block:: python
+
+ import ydb
+
+Driver Initialization
+^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: python
+
+ endpoint = "grpc://localhost:2136" # your ydb endpoint
+ database = "/local" # your ydb database
+
+ with ydb.Driver(
+ endpoint=endpoint,
+ database=database,
+ credentials=ydb.credentials_from_env_variables(),
+ ) as driver:
+ driver.wait(timeout=5, fail_fast=True)
+
+SessionPool Initialization
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: python
+
+ with ydb.QuerySessionPool(driver) as pool:
+ pass
+
+Query Execution
+^^^^^^^^^^^^^^^
+
+Python SDK supports queries described by YQL syntax.
+There are two primary methods for executing queries, each with different properties and use cases:
+
+* ``pool.execute_with_retries``:
+
+ * Buffers the entire result set in client memory.
+ * Automatically retries execution in case of retriable issues.
+ * Does not allow specifying a transaction execution mode.
+ * Recommended for one-off queries that are expected to produce small result sets.
+
+* ``tx.execute``:
+
+ * Returns an iterator over the query results, allowing processing of results that may not fit into client memory.
+ * Retries must be handled manually via `pool.retry_operation_sync`.
+ * Allows specifying a transaction execution mode.
+ * Recommended for scenarios where `pool.execute_with_retries` is insufficient.
+
+
+Usage of ``pool.execute_with_retries()``:
+
+.. code-block:: python
+
+ pool.execute_with_retries("DROP TABLE IF EXISTS example")
+ pool.execute_with_retries("CREATE TABLE example(key UInt64, value String, PRIMARY KEY (key))")
+
+ pool.execute_with_retries("INSERT INTO example (key, value) VALUES (1, 'luffy')")
+
+ res = pool.execute_with_retries("SELECT COUNT(*) AS rows_count FROM example")
+
+>>> res[0].rows_count
+1
+
+Example of ``tx.execute()``:
+
+.. code-block:: python
+
+ def callee(session: ydb.QuerySessionSync):
+ with session.transaction() as tx:
+ with tx.execute(
+ "INSERT INTO example (key, value) VALUES (2, 'zoro')"
+ ):
+ pass
+
+ with tx.execute(
+ "INSERT INTO example (key, value) VALUES (3, 'sanji')",
+ commit_tx=True,
+ ):
+ pass
+
+ pool.retry_operation_sync(callee)
+
+
+
diff --git a/docs/requirements.txt b/docs/requirements.txt
new file mode 100644
index 00000000..f8306480
--- /dev/null
+++ b/docs/requirements.txt
@@ -0,0 +1,2 @@
+sphinx_rtd_theme==2.0.0
+sphinx-copybutton==0.5.2
diff --git a/docs/ydb.rst b/docs/ydb.rst
deleted file mode 100644
index 53297005..00000000
--- a/docs/ydb.rst
+++ /dev/null
@@ -1,111 +0,0 @@
-ydb
-===
-
-.. toctree::
- :caption: Contents:
-
-
-.. module:: ydb
-
-Module contents
----------------
-
-Driver
-^^^^^^
-
-Driver object
-~~~~~~~~~~~~~
-
-.. autoclass:: Driver
- :members:
- :inherited-members:
- :undoc-members:
-
-
-DriverConfig
-~~~~~~~~~~~~
-
-.. autoclass:: DriverConfig
- :members:
- :inherited-members:
- :undoc-members:
- :exclude-members: database, ca_cert, channel_options, secure_channel, endpoint, endpoints, credentials, use_all_nodes, root_certificates, certificate_chain, private_key, grpc_keep_alive_timeout, table_client_settings, primary_user_agent
-
-------------------------
-
-Table
-^^^^^
-TableClient
-~~~~~~~~~~~
-.. autoclass:: TableClient
- :members:
- :inherited-members:
- :undoc-members:
-
-TableClientSettings
-~~~~~~~~~~~~~~~~~~~
-
-.. autoclass:: TableClientSettings
- :members:
- :inherited-members:
- :undoc-members:
-
-Session
-~~~~~~~
-
-.. autoclass:: Session
- :members:
- :inherited-members:
- :undoc-members:
-
-Transaction Context
-~~~~~~~~~~~~~~~~~~~
-
-.. autoclass:: TxContext
- :members:
- :inherited-members:
- :undoc-members:
-
---------------------------
-
-Scheme
-^^^^^^
-
-SchemeClient
-~~~~~~~~~~~~
-
-.. autoclass:: SchemeClient
- :members:
- :inherited-members:
- :undoc-members:
-
-------------------
-
-Session Pool
-^^^^^^^^^^^^
-
-.. autoclass:: SessionPool
- :members:
- :inherited-members:
- :undoc-members:
-
------------------------------
-
-
-Result Sets
-^^^^^^^^^^^
-
-.. autoclass:: ydb.convert._ResultSet
- :members:
- :inherited-members:
- :undoc-members:
-
------------------------------
-
-DataQuery
-^^^^^^^^^
-
-.. autoclass:: DataQuery
- :members:
- :inherited-members:
- :undoc-members:
diff --git a/ydb/_grpc/grpcwrapper/ydb_query_public_types.py b/ydb/_grpc/grpcwrapper/ydb_query_public_types.py
index d79a2967..9888a677 100644
--- a/ydb/_grpc/grpcwrapper/ydb_query_public_types.py
+++ b/ydb/_grpc/grpcwrapper/ydb_query_public_types.py
@@ -11,6 +11,8 @@
class BaseQueryTxMode(IToProto):
+ """Abstract class for Query Transaction Modes."""
+
@property
@abc.abstractmethod
def name(self) -> str:
@@ -18,6 +20,11 @@ def name(self) -> str:
class QuerySnapshotReadOnly(BaseQueryTxMode):
+ """All the read operations within a transaction access the database snapshot.
+ All the data reads are consistent. The snapshot is taken when the transaction begins,
+ meaning the transaction sees all changes committed before it began.
+ """
+
def __init__(self):
self._name = "snapshot_read_only"
@@ -30,6 +37,10 @@ def to_proto(self) -> ydb_query_pb2.SnapshotModeSettings:
class QuerySerializableReadWrite(BaseQueryTxMode):
+ """This mode guarantees that the result of successful parallel transactions is equivalent
+ to their serial execution, and there are no read anomalies for successful transactions.
+ """
+
def __init__(self):
self._name = "serializable_read_write"
@@ -42,6 +53,15 @@ def to_proto(self) -> ydb_query_pb2.SerializableModeSettings:
class QueryOnlineReadOnly(BaseQueryTxMode):
+ """Each read operation in the transaction is reading the data that is most recent at execution time.
+ The consistency of retrieved data depends on the allow_inconsistent_reads setting:
+ * false (consistent reads): Each individual read operation returns consistent data,
+ but no consistency is guaranteed between reads.
+ Reading the same table range twice may return different results.
+ * true (inconsistent reads): Even the data fetched by a particular
+ read operation may contain inconsistent results.
+ """
+
def __init__(self, allow_inconsistent_reads: bool = False):
self.allow_inconsistent_reads = allow_inconsistent_reads
self._name = "online_read_only"
@@ -55,6 +75,11 @@ def to_proto(self) -> ydb_query_pb2.OnlineModeSettings:
class QueryStaleReadOnly(BaseQueryTxMode):
+ """Read operations within a transaction may return results that are slightly out-of-date
+ (lagging by fractions of a second). Each individual read returns consistent data,
+ but no consistency between different reads is guaranteed.
+ """
+
def __init__(self):
self._name = "stale_read_only"
diff --git a/ydb/aio/__init__.py b/ydb/aio/__init__.py
index a755713d..1c9c887c 100644
--- a/ydb/aio/__init__.py
+++ b/ydb/aio/__init__.py
@@ -1,3 +1,3 @@
from .driver import Driver # noqa
from .table import SessionPool, retry_operation # noqa
-from .query import QuerySessionPool, QuerySession # noqa
+from .query import QuerySessionPool, QuerySession, QueryTxContext # noqa
diff --git a/ydb/aio/query/__init__.py b/ydb/aio/query/__init__.py
index ea5273d7..8e7dd4fd 100644
--- a/ydb/aio/query/__init__.py
+++ b/ydb/aio/query/__init__.py
@@ -1,7 +1,9 @@
__all__ = [
"QuerySessionPool",
"QuerySession",
+ "QueryTxContext",
]
from .pool import QuerySessionPool
from .session import QuerySession
+from .transaction import QueryTxContext
diff --git a/ydb/aio/query/pool.py b/ydb/aio/query/pool.py
index f0b962c3..e8d53438 100644
--- a/ydb/aio/query/pool.py
+++ b/ydb/aio/query/pool.py
@@ -44,6 +44,13 @@ async def _create_new_session(self):
return session
async def acquire(self) -> QuerySession:
+ """WARNING: This API is experimental and could be changed.
+
+ Acquire a session from Session Pool.
+
+ :return A QuerySession object.
+ """
+
if self._should_stop.is_set():
logger.error("An attempt to take session from closed session pool.")
raise RuntimeError("An attempt to take session from closed session pool.")
@@ -79,12 +86,18 @@ async def acquire(self) -> QuerySession:
return session
async def release(self, session: QuerySession) -> None:
+ """WARNING: This API is experimental and could be changed.
+
+ Release a session back to Session Pool.
+ """
+
self._queue.put_nowait(session)
logger.debug("Session returned to queue: %s", session._state.session_id)
def checkout(self) -> "SimpleQuerySessionCheckoutAsync":
"""WARNING: This API is experimental and could be changed.
- Return a Session context manager, that opens session on enter and closes session on exit.
+
+ Return a Session context manager, that acquires session on enter and releases session on exit.
"""
return SimpleQuerySessionCheckoutAsync(self)
@@ -93,6 +106,7 @@ async def retry_operation_async(
self, callee: Callable, retry_settings: Optional[RetrySettings] = None, *args, **kwargs
):
"""WARNING: This API is experimental and could be changed.
+
Special interface to execute a bunch of commands with session in a safe, retriable way.
:param callee: A function, that works with session.
@@ -118,6 +132,7 @@ async def execute_with_retries(
**kwargs,
) -> List[convert.ResultSet]:
"""WARNING: This API is experimental and could be changed.
+
Special interface to execute a one-shot queries in a safe, retriable way.
Note: this method loads all data from stream before return, do not use this
method with huge read queries.
diff --git a/ydb/aio/query/session.py b/ydb/aio/query/session.py
index 5f51b671..4c1c1a10 100644
--- a/ydb/aio/query/session.py
+++ b/ydb/aio/query/session.py
@@ -116,6 +116,7 @@ async def execute(
"""WARNING: This API is experimental and could be changed.
Sends a query to Query Service
+
:param query: (YQL or SQL text) to be executed.
:param syntax: Syntax of the query, which is a one from the following choises:
1) QuerySyntax.YQL_V1, which is default;
diff --git a/ydb/aio/query/transaction.py b/ydb/aio/query/transaction.py
index 0e3ab602..b115a4b4 100644
--- a/ydb/aio/query/transaction.py
+++ b/ydb/aio/query/transaction.py
@@ -114,6 +114,7 @@ async def execute(
"""WARNING: This API is experimental and could be changed.
Sends a query to Query Service
+
:param query: (YQL or SQL text) to be executed.
:param parameters: dict with parameters and YDB types;
:param commit_tx: A special flag that allows transaction commit.
diff --git a/ydb/query/__init__.py b/ydb/query/__init__.py
index 1e950bb7..0f818789 100644
--- a/ydb/query/__init__.py
+++ b/ydb/query/__init__.py
@@ -1,11 +1,13 @@
__all__ = [
+ "BaseQueryTxMode",
"QueryOnlineReadOnly",
"QuerySerializableReadWrite",
"QuerySnapshotReadOnly",
"QueryStaleReadOnly",
"QuerySessionPool",
- "QueryClientSync",
+ "QueryClientSettings",
"QuerySession",
+ "QueryTxContext",
]
import logging
@@ -15,9 +17,11 @@
)
from .session import QuerySession
+from .transaction import QueryTxContext
from .._grpc.grpcwrapper import common_utils
from .._grpc.grpcwrapper.ydb_query_public_types import (
+ BaseQueryTxMode,
QueryOnlineReadOnly,
QuerySerializableReadWrite,
QuerySnapshotReadOnly,
diff --git a/ydb/query/pool.py b/ydb/query/pool.py
index 1ee9ea83..839d8688 100644
--- a/ydb/query/pool.py
+++ b/ydb/query/pool.py
@@ -29,7 +29,8 @@ class QuerySessionPool:
def __init__(self, driver: common_utils.SupportedDriverType, size: int = 100):
"""
- :param driver: A driver instance
+ :param driver: A driver instance.
+ :param size: Max size of Session Pool.
"""
logger.warning("QuerySessionPool is an experimental API, which could be changed.")
@@ -47,6 +48,15 @@ def _create_new_session(self, timeout: Optional[float]):
return session
def acquire(self, timeout: Optional[float] = None) -> QuerySession:
+ """WARNING: This API is experimental and could be changed.
+
+ Acquire a session from Session Pool.
+
+ :param timeout: A timeout to wait in seconds.
+
+ :return A QuerySession object.
+ """
+
start = time.monotonic()
lock_acquire_timeout = timeout if timeout is not None else -1
@@ -92,18 +102,27 @@ def acquire(self, timeout: Optional[float] = None) -> QuerySession:
self._lock.release()
def release(self, session: QuerySession) -> None:
+ """WARNING: This API is experimental and could be changed.
+
+ Release a session back to Session Pool.
+ """
+
self._queue.put_nowait(session)
logger.debug("Session returned to queue: %s", session._state.session_id)
def checkout(self, timeout: Optional[float] = None) -> "SimpleQuerySessionCheckout":
"""WARNING: This API is experimental and could be changed.
- Return a Session context manager, that opens session on enter and closes session on exit.
+
+ Return a Session context manager, that acquires session on enter and releases session on exit.
+
+ :param timeout: A timeout to wait in seconds.
"""
return SimpleQuerySessionCheckout(self, timeout)
def retry_operation_sync(self, callee: Callable, retry_settings: Optional[RetrySettings] = None, *args, **kwargs):
"""WARNING: This API is experimental and could be changed.
+
Special interface to execute a bunch of commands with session in a safe, retriable way.
:param callee: A function, that works with session.
@@ -129,6 +148,7 @@ def execute_with_retries(
**kwargs,
) -> List[convert.ResultSet]:
"""WARNING: This API is experimental and could be changed.
+
Special interface to execute a one-shot queries in a safe, retriable way.
Note: this method loads all data from stream before return, do not use this
method with huge read queries.
diff --git a/ydb/query/session.py b/ydb/query/session.py
index 66e86501..5b4db26c 100644
--- a/ydb/query/session.py
+++ b/ydb/query/session.py
@@ -269,6 +269,7 @@ def transaction(self, tx_mode: Optional[base.BaseQueryTxMode] = None) -> QueryTx
"""WARNING: This API is experimental and could be changed.
Creates a transaction context manager with specified transaction mode.
+
:param tx_mode: Transaction mode, which is a one from the following choises:
1) QuerySerializableReadWrite() which is default mode;
2) QueryOnlineReadOnly(allow_inconsistent_reads=False);
@@ -301,6 +302,7 @@ def execute(
"""WARNING: This API is experimental and could be changed.
Sends a query to Query Service
+
:param query: (YQL or SQL text) to be executed.
:param syntax: Syntax of the query, which is a one from the following choises:
1) QuerySyntax.YQL_V1, which is default;
diff --git a/ydb/query/transaction.py b/ydb/query/transaction.py
index 9ad3552f..21ba0279 100644
--- a/ydb/query/transaction.py
+++ b/ydb/query/transaction.py
@@ -394,6 +394,7 @@ def execute(
"""WARNING: This API is experimental and could be changed.
Sends a query to Query Service
+
:param query: (YQL or SQL text) to be executed.
:param parameters: dict with parameters and YDB types;
:param commit_tx: A special flag that allows transaction commit.
diff --git a/ydb/settings.py b/ydb/settings.py
index 6739a46f..019b75a8 100644
--- a/ydb/settings.py
+++ b/ydb/settings.py
@@ -39,7 +39,7 @@ def make_copy(self):
.with_need_rpc_auth(self.need_rpc_auth)
)
- def with_compression(self, compression):
+ def with_compression(self, compression) -> "BaseRequestSettings":
"""
Enables compression for the specific RPC
:param compression: An RPCCompression enum value.
@@ -48,11 +48,11 @@ def with_compression(self, compression):
self.compression = compression
return self
- def with_need_rpc_auth(self, need_rpc_auth):
+ def with_need_rpc_auth(self, need_rpc_auth) -> "BaseRequestSettings":
self.need_rpc_auth = need_rpc_auth
return self
- def with_header(self, key, value):
+ def with_header(self, key, value) -> "BaseRequestSettings":
"""
Adds a key-value pair to the request headers.
:param key: A string with a header key.
@@ -62,7 +62,7 @@ def with_header(self, key, value):
self.headers.append((key, value))
return self
- def with_trace_id(self, trace_id):
+ def with_trace_id(self, trace_id) -> "BaseRequestSettings":
"""
Includes trace id for RPC headers
:param trace_id: A trace id string
@@ -71,7 +71,7 @@ def with_trace_id(self, trace_id):
self.trace_id = trace_id
return self
- def with_request_type(self, request_type):
+ def with_request_type(self, request_type) -> "BaseRequestSettings":
"""
Includes request type for RPC headers
:param request_type: A request type string
@@ -80,7 +80,7 @@ def with_request_type(self, request_type):
self.request_type = request_type
return self
- def with_operation_timeout(self, timeout):
+ def with_operation_timeout(self, timeout) -> "BaseRequestSettings":
"""
Indicates that client is no longer interested in the result of operation after the specified duration
starting from the time operation arrives at the server.
@@ -89,12 +89,12 @@ def with_operation_timeout(self, timeout):
Timeout of operation does not tell anything about its result, it might be completed successfully
or cancelled on server.
:param timeout:
- :return:
+ :return: The self instance
"""
self.operation_timeout = timeout
return self
- def with_cancel_after(self, timeout):
+ def with_cancel_after(self, timeout) -> "BaseRequestSettings":
"""
Server will try to cancel the operation after the specified duration starting from the time
the operation arrives at server.
@@ -102,12 +102,12 @@ def with_cancel_after(self, timeout):
sent back to client if it was waiting for the operation result.
In case when cancellation isn't possible, no action will be performed.
:param timeout:
- :return:
+ :return: The self instance
"""
self.cancel_after = timeout
return self
- def with_timeout(self, timeout):
+ def with_timeout(self, timeout) -> "BaseRequestSettings":
"""
Client-side timeout to complete request.
Since YDB doesn't support request cancellation at this moment, this feature should be