diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e69de29 diff --git a/acouchbase_analytics/cluster.py b/acouchbase_analytics/cluster.py index 02d869f..9977c71 100644 --- a/acouchbase_analytics/cluster.py +++ b/acouchbase_analytics/cluster.py @@ -34,32 +34,32 @@ class AsyncCluster: """Create an AsyncCluster instance. - The cluster instance exposes the operations which are available to be performed against a Columnar cluster. + The cluster instance exposes the operations which are available to be performed against a Analytics cluster. .. important:: Use the static :meth:`.AsyncCluster.create_instance` method to create an AsyncCluster. Args: - connstr: - The connection string to use for connecting to the cluster. - The format of the connection string is the *scheme* (``couchbases`` as TLS enabled connections are _required_), followed a hostname + endpoint: + The endpoint to use for sending HTTP requests to the Analytics server. + The format of the endpoint string is the **scheme** (``http`` or ``https`` is *required*, use ``https`` for TLS enabled connections), followed a hostname and optional port. credential: User credentials. options: Global options to set for the cluster. Some operations allow the global options to be overriden by passing in options to the operation. **kwargs: keyword arguments that can be used in place or to overrride provided :class:`~acouchbase_analytics.options.ClusterOptions` Raises: - ValueError: If incorrect connstr is provided. + ValueError: If incorrect endpoint is provided. ValueError: If incorrect options are provided. """ # noqa: E501 def __init__( - self, connstr: str, credential: Credential, options: Optional[ClusterOptions] = None, **kwargs: object + self, endpoint: str, credential: Credential, options: Optional[ClusterOptions] = None, **kwargs: object ) -> None: from acouchbase_analytics.protocol.cluster import AsyncCluster as _AsyncCluster - self._impl = _AsyncCluster(connstr, credential, options, **kwargs) + self._impl = _AsyncCluster(endpoint, credential, options, **kwargs) def database(self, name: str) -> AsyncDatabase: """Creates a database instance. @@ -77,7 +77,7 @@ def database(self, name: str) -> AsyncDatabase: return AsyncDatabase(self._impl, name) def execute_query(self, statement: str, *args: object, **kwargs: object) -> Awaitable[AsyncQueryResult]: - """Executes a query against a Capella Columnar cluster. + """Executes a query against an Analytics cluster. .. note:: A departure from the operational SDK, the query is *NOT* executed lazily. @@ -142,7 +142,7 @@ def execute_query(self, statement: str, *args: object, **kwargs: object) -> Awai """ # noqa: E501 return self._impl.execute_query(statement, *args, **kwargs) - def shutdown(self) -> None: + async def shutdown(self) -> None: """Shuts down this cluster instance. Cleaning up all resources associated with it. .. warning:: @@ -151,18 +151,24 @@ def shutdown(self) -> None: is necessary and in those types of applications, this method might be beneficial. """ - return self._impl.shutdown() + return await self._impl.shutdown() @classmethod def create_instance( - cls, connstr: str, credential: Credential, options: Optional[ClusterOptions] = None, **kwargs: object + cls, endpoint: str, credential: Credential, options: Optional[ClusterOptions] = None, **kwargs: object ) -> AsyncCluster: """Create an AsyncCluster instance + .. important:: + The appropriate port needs to be specified. The SDK's default ports are 80 (http) and 443 (https). + If attempting to connect to Capella, the correct ports are most likely to be 8095 (http) and 18095 (https). + + Capella example: https://cb.2xg3vwszqgqcrsix.cloud.couchbase.com:18095 + Args: - connstr: - The connection string to use for connecting to the cluster. - The format of the connection string is the *scheme* (``couchbases`` as TLS enabled connections are _required_), followed a hostname + endpoint: + The endpoint to use for sending HTTP requests to the Analytics server. + The format of the endpoint string is the **scheme** (``http`` or ``https`` is *required*, use ``https`` for TLS enabled connections), followed a hostname and optional port. credential: User credentials. options: Global options to set for the cluster. Some operations allow the global options to be overriden by passing in options to the operation. @@ -170,32 +176,33 @@ def create_instance( Returns: - A Capella Columnar Cluster instance. + An Analytics Cluster instance. Raises: - ValueError: If incorrect connstr is provided. + ValueError: If incorrect endpoint is provided. ValueError: If incorrect options are provided. Examples: Initialize cluster using default options:: - from acouchbase_analytics import get_event_loop + import asyncio + from acouchbase_analytics.cluster import AsyncCluster from acouchbase_analytics.credential import Credential async def main() -> None: cred = Credential.from_username_and_password('username', 'password') - cluster = AsyncCluster.create_instance('couchbases://hostname', cred) + cluster = AsyncCluster.create_instance('https://hostname', cred) # ... other async code ... if __name__ == '__main__': - loop = get_event_loop() - loop.run_until_complete(main()) + asyncio.run(main()) Initialize cluster using with global timeout options:: + import asyncio from datetime import timedelta from acouchbase_analytics import get_event_loop @@ -206,15 +213,14 @@ async def main() -> None: async def main() -> None: cred = Credential.from_username_and_password('username', 'password') opts = ClusterOptions(timeout_options=ClusterTimeoutOptions(query_timeout=timedelta(seconds=120))) - cluster = AsyncCluster.create_instance('couchbases://hostname', cred, opts) + cluster = AsyncCluster.create_instance('https://hostname', cred, opts) # ... other async code ... if __name__ == '__main__': - loop = get_event_loop() - loop.run_until_complete(main()) + asyncio.run(main()) """ # noqa: E501 - return cls(connstr, credential, options, **kwargs) + return cls(endpoint, credential, options, **kwargs) Cluster: TypeAlias = AsyncCluster diff --git a/acouchbase_analytics/cluster.pyi b/acouchbase_analytics/cluster.pyi index 3969716..d45e3f1 100644 --- a/acouchbase_analytics/cluster.pyi +++ b/acouchbase_analytics/cluster.pyi @@ -28,15 +28,15 @@ from couchbase_analytics.result import AsyncQueryResult class AsyncCluster: @overload - def __init__(self, http_endpoint: str, credential: Credential) -> None: ... + def __init__(self, endpoint: str, credential: Credential) -> None: ... @overload - def __init__(self, http_endpoint: str, credential: Credential, options: ClusterOptions) -> None: ... + def __init__(self, endpoint: str, credential: Credential, options: ClusterOptions) -> None: ... @overload - def __init__(self, http_endpoint: str, credential: Credential, **kwargs: Unpack[ClusterOptionsKwargs]) -> None: ... + def __init__(self, endpoint: str, credential: Credential, **kwargs: Unpack[ClusterOptionsKwargs]) -> None: ... @overload def __init__( self, - http_endpoint: str, + endpoint: str, credential: Credential, options: ClusterOptions, **kwargs: Unpack[ClusterOptionsKwargs], @@ -62,20 +62,20 @@ class AsyncCluster: ) -> Awaitable[AsyncQueryResult]: ... @overload def execute_query(self, statement: str, *args: str, **kwargs: str) -> Awaitable[AsyncQueryResult]: ... - def shutdown(self) -> None: ... + def shutdown(self) -> Awaitable[None]: ... @overload @classmethod - def create_instance(cls, http_endpoint: str, credential: Credential) -> AsyncCluster: ... + def create_instance(cls, endpoint: str, credential: Credential) -> AsyncCluster: ... @overload @classmethod - def create_instance(cls, http_endpoint: str, credential: Credential, options: ClusterOptions) -> AsyncCluster: ... + def create_instance(cls, endpoint: str, credential: Credential, options: ClusterOptions) -> AsyncCluster: ... @overload @classmethod def create_instance( - cls, http_endpoint: str, credential: Credential, **kwargs: Unpack[ClusterOptionsKwargs] + cls, endpoint: str, credential: Credential, **kwargs: Unpack[ClusterOptionsKwargs] ) -> AsyncCluster: ... @overload @classmethod def create_instance( - cls, http_endpoint: str, credential: Credential, options: ClusterOptions, **kwargs: Unpack[ClusterOptionsKwargs] + cls, endpoint: str, credential: Credential, options: ClusterOptions, **kwargs: Unpack[ClusterOptionsKwargs] ) -> AsyncCluster: ... diff --git a/acouchbase_analytics/protocol/cluster.py b/acouchbase_analytics/protocol/cluster.py index 8e4ef32..ad12557 100644 --- a/acouchbase_analytics/protocol/cluster.py +++ b/acouchbase_analytics/protocol/cluster.py @@ -38,11 +38,11 @@ class AsyncCluster: def __init__( - self, connstr: str, credential: Credential, options: Optional[ClusterOptions] = None, **kwargs: object + self, endpoint: str, credential: Credential, options: Optional[ClusterOptions] = None, **kwargs: object ) -> None: self._cluster_id = str(uuid4()) kwargs['cluster_id'] = self._cluster_id - self._client_adapter = _AsyncClientAdapter(connstr, credential, options, **kwargs) + self._client_adapter = _AsyncClientAdapter(endpoint, credential, options, **kwargs) self._request_builder = _RequestBuilder(self._client_adapter) self._backend = current_async_library() @@ -115,9 +115,9 @@ def execute_query(self, statement: str, *args: object, **kwargs: object) -> Awai @classmethod def create_instance( - cls, connstr: str, credential: Credential, options: Optional[ClusterOptions] = None, **kwargs: object + cls, endpoint: str, credential: Credential, options: Optional[ClusterOptions] = None, **kwargs: object ) -> AsyncCluster: - return cls(connstr, credential, options, **kwargs) + return cls(endpoint, credential, options, **kwargs) Cluster: TypeAlias = AsyncCluster diff --git a/acouchbase_analytics/protocol/cluster.pyi b/acouchbase_analytics/protocol/cluster.pyi index 46d9767..d9f2429 100644 --- a/acouchbase_analytics/protocol/cluster.pyi +++ b/acouchbase_analytics/protocol/cluster.pyi @@ -29,20 +29,20 @@ from couchbase_analytics.options import ClusterOptions, ClusterOptionsKwargs, Qu class AsyncCluster: @overload - def __init__(self, connstr: str, credential: Credential) -> None: ... + def __init__(self, endpoint: str, credential: Credential) -> None: ... @overload - def __init__(self, connstr: str, credential: Credential, options: ClusterOptions) -> None: ... + def __init__(self, endpoint: str, credential: Credential, options: ClusterOptions) -> None: ... @overload - def __init__(self, connstr: str, credential: Credential, **kwargs: Unpack[ClusterOptionsKwargs]) -> None: ... + def __init__(self, endpoint: str, credential: Credential, **kwargs: Unpack[ClusterOptionsKwargs]) -> None: ... @overload def __init__( - self, connstr: str, credential: Credential, options: ClusterOptions, **kwargs: Unpack[ClusterOptionsKwargs] + self, endpoint: str, credential: Credential, options: ClusterOptions, **kwargs: Unpack[ClusterOptionsKwargs] ) -> None: ... @property def client_adapter(self) -> _AsyncClientAdapter: ... @property def connected(self) -> bool: ... - def shutdown(self) -> None: ... + def shutdown(self) -> Awaitable[None]: ... def database(self, name: str) -> AsyncDatabase: ... @overload def execute_query(self, statement: str) -> Awaitable[AsyncQueryResult]: ... @@ -66,17 +66,17 @@ class AsyncCluster: def execute_query(self, statement: str, *args: str, **kwargs: str) -> Awaitable[AsyncQueryResult]: ... @overload @classmethod - def create_instance(cls, connstr: str, credential: Credential) -> AsyncCluster: ... + def create_instance(cls, endpoint: str, credential: Credential) -> AsyncCluster: ... @overload @classmethod - def create_instance(cls, connstr: str, credential: Credential, options: ClusterOptions) -> AsyncCluster: ... + def create_instance(cls, endpoint: str, credential: Credential, options: ClusterOptions) -> AsyncCluster: ... @overload @classmethod def create_instance( - cls, connstr: str, credential: Credential, **kwargs: Unpack[ClusterOptionsKwargs] + cls, endpoint: str, credential: Credential, **kwargs: Unpack[ClusterOptionsKwargs] ) -> AsyncCluster: ... @overload @classmethod def create_instance( - cls, connstr: str, credential: Credential, options: ClusterOptions, **kwargs: Unpack[ClusterOptionsKwargs] + cls, endpoint: str, credential: Credential, options: ClusterOptions, **kwargs: Unpack[ClusterOptionsKwargs] ) -> AsyncCluster: ... diff --git a/acouchbase_analytics/scope.py b/acouchbase_analytics/scope.py index 7febf95..e9a7c31 100644 --- a/acouchbase_analytics/scope.py +++ b/acouchbase_analytics/scope.py @@ -44,7 +44,7 @@ def name(self) -> str: return self._impl.name def execute_query(self, statement: str, *args: object, **kwargs: object) -> Future[AsyncQueryResult]: - """Executes a query against a Capella Columnar scope. + """Executes a query against an Analytics scope. .. note:: A departure from the operational SDK, the query is *NOT* executed lazily. diff --git a/couchbase_analytics/_version.py b/couchbase_analytics/_version.py index 081f83c..d9de17b 100644 --- a/couchbase_analytics/_version.py +++ b/couchbase_analytics/_version.py @@ -1,5 +1,5 @@ # This file automatically generated by -# /Users/jaredcasey/GIT/couchbase/clients/python/analytics-python-client/couchbase_analytics_version.py +# /Users/jaredcasey/GIT/couchbase/clients/python/analytics-python-client/./couchbase_analytics_version.py # at -# 2025-07-24 17:08:38.315069 +# 2025-08-01 15:43:36.591881 __version__ = '0.0.1' diff --git a/couchbase_analytics/cluster.py b/couchbase_analytics/cluster.py index 8c728b9..12cb2d2 100644 --- a/couchbase_analytics/cluster.py +++ b/couchbase_analytics/cluster.py @@ -35,26 +35,26 @@ class Cluster: Use the static :meth:`.Cluster.create_instance` method to create a Cluster. Args: - http_endpoint: - The HTTP endpoint to use for sending requests to the Analytics server. - The format of the endpoint string is the *scheme* (``http`` or ``https`` is _required_), followed a hostname + endpoint: + The endpoint to use for sending HTTP requests to the Analytics server. + The format of the endpoint string is the **scheme** (``http`` or ``https`` is *required*, use ``https`` for TLS enabled connections), followed a hostname and optional port. credential: User credentials. options: Global options to set for the cluster. Some operations allow the global options to be overriden by passing in options to the operation. **kwargs: keyword arguments that can be used in place or to overrride provided :class:`~couchbase_analytics.options.ClusterOptions` Raises: - ValueError: If incorrect connstr is provided. + ValueError: If incorrect endpoint is provided. ValueError: If incorrect options are provided. """ # noqa: E501 def __init__( - self, http_endpoint: str, credential: Credential, options: Optional[ClusterOptions] = None, **kwargs: object + self, endpoint: str, credential: Credential, options: Optional[ClusterOptions] = None, **kwargs: object ) -> None: from couchbase_analytics.protocol.cluster import Cluster as _Cluster - self._impl = _Cluster(http_endpoint, credential, options, **kwargs) + self._impl = _Cluster(endpoint, credential, options, **kwargs) def database(self, name: str) -> Database: """Creates a database instance. @@ -151,14 +151,20 @@ def shutdown(self) -> None: @classmethod def create_instance( - cls, http_endpoint: str, credential: Credential, options: Optional[ClusterOptions] = None, **kwargs: object + cls, endpoint: str, credential: Credential, options: Optional[ClusterOptions] = None, **kwargs: object ) -> Cluster: """Create a Cluster instance + .. important:: + The appropriate port needs to be specified. The SDK's default ports are 80 (http) and 443 (https). + If attempting to connect to Capella, the correct ports are most likely to be 8095 (http) and 18095 (https). + + Capella example: https://cb.2xg3vwszqgqcrsix.cloud.couchbase.com:18095 + Args: - http_endpoint: - The HTTP endpoint to use for sending requests to the Analytics server. - The format of the endpoint string is the *scheme* (``http`` or ``https`` is _required_), followed a hostname + endpoint: + The endpoint to use for sending HTTP requests to the Analytics server. + The format of the endpoint string is the **scheme** (``http`` or ``https`` is *required*, use ``https`` for TLS enabled connections), followed a hostname and optional port. credential: User credentials. options: Global options to set for the cluster. Some operations allow the global options to be overriden by passing in options to the operation. @@ -169,7 +175,7 @@ def create_instance( An Analytics Cluster instance. Raises: - ValueError: If incorrect connstr is provided. + ValueError: If incorrect endpoint is provided. ValueError: If incorrect options are provided. @@ -196,4 +202,4 @@ def create_instance( cluster = Cluster.create_instance('https://hostname', cred, opts) """ # noqa: E501 - return cls(http_endpoint, credential, options, **kwargs) + return cls(endpoint, credential, options, **kwargs) diff --git a/couchbase_analytics/cluster.pyi b/couchbase_analytics/cluster.pyi index 9dcbfba..5a2e610 100644 --- a/couchbase_analytics/cluster.pyi +++ b/couchbase_analytics/cluster.pyi @@ -30,15 +30,15 @@ from couchbase_analytics.result import BlockingQueryResult class Cluster: @overload - def __init__(self, http_endpoint: str, credential: Credential) -> None: ... + def __init__(self, endpoint: str, credential: Credential) -> None: ... @overload - def __init__(self, http_endpoint: str, credential: Credential, options: ClusterOptions) -> None: ... + def __init__(self, endpoint: str, credential: Credential, options: ClusterOptions) -> None: ... @overload - def __init__(self, http_endpoint: str, credential: Credential, **kwargs: Unpack[ClusterOptionsKwargs]) -> None: ... + def __init__(self, endpoint: str, credential: Credential, **kwargs: Unpack[ClusterOptionsKwargs]) -> None: ... @overload def __init__( self, - http_endpoint: str, + endpoint: str, credential: Credential, options: ClusterOptions, **kwargs: Unpack[ClusterOptionsKwargs], @@ -117,17 +117,17 @@ class Cluster: def shutdown(self) -> None: ... @overload @classmethod - def create_instance(cls, http_endpoint: str, credential: Credential) -> Cluster: ... + def create_instance(cls, endpoint: str, credential: Credential) -> Cluster: ... @overload @classmethod - def create_instance(cls, http_endpoint: str, credential: Credential, options: ClusterOptions) -> Cluster: ... + def create_instance(cls, endpoint: str, credential: Credential, options: ClusterOptions) -> Cluster: ... @overload @classmethod def create_instance( - cls, http_endpoint: str, credential: Credential, **kwargs: Unpack[ClusterOptionsKwargs] + cls, endpoint: str, credential: Credential, **kwargs: Unpack[ClusterOptionsKwargs] ) -> Cluster: ... @overload @classmethod def create_instance( - cls, http_endpoint: str, credential: Credential, options: ClusterOptions, **kwargs: Unpack[ClusterOptionsKwargs] + cls, endpoint: str, credential: Credential, options: ClusterOptions, **kwargs: Unpack[ClusterOptionsKwargs] ) -> Cluster: ... diff --git a/couchbase_analytics/common/options.py b/couchbase_analytics/common/options.py index 387b2b3..d13b69f 100644 --- a/couchbase_analytics/common/options.py +++ b/couchbase_analytics/common/options.py @@ -51,7 +51,7 @@ class ClusterOptions(ClusterOptionsBase): Args: deserializer (Optional[Deserializer]): Set to configure global serializer to translate JSON to Python objects. Defaults to `None` (:class:`~couchbase_analytics.deserializer.DefaultJsonDeserializer`). - max_retries (Optional[int]): Set to configure the maximum number of retries for a request. Defaults to 7. + max_retries (Optional[int]): **VOLATILE** Set to configure the maximum number of retries for a request. Defaults to 7. security_options (Optional[:class:`.SecurityOptions`]): Security options for SDK connection. timeout_options (Optional[:class:`.TimeoutOptions`]): Timeout options for the various stages of a request. See :class:`.TimeoutOptions` for details. """ # noqa: E501 @@ -150,7 +150,7 @@ class QueryOptions(QueryOptionsBase): client_context_id (Optional[str]): Set to configure a unique identifier for this query request. Defaults to `None` (autogenerated by client). deserializer (Optional[Deserializer]): Specifies a :class:`~couchbase_analytics.deserializer.Deserializer` to apply to results. Defaults to `None` (:class:`~couchbase_analytics.deserializer.DefaultJsonDeserializer`). lazy_execute (Optional[bool]): **VOLATILE** If enabled, the query will not execute until the application begins to iterate over results. Defaulst to `None` (disabled). - max_retries (Optional[int]): Set to configure the maximum number of retries for a request. + max_retries (Optional[int]): **VOLATILE** Set to configure the maximum number of retries for a request. named_parameters (Optional[Dict[str, :py:type:`~couchbase_analytics.JSONType`]]): Values to use for positional placeholders in query. positional_parameters (Optional[List[:py:type:`~couchbase_analytics.JSONType`]]):, optional): Values to use for named placeholders in query. query_context (Optional[str]): Specifies the context within which this query should be executed. diff --git a/couchbase_analytics/common/result.py b/couchbase_analytics/common/result.py index c35e139..81d5431 100644 --- a/couchbase_analytics/common/result.py +++ b/couchbase_analytics/common/result.py @@ -48,7 +48,7 @@ def get_all_rows(self) -> List[Any]: Read all rows from simple query:: q_str = 'SELECT * FROM `travel-sample`.inventory WHERE country LIKE 'United%' LIMIT 2;' - q_rows = cluster.execute_query(q_str).all_rows() + q_rows = cluster.execute_query(q_str).get_all_rows() """ return BlockingIterator(self._http_response).get_all_rows() @@ -108,7 +108,7 @@ async def get_all_rows(self) -> List[Any]: Read all rows from simple query:: q_str = 'SELECT * FROM `travel-sample`.inventory WHERE country LIKE 'United%' LIMIT 2;' - q_rows = await cluster.execute_query(q_str).all_rows() + q_rows = await cluster.execute_query(q_str).get_all_rows() """ return await AsyncIterator(self._http_response).get_all_rows() diff --git a/couchbase_analytics/common/streaming.py b/couchbase_analytics/common/streaming.py index 5ccbfc5..286dd4d 100644 --- a/couchbase_analytics/common/streaming.py +++ b/couchbase_analytics/common/streaming.py @@ -17,8 +17,7 @@ from collections.abc import AsyncIterator as PyAsyncIterator from collections.abc import Iterator -from enum import IntEnum -from typing import TYPE_CHECKING, Any, List, NamedTuple +from typing import TYPE_CHECKING, Any, List from couchbase_analytics.common.errors import AnalyticsError, InternalSDKError @@ -96,22 +95,3 @@ async def __anext__(self) -> Any: raise err except Exception as ex: raise InternalSDKError(cause=ex, message='Error attempting to obtain next row.') from None - - -class HttpResponseType(IntEnum): - """ - **INTERNAL** - """ - - ROW = 0 - ERROR = 1 - END = 2 - - -class ParsedResult(NamedTuple): - """ - **INTERNAL** - """ - - result: str - result_type: HttpResponseType diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d4bb2cb --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# 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 ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# 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/docs/acouchbase_analytics_api/acouchbase_analytics.rst b/docs/acouchbase_analytics_api/acouchbase_analytics.rst new file mode 100644 index 0000000..1fef7ee --- /dev/null +++ b/docs/acouchbase_analytics_api/acouchbase_analytics.rst @@ -0,0 +1,51 @@ +=========================== +Asynchronous API +=========================== + + +:doc:`acouchbase_analytics_core` + API reference for Cluster, Database and Scope objects. + +:doc:`credential` + API reference for Credential. + +:doc:`query` + API reference for query (SQL++) operations. + +:doc:`options` + API reference for operation options. + +:doc:`results` + API reference for operation results. + +:doc:`errors` + API reference for Errors. + +:doc:`enums` + API reference for Enums. + +:doc:`types` + API reference for Types. + +:doc:`deserializers` + API reference for Deserializers. + +:doc:`async_overload_details` + Asynchronous API Overload Detail. + + +.. Hidden TOCs +.. toctree:: + :maxdepth: 3 + :hidden: + + acouchbase_analytics_core + credential + query + options + results + errors + enums + types + deserializers + async_overload_details diff --git a/docs/acouchbase_analytics_api/acouchbase_analytics_core.rst b/docs/acouchbase_analytics_api/acouchbase_analytics_core.rst new file mode 100644 index 0000000..f07415d --- /dev/null +++ b/docs/acouchbase_analytics_api/acouchbase_analytics_core.rst @@ -0,0 +1,48 @@ +====================================== +Core API +====================================== + + +.. contents:: + :local: + +AsyncCluster +============== + +.. module:: acouchbase_analytics.cluster +.. autoclass:: AsyncCluster + + .. important:: + See :ref:`AsyncCluster Overloads` for details on overloaded methods. + + .. automethod:: create_instance + .. automethod:: database + + .. important:: + See :ref:`AsyncCluster Overloads` for details on overloaded methods. + + .. automethod:: execute_query + .. automethod:: shutdown + + +AsyncDatabase +============== + +.. module:: acouchbase_analytics.database +.. autoclass:: AsyncDatabase + + .. autoproperty:: name + .. automethod:: scope + +AsyncScope +============== + +.. module:: acouchbase_analytics.scope +.. autoclass:: AsyncScope + + .. autoproperty:: name + + .. important:: + See :ref:`AsyncScope Overloads` for details on overloaded methods. + + .. automethod:: execute_query diff --git a/docs/acouchbase_analytics_api/async_overload_details.rst b/docs/acouchbase_analytics_api/async_overload_details.rst new file mode 100644 index 0000000..77b14a7 --- /dev/null +++ b/docs/acouchbase_analytics_api/async_overload_details.rst @@ -0,0 +1,9 @@ +============================== +Overloads +============================== + +.. toctree:: + :maxdepth: 2 + + overloads/async_cluster_overloads + overloads/async_scope_overloads diff --git a/docs/acouchbase_analytics_api/credential.rst b/docs/acouchbase_analytics_api/credential.rst new file mode 100644 index 0000000..6f6c617 --- /dev/null +++ b/docs/acouchbase_analytics_api/credential.rst @@ -0,0 +1,15 @@ +================ +Credential +================ + +.. _async-credential-ref: + +.. module:: acouchbase_analytics.credential + +.. autoclass:: Credential + :no-index: + + .. automethod:: from_username_and_password + :no-index: + .. automethod:: from_callable + :no-index: diff --git a/docs/acouchbase_analytics_api/deserializers.rst b/docs/acouchbase_analytics_api/deserializers.rst new file mode 100644 index 0000000..d408b2a --- /dev/null +++ b/docs/acouchbase_analytics_api/deserializers.rst @@ -0,0 +1,31 @@ +============== +Deserializers +============== + +.. contents:: + :local: + +.. module:: acouchbase_analytics.deserializer + +Deserializer +++++++++++++++++++++++++++++++++ +.. py:class:: Deserializer + :no-index: + + Abstract base class for deserializers. + + .. automethod:: deserialize + +DefaultJsonDeserializer +++++++++++++++++++++++++++++++++ + +.. autoclass:: DefaultJsonDeserializer + :no-index: + :members: + +PassthroughDeserializer +++++++++++++++++++++++++++++++++ + +.. autoclass:: PassthroughDeserializer + :no-index: + :members: diff --git a/docs/acouchbase_analytics_api/enums.rst b/docs/acouchbase_analytics_api/enums.rst new file mode 100644 index 0000000..d7c5c51 --- /dev/null +++ b/docs/acouchbase_analytics_api/enums.rst @@ -0,0 +1,16 @@ +============== +Enums +============== + +.. contents:: + :local: + +QueryScanConsistency +++++++++++++++++++++++++++++++++ +.. module:: acouchbase_analytics.query + :no-index: +.. autoenum:: QueryScanConsistency + :no-index: + +.. module:: acouchbase_analytics.options + :no-index: diff --git a/docs/acouchbase_analytics_api/errors.rst b/docs/acouchbase_analytics_api/errors.rst new file mode 100644 index 0000000..4ffd789 --- /dev/null +++ b/docs/acouchbase_analytics_api/errors.rst @@ -0,0 +1,37 @@ +============== +Errors +============== + +.. contents:: + :local: + +.. module:: acouchbase_analytics.errors + + +AnalyticsError +++++++++++++++++++++++++++++++++ +.. autoclass:: AnalyticsError + :no-index: + +InvalidCredentialError +++++++++++++++++++++++++++++++++ +.. autoclass:: InvalidCredentialError + :no-index: + +QueryError +++++++++++++++++++++++++++++++++ +.. autoclass:: QueryError + :no-index: + + .. autoproperty:: code + .. autoproperty:: server_message + +TimeoutError +++++++++++++++++++++++++++++++++ +.. autoclass:: TimeoutError + :no-index: + +InternalSDKError +++++++++++++++++++++++++++++++++ +.. autoclass:: InternalSDKError + :no-index: diff --git a/docs/acouchbase_analytics_api/options.rst b/docs/acouchbase_analytics_api/options.rst new file mode 100644 index 0000000..e120bf5 --- /dev/null +++ b/docs/acouchbase_analytics_api/options.rst @@ -0,0 +1,65 @@ +============== +Options +============== + +.. contents:: + :local: + :depth: 2 + :backlinks: none + +.. module:: acouchbase_analytics.options + + +Option Classes +================= + +ClusterOptions +++++++++++++++++++++++ +.. autoclass:: ClusterOptions + :no-index: + +SecurityOptions +++++++++++++++++++++++ +.. autoclass:: SecurityOptions + :no-index: + +TimeoutOptions +++++++++++++++++++++++ +.. autoclass:: TimeoutOptions + :no-index: + +QueryOptions +++++++++++++++++++++++ +.. autoclass:: QueryOptions + :no-index: + +Option TypeDict Classes +========================= + +ClusterOptionsKwargs +++++++++++++++++++++++ +.. autoclass:: ClusterOptionsKwargs + :no-index: + :members: + :undoc-members: + +SecurityOptionsKwargs +++++++++++++++++++++++ +.. autoclass:: SecurityOptionsKwargs + :no-index: + :members: + :undoc-members: + +TimeoutOptionsKwargs +++++++++++++++++++++++ +.. autoclass:: TimeoutOptionsKwargs + :no-index: + :members: + :undoc-members: + +QueryOptionsKwargs +++++++++++++++++++++++ +.. autoclass:: QueryOptionsKwargs + :no-index: + :members: + :undoc-members: diff --git a/docs/acouchbase_analytics_api/overloads/async_cluster_overloads.rst b/docs/acouchbase_analytics_api/overloads/async_cluster_overloads.rst new file mode 100644 index 0000000..4949db0 --- /dev/null +++ b/docs/acouchbase_analytics_api/overloads/async_cluster_overloads.rst @@ -0,0 +1,76 @@ +======================= +AsyncCluster Overloads +======================= + +.. _async-cluster-overloads-ref: + +AsyncCluster +============== + +.. module:: acouchbase_analytics.cluster + :no-index: + +.. important:: + Not all class methods are listed. Only methods that allow overloads. + +.. py:class:: AsyncCluster + :no-index: + + .. py:method:: execute_query(statement: str) -> Awaitable[AsyncQueryResult] + execute_query(statement: str, options: QueryOptions) -> Awaitable[AsyncQueryResult] + execute_query(statement: str, **kwargs: QueryOptionsKwargs) -> Awaitable[AsyncQueryResult] + execute_query(statement: str, options: QueryOptions, **kwargs: QueryOptionsKwargs) -> Awaitable[AsyncQueryResult] + execute_query(statement: str, options: QueryOptions, *args: JSONType, **kwargs: QueryOptionsKwargs) -> Awaitable[AsyncQueryResult] + execute_query(statement: str, options: QueryOptions, *args: JSONType, **kwargs: str) -> Awaitable[AsyncQueryResult] + execute_query(statement: str, *args: JSONType, **kwargs: str) -> Awaitable[AsyncQueryResult] + :no-index: + + Executes a query against a Capella analytics cluster. + + .. important:: + The cancel API is **VOLATILE** and is subject to change at any time. + + :param statement: The SQL++ statement to execute. + :type statement: str + :param options: Options to set for the query. + :type options: Optional[:class:`~acouchbase_analytics.options.QueryOptions`] + :param \*args: Can be used to pass in positional query placeholders. + :type \*args: Optional[:py:type:`~acouchbase_analytics.JSONType`] + :param \*\*kwargs: Keyword arguments that can be used in place or to overrride provided :class:`~acouchbase_analytics.options.ClusterOptions`. + Can also be used to pass in named query placeholders. + :type \*\*kwargs: Optional[Union[:class:`~acouchbase_analytics.options.QueryOptionsKwargs`, str]] + + :returns: An `Awaitable` is returned. Once the `Awaitable` completes, an instance of a :class:`~acouchbase_analytics.result.AsyncQueryResult` will be available. + :rtype: Awaitable[:class:`~acouchbase_analytics.result.AsyncQueryResult`] + + .. py:method:: create_instance(endpoint: str, credential: Credential) -> AsyncCluster + create_instance(endpoint: str, credential: Credential, options: ClusterOptions) -> AsyncCluster + create_instance(endpoint: str, credential: Credential, **kwargs: ClusterOptionsKwargs) -> AsyncCluster + create_instance(endpoint: str, credential: Credential, options: ClusterOptions, **kwargs: ClusterOptionsKwargs) -> AsyncCluster + :classmethod: + :no-index: + + Create a Cluster instance + + .. important:: + The appropriate port needs to be specified. The SDK's default ports are 80 (http) and 443 (https). + If attempting to connect to Capella, the correct ports are most likely to be 8095 (http) and 18095 (https). + + Capella example: https://cb.2xg3vwszqgqcrsix.cloud.couchbase.com:18095 + + :param endpoint: The endpoint to use for sending HTTP requests to the Analytics server. + The format of the endpoint string is the **scheme** (``http`` or ``https`` is *required*, use ``https`` for TLS enabled connections), followed a hostname and optional port. + :type endpoint: str + :param credential: The user credentials. + :type credential: :class:`~acouchbase_analytics.credential.Credential` + :param options: Global options to set for the cluster. + Some operations allow the global options to be overriden by passing in options to the operation. + :type options: Optional[:class:`~acouchbase_analytics.options.ClusterOptions`] + :param \*\*kwargs: Keyword arguments that can be used in place or to overrride provided :class:`~acouchbase_analytics.options.ClusterOptions` + :type \*\*kwargs: Optional[:class:`~acouchbase_analytics.options.ClusterOptionsKwargs`] + + :returns: An Analytics AsyncCluster instance. + :rtype: :class:`.AsyncCluster` + + :raises ValueError: If incorrect endpoint is provided. + :raises ValueError: If incorrect options are provided. diff --git a/docs/acouchbase_analytics_api/overloads/async_scope_overloads.rst b/docs/acouchbase_analytics_api/overloads/async_scope_overloads.rst new file mode 100644 index 0000000..c84a135 --- /dev/null +++ b/docs/acouchbase_analytics_api/overloads/async_scope_overloads.rst @@ -0,0 +1,44 @@ +===================== +AsyncScope Overloads +===================== + +.. _async-scope-overloads-ref: + +AsyncScope +============== + +.. module:: acouchbase_analytics.scope + :no-index: + +.. important:: + Not all class methods are listed. Only methods that allow overloads. + +.. py:class:: AysncScope + :no-index: + + .. py:method:: execute_query(statement: str) -> Future[AsyncQueryResult] + execute_query(statement: str, options: QueryOptions) -> Future[AsyncQueryResult] + execute_query(statement: str, **kwargs: QueryOptionsKwargs) -> Future[AsyncQueryResult] + execute_query(statement: str, options: QueryOptions, **kwargs: QueryOptionsKwargs) -> BlockingQueryResult + execute_query(statement: str, options: QueryOptions, *args: JSONType, **kwargs: QueryOptionsKwargs) -> Future[AsyncQueryResult] + execute_query(statement: str, options: QueryOptions, *args: JSONType, **kwargs: str) -> Future[AsyncQueryResult] + execute_query(statement: str, *args: JSONType, **kwargs: str) -> Future[AsyncQueryResult] + :no-index: + + Executes a query against a Capella analytics scope. + + .. important:: + The cancel API is **VOLATILE** and is subject to change at any time. + + :param statement: The SQL++ statement to execute. + :type statement: str + :param options: Options to set for the query. + :type options: Optional[:class:`~acouchbase_analytics.options.QueryOptions`] + :param \*args: Can be used to pass in positional query placeholders. + :type \*args: Optional[:py:type:`~acouchbase_analytics.JSONType`] + :param \*\*kwargs: Keyword arguments that can be used in place or to overrride provided :class:`~acouchbase_analytics.options.ClusterOptions`. + Can also be used to pass in named query placeholders. + :type \*\*kwargs: Optional[Union[:class:`~acouchbase_analytics.options.QueryOptionsKwargs`, str]] + + :returns: A :class:`~asyncio.Future` is returned. Once the :class:`~asyncio.Future` completes, an instance of a :class:`~acouchbase_analytics.result.AsyncQueryResult` will be available. + :rtype: Future[:class:`~acouchbase_analytics.result.AsyncQueryResult`] diff --git a/docs/acouchbase_analytics_api/query.rst b/docs/acouchbase_analytics_api/query.rst new file mode 100644 index 0000000..6d9869c --- /dev/null +++ b/docs/acouchbase_analytics_api/query.rst @@ -0,0 +1,77 @@ +============== +Query (SQL++) +============== + +.. contents:: + :local: + :depth: 2 + + +Enumerations +=============== + +.. module:: acouchbase_analytics.query +.. autoenum:: QueryScanConsistency + :no-index: + + +Options +=============== + +.. module:: acouchbase_analytics.options + :no-index: + +.. autoclass:: QueryOptions + :no-index: + + +Results +=============== + +AsyncQueryResult ++++++++++++++++++++ +.. module:: acouchbase_analytics.result + :no-index: + +.. py:class:: AsyncQueryResult + :no-index: + + .. automethod:: cancel + :no-index: + .. automethod:: rows + :no-index: + .. automethod:: get_all_rows + :no-index: + .. automethod:: metadata + :no-index: + +.. module:: acouchbase_analytics.query + :no-index: + +QueryMetadata ++++++++++++++++++++ +.. py:class:: QueryMetadata + :no-index: + + .. automethod:: request_id + .. automethod:: warnings + .. automethod:: metrics + +QueryMetrics ++++++++++++++++++++ +.. py:class:: QueryMetrics + :no-index: + + .. automethod:: elapsed_time + .. automethod:: execution_time + .. automethod:: result_count + .. automethod:: result_size + .. automethod:: processed_objects + +QueryWarning ++++++++++++++++++++ +.. py:class:: QueryWarning + :no-index: + + .. automethod:: code + .. automethod:: message diff --git a/docs/acouchbase_analytics_api/results.rst b/docs/acouchbase_analytics_api/results.rst new file mode 100644 index 0000000..c67ec7b --- /dev/null +++ b/docs/acouchbase_analytics_api/results.rst @@ -0,0 +1,15 @@ +============== +Results +============== + +.. module:: acouchbase_analytics.result + +AsyncQueryResult +===================== + +.. py:class:: AsyncQueryResult + + .. automethod:: cancel + .. automethod:: rows + .. automethod:: get_all_rows + .. automethod:: metadata diff --git a/docs/acouchbase_analytics_api/types.rst b/docs/acouchbase_analytics_api/types.rst new file mode 100644 index 0000000..2a86382 --- /dev/null +++ b/docs/acouchbase_analytics_api/types.rst @@ -0,0 +1,16 @@ +============== +Types +============== + +.. contents:: + :local: + +TypeAliases ++++++++++++++++++++ + +.. module:: acouchbase_analytics + :no-index: + +.. py:type:: JSONType + + :canonical: Union[str, int, float, bool, None, Dict[str, Any], List[Any]] diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..d94cd97 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,120 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +import os +import sys + +sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.dirname(__file__)) + +# -- Project information ----------------------------------------------------- + +project = 'Couchbase Python Analytics Client Library' +copyright = '2025, Couchbase, Inc.' +author = 'Couchbase, Inc.' + +# from .. import couchbase_version +import couchbase_analytics_version # nopep8 # isort:skip # noqa: E402 + +try: + from datetime import datetime + year = f'{datetime.today():%Y}' +except BaseException: + year = '2024' +copyright = f'2016-{year}, Couchbase, Inc.' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +sdk_version = couchbase_analytics_version.get_version() +version = sdk_version +release = sdk_version + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx_rtd_theme', + 'sphinx.ext.autodoc', + 'sphinx.ext.napoleon', + 'sphinx.ext.extlinks', + 'sphinx_copybutton', + 'enum_tools.autoenum', + # 'sphinx.ext.autodoc.typehints', + # 'sphinx_toolbox.more_autodoc.overloads', + 'sphinx_autodoc_typehints', + 'sphinx.ext.intersphinx' +] + +typehints_use_signature = True +autodoc_type_aliases = {'JSONType': 'couchbase_analytics.common.JSONType'} + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'docs_mock'] + +intersphinx_mapping = {'python': ('https://docs.python.org/3', None)} + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' +# html_theme = 'classic' + +html_theme_options = { + 'display_version': True, +} + +# 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 = [] + +# The docs are unclear, but adding the `%s` to the end of the URL prevents: +# TypeError: not all arguments converted during string formatting +extlinks = { + 'couchbase_dev_portal': ('https://developer.couchbase.com/%s', None), + 'couchbase_discord': ('https://discord.com/invite/sQ5qbPZuTh%s', None), + 'analytics_sdk_github': ('https://github.com/couchbaselabs/analytics-python-client%s', None), + 'acouchbase_analytics_examples': + ('https://github.com/couchbaselabs/analytics-python-client/tree/main/async/examples%s', None), + 'couchbase_analytics_examples': + ('https://github.com/couchbaselabs/analytics-python-client/tree/main/sync/examples%s', None), + 'analytics_sdk_jira': ('https://issues.couchbase.com/projects/PYCO/issues/%s', None), + 'analytics_sdk_docs': ('https://docs.couchbase.com/python-sdk/current/hello-world/overview.html%s', None), + 'analytics_sdk_release_notes': + ('https://docs.couchbase.com/python-sdk/current/project-docs/sdk-release-notes.html%s', None), + 'analytics_sdk_compatibility': + ('https://docs.couchbase.com/python-sdk/current/project-docs/compatibility.html%s', None), + 'analytics_sdk_forums': ('https://forums.couchbase.com/c/python-sdk/10%s', None), + 'analytics_sdk_license': ('https://github.com/couchbaselabs/analytics-python-client/blob/main/LICENSE%s', None), + 'analytics_sdk_contribute': + ('https://github.com/couchbaselabs/analytics-python-client/blob/main/CONTRIBUTING.md%s', None), + 'analytics_sdk_version_compat': + ('https://docs.couchbase.com/python-sdk/current/project-docs/compatibility.html#python-version-compat%s', None), +} diff --git a/docs/couchbase_analytics_api/couchbase_analytics.rst b/docs/couchbase_analytics_api/couchbase_analytics.rst new file mode 100644 index 0000000..fc022bc --- /dev/null +++ b/docs/couchbase_analytics_api/couchbase_analytics.rst @@ -0,0 +1,50 @@ +=========================== +Synchronous API +=========================== + +:doc:`couchbase_analytics_core` + API reference for Cluster, Database and Scope objects. + +:doc:`credential` + API reference for Credential. + +:doc:`query` + API reference for query (SQL++) operations. + +:doc:`options` + API reference for operation options. + +:doc:`results` + API reference for operation results. + +:doc:`errors` + API reference for Errors. + +:doc:`enums` + API reference for Enums. + +:doc:`types` + API reference for Types. + +:doc:`deserializers` + API reference for Deserializers. + +:doc:`overload_details` + Synchronous API Overload Detail. + + +.. Hidden TOCs +.. toctree:: + :maxdepth: 3 + :hidden: + + couchbase_analytics_core + credential + query + options + results + errors + enums + types + deserializers + overload_details diff --git a/docs/couchbase_analytics_api/couchbase_analytics_core.rst b/docs/couchbase_analytics_api/couchbase_analytics_core.rst new file mode 100644 index 0000000..009ade0 --- /dev/null +++ b/docs/couchbase_analytics_api/couchbase_analytics_core.rst @@ -0,0 +1,47 @@ +=========================== +Core API +=========================== + +.. contents:: + :local: + +Cluster +============== + +.. module:: couchbase_analytics.cluster +.. autoclass:: Cluster + + .. important:: + See :ref:`Cluster Overloads` for details on overloaded methods. + + .. automethod:: create_instance + .. automethod:: database + + .. important:: + See :ref:`Cluster Overloads` for details on overloaded methods. + + .. automethod:: execute_query + .. automethod:: shutdown + + +Database +============== + +.. module:: couchbase_analytics.database +.. autoclass:: Database + + .. autoproperty:: name + .. automethod:: scope + +Scope +============== + +.. module:: couchbase_analytics.scope +.. autoclass:: Scope + + .. autoproperty:: name + + .. important:: + See :ref:`Scope Overloads` for details on overloaded methods. + + .. automethod:: execute_query diff --git a/docs/couchbase_analytics_api/credential.rst b/docs/couchbase_analytics_api/credential.rst new file mode 100644 index 0000000..47ced06 --- /dev/null +++ b/docs/couchbase_analytics_api/credential.rst @@ -0,0 +1,12 @@ +================ +Credential +================ + +.. _credential-ref: + +.. module:: couchbase_analytics.credential + +.. autoclass:: Credential + + .. automethod:: from_username_and_password + .. automethod:: from_callable diff --git a/docs/couchbase_analytics_api/deserializers.rst b/docs/couchbase_analytics_api/deserializers.rst new file mode 100644 index 0000000..0d2d9ec --- /dev/null +++ b/docs/couchbase_analytics_api/deserializers.rst @@ -0,0 +1,29 @@ +============== +Deserializers +============== + +.. contents:: + :local: + +.. module:: couchbase_analytics.deserializer + +Deserializer +++++++++++++++++++++++++++++++++ +.. py:class:: Deserializer + + Abstract base class for deserializers. + + .. automethod:: deserialize + +DefaultJsonDeserializer +++++++++++++++++++++++++++++++++ + +.. autoclass:: DefaultJsonDeserializer + :members: + + +PassthroughDeserializer +++++++++++++++++++++++++++++++++ + +.. autoclass:: PassthroughDeserializer + :members: diff --git a/docs/couchbase_analytics_api/enums.rst b/docs/couchbase_analytics_api/enums.rst new file mode 100644 index 0000000..e77d1f7 --- /dev/null +++ b/docs/couchbase_analytics_api/enums.rst @@ -0,0 +1,16 @@ +============== +Enums +============== + +.. contents:: + :local: + +QueryScanConsistency +++++++++++++++++++++++++++++++++ +.. module:: couchbase_analytics.query + :no-index: +.. autoenum:: QueryScanConsistency + :no-index: + +.. module:: couchbase_analytics.options + :no-index: diff --git a/docs/couchbase_analytics_api/errors.rst b/docs/couchbase_analytics_api/errors.rst new file mode 100644 index 0000000..b87f371 --- /dev/null +++ b/docs/couchbase_analytics_api/errors.rst @@ -0,0 +1,32 @@ +============== +Errors +============== + +.. contents:: + :local: + +.. module:: couchbase_analytics.errors + + +AnalyticsError +++++++++++++++++++++++++++++++++ +.. autoclass:: AnalyticsError + +InvalidCredentialError +++++++++++++++++++++++++++++++++ +.. autoclass:: InvalidCredentialError + +QueryError +++++++++++++++++++++++++++++++++ +.. autoclass:: QueryError + + .. autoproperty:: code + .. autoproperty:: server_message + +TimeoutError +++++++++++++++++++++++++++++++++ +.. autoclass:: TimeoutError + +InternalSDKError +++++++++++++++++++++++++++++++++ +.. autoclass:: InternalSDKError diff --git a/docs/couchbase_analytics_api/options.rst b/docs/couchbase_analytics_api/options.rst new file mode 100644 index 0000000..f035605 --- /dev/null +++ b/docs/couchbase_analytics_api/options.rst @@ -0,0 +1,58 @@ +============== +Options +============== + +.. contents:: + :local: + :depth: 2 + :backlinks: none + +.. module:: couchbase_analytics.options + + +Option Classes +================= + +ClusterOptions +++++++++++++++++++++++ +.. autoclass:: ClusterOptions + +SecurityOptions +++++++++++++++++++++++ +.. autoclass:: SecurityOptions + +TimeoutOptions +++++++++++++++++++++++ +.. autoclass:: TimeoutOptions + +QueryOptions +++++++++++++++++++++++ +.. autoclass:: QueryOptions + + +Option TypeDict Classes +========================= + +ClusterOptionsKwargs +++++++++++++++++++++++ +.. autoclass:: ClusterOptionsKwargs + :members: + :undoc-members: + +SecurityOptionsKwargs +++++++++++++++++++++++ +.. autoclass:: SecurityOptionsKwargs + :members: + :undoc-members: + +TimeoutOptionsKwargs +++++++++++++++++++++++ +.. autoclass:: TimeoutOptionsKwargs + :members: + :undoc-members: + +QueryOptionsKwargs +++++++++++++++++++++++ +.. autoclass:: QueryOptionsKwargs + :members: + :undoc-members: diff --git a/docs/couchbase_analytics_api/overload_details.rst b/docs/couchbase_analytics_api/overload_details.rst new file mode 100644 index 0000000..e65e04c --- /dev/null +++ b/docs/couchbase_analytics_api/overload_details.rst @@ -0,0 +1,9 @@ +============================ +Overloads +============================ + +.. toctree:: + :maxdepth: 2 + + overloads/cluster_overloads + overloads/scope_overloads diff --git a/docs/couchbase_analytics_api/overloads/cluster_overloads.rst b/docs/couchbase_analytics_api/overloads/cluster_overloads.rst new file mode 100644 index 0000000..41e53ea --- /dev/null +++ b/docs/couchbase_analytics_api/overloads/cluster_overloads.rst @@ -0,0 +1,91 @@ +================= +Cluster Overloads +================= + +.. _cluster-overloads-ref: + +Cluster +============== + +.. module:: couchbase_analytics.cluster + :no-index: + +.. important:: + Not all class methods are listed. Only methods that allow overloads. + +.. py:class:: Cluster + :no-index: + + .. py:method:: execute_query(statement: str) -> BlockingQueryResult + execute_query(statement: str, options: QueryOptions) -> BlockingQueryResult + execute_query(statement: str, **kwargs: QueryOptionsKwargs) -> BlockingQueryResult + execute_query(statement: str, options: QueryOptions, **kwargs: QueryOptionsKwargs) -> BlockingQueryResult + execute_query(statement: str, options: QueryOptions, *args: JSONType, **kwargs: QueryOptionsKwargs) -> BlockingQueryResult + execute_query(statement: str, options: QueryOptions, *args: JSONType, **kwargs: str) -> BlockingQueryResult + execute_query(statement: str, *args: JSONType, **kwargs: str) -> BlockingQueryResult + execute_query(statement: str, enable_cancel: bool) -> Future[BlockingQueryResult] + execute_query(statement: str, enable_cancel: bool, *args: JSONType) -> Future[BlockingQueryResult] + execute_query(statement: str, options: QueryOptions, enable_cancel: bool) -> Future[BlockingQueryResult] + execute_query(statement: str, enable_cancel: bool, **kwargs: QueryOptionsKwargs) -> Future[BlockingQueryResult] + execute_query(statement: str, options: QueryOptions, enable_cancel: bool, **kwargs: QueryOptionsKwargs) -> Future[BlockingQueryResult] + execute_query(statement: str, options: QueryOptions, enable_cancel: bool, *args: JSONType, **kwargs: QueryOptionsKwargs) -> Future[BlockingQueryResult] + execute_query(statement: str, options: QueryOptions, *args: JSONType, enable_cancel: bool, **kwargs: QueryOptionsKwargs) -> Future[BlockingQueryResult] + execute_query(statement: str, options: QueryOptions, enable_cancel: bool, *args: JSONType, **kwargs: str) -> Future[BlockingQueryResult] + execute_query(statement: str, options: QueryOptions, *args: JSONType, enable_cancel: bool, **kwargs: str) -> Future[BlockingQueryResult] + execute_query(statement: str, enable_cancel: bool, *args: JSONType, **kwargs: str) -> Future[BlockingQueryResult] + execute_query(statement: str, *args: JSONType, enable_cancel: bool, **kwargs: str) -> Future[BlockingQueryResult] + :no-index: + + Executes a query against an Analytics cluster. + + .. important:: + The cancel API is **VOLATILE** and is subject to change at any time. + + :param statement: The SQL++ statement to execute. + :type statement: str + :param options: Options to set for the query. + :type options: Optional[:class:`~couchbase_analytics.options.QueryOptions`] + :param enable_cancel: Enable cancellation of the result or results stream. + :type enable_cancel: Optional[bool] + :param \*args: Can be used to pass in positional query placeholders. + :type \*args: Optional[:py:type:`~couchbase_analytics.JSONType`] + :param \*\*kwargs: Keyword arguments that can be used in place or to overrride provided :class:`~couchbase_analytics.options.ClusterOptions`. + Can also be used to pass in named query placeholders. + :type \*\*kwargs: Optional[Union[:class:`~couchbase_analytics.options.QueryOptionsKwargs`, str]] + + :returns: An instance of :class:`~couchbase_analytics.result.BlockingQueryResult`. When a cancel token is provided + a :class:`~concurrent.futures.Future` is returned. Once the :class:`~concurrent.futures.Future` completes, an instance of a :class:`~couchbase_analytics.result.BlockingQueryResult` will be available. + :rtype: Union[Future[:class:`~couchbase_analytics.result.BlockingQueryResult`], :class:`~couchbase_analytics.result.BlockingQueryResult`] + + .. py:method:: create_instance(endpoint: str, credential: Credential) -> Cluster + create_instance(endpoint: str, credential: Credential, options: ClusterOptions) -> Cluster + create_instance(endpoint: str, credential: Credential, **kwargs: ClusterOptionsKwargs) -> Cluster + create_instance(endpoint: str, credential: Credential, options: ClusterOptions, **kwargs: ClusterOptionsKwargs) -> Cluster + :classmethod: + :no-index: + + Create a Cluster instance + + .. important:: + The appropriate port needs to be specified. The SDK's default ports are 80 (http) and 443 (https). + If attempting to connect to Capella, the correct ports are most likely to be 8095 (http) and 18095 (https). + + Capella example: https://cb.2xg3vwszqgqcrsix.cloud.couchbase.com:18095 + + + :param endpoint: The endpoint to use for sending HTTP requests to the Analytics server. + The format of the endpoint string is the **scheme** (``http`` or ``https`` is *required*, use ``https`` for TLS enabled connections), followed a hostname and optional port. + :type endpoint: str + :param credential: The user credentials. + :type credential: :class:`~couchbase_analytics.credential.Credential` + :param options: Global options to set for the cluster. + Some operations allow the global options to be overriden by passing in options to the operation. + :type options: Optional[:class:`~couchbase_analytics.options.ClusterOptions`] + :param \*\*kwargs: Keyword arguments that can be used in place or to overrride provided :class:`~couchbase_analytics.options.ClusterOptions` + :type \*\*kwargs: Optional[:class:`~couchbase_analytics.options.ClusterOptionsKwargs`] + + :returns: An Analytics Cluster instance. + :rtype: :class:`.Cluster` + + :raises ValueError: If incorrect endpoint is provided. + :raises ValueError: If incorrect options are provided. diff --git a/docs/couchbase_analytics_api/overloads/scope_overloads.rst b/docs/couchbase_analytics_api/overloads/scope_overloads.rst new file mode 100644 index 0000000..40c58d9 --- /dev/null +++ b/docs/couchbase_analytics_api/overloads/scope_overloads.rst @@ -0,0 +1,58 @@ +================= +Scope Overloads +================= + +.. _scope-overloads-ref: + +Scope +============== + +.. module:: couchbase_analytics.scope + :no-index: + +.. important:: + Not all class methods are listed. Only methods that allow overloads. + +.. py:class:: Scope + :no-index: + + .. py:method:: execute_query(statement: str) -> BlockingQueryResult + execute_query(statement: str, options: QueryOptions) -> BlockingQueryResult + execute_query(statement: str, **kwargs: QueryOptionsKwargs) -> BlockingQueryResult + execute_query(statement: str, options: QueryOptions, **kwargs: QueryOptionsKwargs) -> BlockingQueryResult + execute_query(statement: str, options: QueryOptions, *args: JSONType, **kwargs: QueryOptionsKwargs) -> BlockingQueryResult + execute_query(statement: str, options: QueryOptions, *args: JSONType, **kwargs: str) -> BlockingQueryResult + execute_query(statement: str, *args: JSONType, **kwargs: str) -> BlockingQueryResult + execute_query(statement: str, enable_cancel: bool) -> Future[BlockingQueryResult] + execute_query(statement: str, enable_cancel: bool, *args: JSONType) -> Future[BlockingQueryResult] + execute_query(statement: str, options: QueryOptions, enable_cancel: bool) -> Future[BlockingQueryResult] + execute_query(statement: str, enable_cancel: bool, **kwargs: QueryOptionsKwargs) -> Future[BlockingQueryResult] + execute_query(statement: str, options: QueryOptions, enable_cancel: bool, **kwargs: QueryOptionsKwargs) -> Future[BlockingQueryResult] + execute_query(statement: str, options: QueryOptions, enable_cancel: bool, *args: JSONType, **kwargs: QueryOptionsKwargs) -> Future[BlockingQueryResult] + execute_query(statement: str, options: QueryOptions, *args: JSONType, enable_cancel: bool, **kwargs: QueryOptionsKwargs) -> Future[BlockingQueryResult] + execute_query(statement: str, options: QueryOptions, enable_cancel: bool, *args: JSONType, **kwargs: str) -> Future[BlockingQueryResult] + execute_query(statement: str, options: QueryOptions, *args: JSONType, enable_cancel: bool, **kwargs: str) -> Future[BlockingQueryResult] + execute_query(statement: str, enable_cancel: bool, *args: JSONType, **kwargs: str) -> Future[BlockingQueryResult] + execute_query(statement: str, *args: JSONType, enable_cancel: bool, **kwargs: str) -> Future[BlockingQueryResult] + :no-index: + + Executes a query against an Analytics scope. + + .. important:: + The cancel API is **VOLATILE** and is subject to change at any time. + + :param statement: The SQL++ statement to execute. + :type statement: str + :param options: Options to set for the query. + :type options: Optional[:class:`~couchbase_analytics.options.QueryOptions`] + :param enable_cancel: Enable cancellation of the result or results stream. + :type enable_cancel: Optional[bool] + :param \*args: Can be used to pass in positional query placeholders. + :type \*args: Optional[:py:type:`~couchbase_analytics.JSONType`] + :param \*\*kwargs: Keyword arguments that can be used in place or to overrride provided :class:`~couchbase_analytics.options.ClusterOptions`. + Can also be used to pass in named query placeholders. + :type \*\*kwargs: Optional[Union[:class:`~couchbase_analytics.options.QueryOptionsKwargs`, str]] + + :returns: An instance of :class:`~couchbase_analytics.result.BlockingQueryResult`. When a cancel token is provided + a :class:`~concurrent.futures.Future` is returned. Once the :class:`~concurrent.futures.Future` completes, an instance of a :class:`~couchbase_analytics.result.BlockingQueryResult` will be available. + :rtype: Union[Future[:class:`~couchbase_analytics.result.BlockingQueryResult`], :class:`~couchbase_analytics.result.BlockingQueryResult`] diff --git a/docs/couchbase_analytics_api/query.rst b/docs/couchbase_analytics_api/query.rst new file mode 100644 index 0000000..0de2056 --- /dev/null +++ b/docs/couchbase_analytics_api/query.rst @@ -0,0 +1,73 @@ +============== +Query (SQL++) +============== + +.. contents:: + :local: + :depth: 2 + + +Enumerations +=============== + +.. module:: couchbase_analytics.query +.. autoenum:: QueryScanConsistency + + +Options +=============== + +.. module:: couchbase_analytics.options + :no-index: + +.. autoclass:: QueryOptions + :no-index: + + +Results +=============== + +BlockingQueryResult ++++++++++++++++++++ +.. module:: couchbase_analytics.result + :no-index: + +.. py:class:: BlockingQueryResult + :no-index: + + .. automethod:: cancel + :no-index: + .. automethod:: rows + :no-index: + .. automethod:: get_all_rows + :no-index: + .. automethod:: metadata + :no-index: + +.. module:: couchbase_analytics.query + :no-index: + +QueryMetadata ++++++++++++++++++++ +.. py:class:: QueryMetadata + + .. automethod:: request_id + .. automethod:: warnings + .. automethod:: metrics + +QueryMetrics ++++++++++++++++++++ +.. py:class:: QueryMetrics + + .. automethod:: elapsed_time + .. automethod:: execution_time + .. automethod:: result_count + .. automethod:: result_size + .. automethod:: processed_objects + +QueryWarning ++++++++++++++++++++ +.. py:class:: QueryWarning + + .. automethod:: code + .. automethod:: message diff --git a/docs/couchbase_analytics_api/results.rst b/docs/couchbase_analytics_api/results.rst new file mode 100644 index 0000000..b2d723c --- /dev/null +++ b/docs/couchbase_analytics_api/results.rst @@ -0,0 +1,16 @@ +============== +Results +============== + +.. module:: couchbase_analytics.result + + +BlockingQueryResult +===================== + +.. py:class:: BlockingQueryResult + + .. automethod:: cancel + .. automethod:: rows + .. automethod:: get_all_rows + .. automethod:: metadata diff --git a/docs/couchbase_analytics_api/types.rst b/docs/couchbase_analytics_api/types.rst new file mode 100644 index 0000000..e97af64 --- /dev/null +++ b/docs/couchbase_analytics_api/types.rst @@ -0,0 +1,16 @@ +============== +Types +============== + +.. contents:: + :local: + +TypeAliases ++++++++++++++++++++ + +.. module:: couchbase_analytics + :no-index: + +.. py:type:: JSONType + + :canonical: Union[str, int, float, bool, None, Dict[str, Any], List[Any]] diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..6ad80f5 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,58 @@ +.. Couchbase Python Client Library documentation master file, created by + sphinx-quickstart on Thu Apr 14 13:34:44 2022. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +============================================================= +Welcome to the Couchbase Python Analytics SDK documentation! +============================================================= + +Getting Started with the Python Analytics SDK +--------------------------------------------- + +:doc:`using_the_analytics_sdk` + Useful information for getting started and using the Python Analytics SDK. + +Synchronous API +--------------- + +:doc:`couchbase_analytics_api/couchbase_analytics` + API reference for the couchbase_analytics API. + + +Asynchronous API +----------------- + +:doc:`acouchbase_analytics_api/acouchbase_analytics` + API reference for the acouchbase_analytics API (asyncio). + + +Indices and tables +------------------ + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + +.. Hidden TOCs + +.. toctree:: + :caption: Using the Couchbase Analytics Python SDK + :maxdepth: 2 + :hidden: + + using_the_analytics_sdk + +.. toctree:: + :caption: Synchronous API + :maxdepth: 3 + :hidden: + + couchbase_analytics_api/couchbase_analytics + +.. toctree:: + :caption: Asynchronous API + :maxdepth: 3 + :hidden: + + acouchbase_analytics_api/acouchbase_analytics diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..954237b --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/using_the_analytics_sdk.rst b/docs/using_the_analytics_sdk.rst new file mode 100644 index 0000000..0eb66bb --- /dev/null +++ b/docs/using_the_analytics_sdk.rst @@ -0,0 +1,107 @@ +=============================== +Using the Python Analytics SDK +=============================== + +The Analytics Python SDK library allows you to connect to a Enterprise Analytics cluster from Python. + +Useful Links +======================= + +* :analytics_sdk_github:`Source <>` +* :analytics_sdk_jira:`Bug Tracker <>` +* :analytics_sdk_docs:`Python docs on the Couchbase website <>` +* :analytics_sdk_release_notes:`Release Notes <>` +* :analytics_sdk_compatibility:`Compatibility Guide <>` +* :couchbase_dev_portal:`Couchbase Developer Portal <>` + +How to Engage +======================= + +* :couchbase_discord:`Join Discord and contribute <>`. + The Couchbase Discord server is a place where you can collaborate about all things Couchbase. + Connect with others from the community, learn tips and tricks, and ask questions. +* Ask and/or answer questions on the :analytics_sdk_forums:`Python SDK Forums <>`. + + +Installing the SDK +======================= + +.. note:: + Best practice is to use a Python virtual environment such as venv or pyenv. + Checkout: + + * Linux/MacOS: `pyenv `_ + * Windows: `pyenv-win `_ + + +.. note:: + The Analytics Python SDK provides wheels for Windows, MacOS and Linux platforms for supported versions of Python. + See :analytics_sdk_version_compat:`Analytics Python Version Compatibility <>` docs for details. + +Prereqs +++++++++++ + +See :analytics_sdk_version_compat:`Analytics Python Version Compatibility <>` for details on supported Python versions. + +We also recommend the following command to install/update ``pip``, ``setuptools`` and ``wheel``. + +.. code-block:: console + + $ python3 -m pip install --upgrade pip setuptools wheel + +Install +++++++++++ + +.. code-block:: console + + $ python3 -m pip install couchbase-analytics + +Introduction +======================= + +Connecting to an Analytics cluster is as simple as creating a new ``Cluster`` instance to represent the ``Cluster`` +you are using. You are able to execute most operations immediately, and they will be queued until the connection is successfully established. + +Here is a simple example of creating a ``Cluster`` instance and issuing a query. + +.. code-block:: python + + from couchbase_analytics.cluster import Cluster + from couchbase_analytics.credential import Credential + from couchbase_analytics.options import (ClusterOptions, + QueryOptions, + SecurityOptions) + + + # Update this to your cluster + # IMPORTANT: The appropriate port needs to be specified. The SDK's default ports are 80 (http) and 443 (https). + # If attempting to connect to Capella, the correct ports are most likely to be 8095 (http) and 18095 (https). + # Capella example: https://cb.2xg3vwszqgqcrsix.cloud.couchbase.com:18095 + endpoint = 'https://--your-instance--' + username = 'username' + pw = 'Password!123' + # User Input ends here. + + cred = Credential.from_username_and_password(username, pw) + cluster = Cluster.create_instance(endpoint, cred) + + # Execute a query and process rows as they arrive from server. + statement = 'SELECT * FROM `travel-sample`.inventory.airline WHERE country="United States" LIMIT 10;' + res = cluster.execute_query(statement) + for row in res.rows(): + print(f'Found row: {row}') + print(f'metadata={res.metadata()}') + +Source Control +======================= + +The source control is available on :analytics_sdk_github:`Github <>`. +Once you have cloned the repository, you may contribute changes through Github. +For more details see :analytics_sdk_contribute:`CONTRIBUTING.md <>`. + +License +======================= + +The Analytics Python SDK is licensed under the Apache License 2.0. + +See :analytics_sdk_license:`LICENSE <>` for further details. diff --git a/examples/sync/basic_cluster_query.py b/examples/sync/basic_cluster_query.py index 9147e81..604bf91 100644 --- a/examples/sync/basic_cluster_query.py +++ b/examples/sync/basic_cluster_query.py @@ -22,7 +22,7 @@ def main() -> None: # Update this to your cluster - endpoint = 'couchbases://--your-instance--' + endpoint = 'https://--your-instance--' username = 'username' pw = 'Password!123' # User Input ends here. diff --git a/examples/sync/basic_scope_query.py b/examples/sync/basic_scope_query.py index 8b74cac..b7ef1f3 100644 --- a/examples/sync/basic_scope_query.py +++ b/examples/sync/basic_scope_query.py @@ -22,7 +22,7 @@ def main() -> None: # Update this to your cluster - endpoint = 'couchbases://--your-instance--' + endpoint = 'https://--your-instance--' username = 'username' pw = 'Password!123' # User Input ends here. diff --git a/pyproject.toml b/pyproject.toml index 471cd09..3e6ff08 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -117,6 +117,7 @@ markers = [ line-length = 120 extend-exclude = [ "tests/test_config.ini", + "docs", ] [tool.ruff.lint] diff --git a/uv.lock b/uv.lock index 1ca1a7f..d9612a3 100644 --- a/uv.lock +++ b/uv.lock @@ -351,18 +351,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] -[[package]] -name = "couchbase-analytics" -version = "1.0.0.dev1" -source = { editable = "." } -dependencies = [ - { name = "anyio" }, - { name = "httpx" }, - { name = "ijson" }, - { name = "sniffio" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] - [package.dev-dependencies] dev = [ { name = "aiohttp" },