Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

async support #1714

Merged
merged 27 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
05ebfa5
async support (work in progress)
miguelgrinberg Mar 8, 2024
74eccd7
minor refactoring, fixed linter and docs
miguelgrinberg Mar 11, 2024
8fcf16c
validate _sync directory during lint phase
miguelgrinberg Mar 11, 2024
78a4f72
search unit tests
miguelgrinberg Mar 13, 2024
5f9eb27
async support for Document class
miguelgrinberg Mar 13, 2024
db05fc2
search integration tests
miguelgrinberg Mar 13, 2024
85a1f41
document tests
miguelgrinberg Mar 14, 2024
a0fb061
async support for Index class
miguelgrinberg Mar 14, 2024
a3fa07d
document integration tests
miguelgrinberg Mar 14, 2024
326f965
remove unused mock dependency
miguelgrinberg Mar 19, 2024
90c8eb5
unasync support for update_by_query
miguelgrinberg Mar 19, 2024
071ddea
remove star imports
miguelgrinberg Mar 19, 2024
eca6306
unasync support for mapping.py
miguelgrinberg Mar 19, 2024
73ffe5a
unasync index integration tests
miguelgrinberg Mar 19, 2024
3690105
unasync faceted search
miguelgrinberg Mar 20, 2024
0184a77
review imports for consistency
miguelgrinberg Mar 20, 2024
8add69f
async support for analyzer
miguelgrinberg Mar 20, 2024
4b7e9fb
async examples
miguelgrinberg Mar 21, 2024
38cd862
examples integration tests
miguelgrinberg Mar 22, 2024
7386dd5
restore sync examples unasynced by mistake
miguelgrinberg Mar 22, 2024
8b5fa41
Documentation updates
miguelgrinberg Mar 22, 2024
2468e8a
Review feedback
miguelgrinberg Mar 27, 2024
d06d804
more review feedback
miguelgrinberg Mar 28, 2024
7bdf7dc
another batch of review updates
miguelgrinberg Mar 29, 2024
9c8e63d
documentation reorg
miguelgrinberg Apr 2, 2024
c172281
more documentation improvements
miguelgrinberg Apr 2, 2024
6b56fb3
unasyncing of examples
miguelgrinberg Apr 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,33 @@ The process for contributing to any of the Elasticsearch repositories is similar
assure our users of the origin and continuing existence of the code. You only
need to sign the CLA once.

2. Run the test suite to ensure your changes do not break existing code:
2. Many classes included in this library are offered in two versions, for
asynchronous and synchronous Python. When working with these classes, you only
need to make changes to the asynchronous code, located in the *_async*
subdirectory of the source tree. Once you've made your changes, run the
miguelgrinberg marked this conversation as resolved.
Show resolved Hide resolved
following command to automatically generate the corresponding synchronous code:

.. code:: bash

$ nox -rs format

3. Run the test suite to ensure your changes do not break existing code:

.. code:: bash

$ nox -rs lint test

3. Rebase your changes.
4. Rebase your changes.
Update your local repository with the most recent code from the main
elasticsearch-dsl-py repository, and rebase your branch on top of the latest master
branch. We prefer your changes to be squashed into a single commit.

4. Submit a pull request. Push your local changes to your forked copy of the
5. Submit a pull request. Push your local changes to your forked copy of the
repository and submit a pull request. In the pull request, describe what your
changes do and mention the number of the issue where discussion has taken
place, eg “Closes #123″. Please consider adding or modifying tests related to
your changes.
your changes. Include any generated files in the *_sync* subdirectory in your
pull request.

Then sit back and wait. There will probably be discussion about the pull
request and, if any changes are needed, we would love to work with you to get
Expand Down
37 changes: 34 additions & 3 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,39 +11,70 @@ Search
------

.. autoclass:: Search
:inherited-members:
:members:

.. autoclass:: MultiSearch
:inherited-members:
:members:

.. autoclass:: AsyncSearch
:inherited-members:
:members:

.. autoclass:: AsyncMultiSearch
:inherited-members:
:members:
miguelgrinberg marked this conversation as resolved.
Show resolved Hide resolved

Document
--------

.. autoclass:: Document
:inherited-members:
:members:

.. autoclass:: AsyncDocument
:inherited-members:
:members:

Index
-----

.. autoclass:: Index
:inherited-members:
:members:

.. autoclass:: AsyncIndex
:inherited-members:
:members:

Faceted Search
--------------

.. autoclass:: FacetedSearch
:inherited-members:
:members:

.. autoclass:: AsyncFacetedSearch
:inherited-members:
:members:

Update By Query
----------------

.. autoclass:: UpdateByQuery
:members:
:inherited-members:
:members:

.. autoclass:: AsyncUpdateByQuery
:inherited-members:
:members:

Mappings
--------

If you wish to create mappings manually you can use the ``Mapping`` class, for
more advanced use cases, however, we recommend you use the :ref:`doc_type`
If you wish to create mappings manually you can use the ``Mapping`` or ``AsyncMapping``
classes, for more advanced use cases, however, we recommend you use the :ref:`doc_type`
abstraction in combination with :ref:`index` (or :ref:`index-template`) to define
index-level settings and properties. The mapping definition follows a similar
pattern to the query dsl:
Expand Down
92 changes: 92 additions & 0 deletions docs/asyncio.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
.. _asyncio:

Using Asyncio with Elasticsearch DSL
====================================

The ``elasticsearch-dsl`` package supports async/await with `Asyncio <https://docs.python.org/3/library/asyncio.html>`__.
miguelgrinberg marked this conversation as resolved.
Show resolved Hide resolved
To ensure that you have all the required dependencies, install the ``[async]`` extra:

.. code:: bash

$ python -m pip install elasticsearch-dsl[async]

Connections
-----------

Use the ``async_connections`` module to manage your asynchronous connections.

.. code:: python

from elasticsearch_dsl import async_connections

async_connections.create_connection(hosts=['localhost'], timeout=20)

All the options available in the ``connections`` module can be used with ``async_connections``.

How to avoid 'Unclosed client session / connector' warnings on exit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

These warnings come from the ``aiohttp`` package, which is used internally by the
``AsyncElasticsearch`` client. They appear often when the application exits and
are caused by HTTP connections that are open when they are garbage collected. To
avoid these warnings, make sure that you close your connections.

.. code:: python

es = async_connections.get_connection()
await es.close()

Search DSL
----------

Use the ``AsyncSearch`` class to perform asynchronous searches.

.. code:: python

from elasticsearch_dsl import AsyncSearch

s = AsyncSearch().query("match", title="python")
async for hit in s:
print(hit.title)

Instead of using the ``AsyncSearch`` object as an asynchronous iterator, you can
explicitly call the ``execute()`` method to get a ``Response`` object.

.. code:: python

s = AsyncSearch().query("match", title="python")
response = await s.execute()
for hit in response:
print(hit.title)

An ``AsyncMultiSearch`` is available as well.

.. code:: python

from elasticsearch_dsl import AsyncMultiSearch

ms = AsyncMultiSearch(index='blogs')

ms = ms.add(AsyncSearch().filter('term', tags='python'))
ms = ms.add(AsyncSearch().filter('term', tags='elasticsearch'))

responses = await ms.execute()

for response in responses:
print("Results for query %r." % response.search.query)
for hit in response:
print(hit.title)

Asynchronous Documents, Indexes, and more
-----------------------------------------
miguelgrinberg marked this conversation as resolved.
Show resolved Hide resolved

The ``Document``, ``Index``, ``IndexTemplate``, ``Mapping``, ``UpdateByQuery`` and
``FacetedSearch`` classes all have asynchronous versions that use the same name
with an ``Async`` prefix. These classes expose the same interfaces as the
synchronous versions, but any methods that perform I/O are defined as coroutines.

Auxiliary classes that do not perform I/O do not have asynchronous versions. The
same classes can be used in synchronous and asynchronous applications.

You can consult the :ref:`api` section for details about each specific
method.
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ Contents
persistence
faceted_search
update_by_query
asyncio
api
CONTRIBUTING
Changelog
20 changes: 15 additions & 5 deletions elasticsearch_dsl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@
from . import connections
from .aggs import A
from .analysis import analyzer, char_filter, normalizer, token_filter, tokenizer
from .document import Document, InnerDoc, MetaField
from .document import AsyncDocument, Document
from .document_base import InnerDoc, MetaField
from .exceptions import (
ElasticsearchDslException,
IllegalOperation,
UnknownDslObject,
ValidationException,
)
from .faceted_search import (
AsyncFacetedSearch,
DateHistogramFacet,
Facet,
FacetedResponse,
Expand Down Expand Up @@ -76,11 +78,11 @@
construct_field,
)
from .function import SF
from .index import Index, IndexTemplate
from .mapping import Mapping
from .index import AsyncIndex, AsyncIndexTemplate, Index, IndexTemplate
from .mapping import AsyncMapping, Mapping
from .query import Q
from .search import MultiSearch, Search
from .update_by_query import UpdateByQuery
from .search import AsyncMultiSearch, AsyncSearch, MultiSearch, Search
from .update_by_query import AsyncUpdateByQuery, UpdateByQuery
from .utils import AttrDict, AttrList, DslBase
from .wrappers import Range

Expand All @@ -89,6 +91,14 @@
__versionstr__ = ".".join(map(str, VERSION))
__all__ = [
"A",
"AsyncDocument",
"AsyncFacetedSearch",
"AsyncIndex",
"AsyncIndexTemplate",
"AsyncMapping",
"AsyncMultiSearch",
"AsyncSearch",
"AsyncUpdateByQuery",
"AttrDict",
"AttrList",
"Binary",
Expand Down
16 changes: 16 additions & 0 deletions elasticsearch_dsl/_async/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Licensed to Elasticsearch B.V. under one or more contributor
# license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright
# ownership. Elasticsearch B.V. licenses this file to you under
# the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
Loading
Loading