Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ lint:

test:
coverage erase
coverage run `which django-admin` test
coverage run `which django-admin` test -v 1
coverage report
coverage xml
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Django REST Search
:target: https://pypi.python.org/pypi/djangorestsearch

Django REST Search provides a set of classes to facilitate the integration of
ElasticSearch into applications powered by the Django REST Framework.
OpenSearch into applications powered by the Django REST Framework.

Full documentation for the project is available at
http://django-rest-search.readthedocs.io/.
8 changes: 4 additions & 4 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Django REST Search
==================

Django REST Search provides a set of classes to facilitate the integration of
ElasticSearch [1]_ into applications powered by the Django REST Framework [2]_.
OpenSearch [1]_ into applications powered by the Django REST Framework [2]_.

Installation
------------
Expand All @@ -22,7 +22,7 @@ Add `'rest_search'` to your `INSTALLED_APPS` setting.
'rest_search',
]

Add the middleware to flush ElasticSearch updates to a celery task.
Add the middleware to flush OpenSearch updates to a celery task.

.. code-block:: python

Expand All @@ -31,7 +31,7 @@ Add the middleware to flush ElasticSearch updates to a celery task.
'rest_search.middleware.FlushUpdatesMiddleware',
]

Configure your ElasticSearch connection.
Configure your OpenSearch connection.

.. code-block:: python

Expand Down Expand Up @@ -68,6 +68,6 @@ Contents
indexers
tasks

.. [1] https://www.elastic.co/products/elasticsearch
.. [1] https://opensearch.org/

.. [2] http://www.django-rest-framework.org/
8 changes: 4 additions & 4 deletions docs/indexers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ Indexers
========

Indexers provide the binding between the data in the ORM and the data which
is indexed in ElasticSearch.
is indexed in OpenSearch.

To perform data serialization, indexers build upon the REST framework's
serializers, which allow great flexibility in how you map the data in the ORM
and the JSON representation which is sent to ElasticSearch.
and the JSON representation which is sent to OpenSearch.

Declaring indexers
------------------
Expand Down Expand Up @@ -45,13 +45,13 @@ Options

When declaring an indexer, you can specify some additional properties:

- `index`: the name of the ElasticSearch index, defaults to the model name in lowercase
- `index`: the name of the OpenSearch index, defaults to the model name in lowercase

Index updates
-------------

When you register an indexer, it will install signal handlers for save and
delete events and queue updates to the ElasticSearch index.
delete events and queue updates to the OpenSearch index.

For these updates to actually be performed, either install the
```rest_search.middleware.FlushUpdatesMiddleware``` middleware or wrap your
Expand Down
6 changes: 3 additions & 3 deletions docs/tasks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ Celery Tasks
============

Django REST Search relies on the Celery [1]_ distributed task queue to
perform updates to the ElasticSearch index.
perform updates to the OpenSearch index.

There are two tasks:

- ```rest_search.tasks.update_index``` performs a full update of the
ElasticSearch index by iterating over all the items for which an
OpenSearch index by iterating over all the items for which an
indexer has been defined. You will need to perform this at least once
when you start using Django REST Search or whenever you add an indexer.

- ```rest_search.tasks.patch_index``` performs a partial update of the
ElasticSearch index for specific items. You usually do not need to invoke
OpenSearch index for specific items. You usually do not need to invoke
this yourself, as the indexer sets the required signal handlers when it is
registered.

Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "djangorestsearch"
description = "ElasticSearch integration for Django"
description = "OpenSearch integration for Django"
readme = "README.rst"
requires-python = ">=3.9"
license = "BSD-2-Clause"
Expand All @@ -25,7 +25,7 @@ classifiers = [
]
dependencies = [
"aws-requests-auth>=0.3.0",
"elasticsearch>=7.0.0,<8.0.0",
"opensearch-py>=2.0.0,<3.0.0",
]
dynamic = ["version"]

Expand Down
6 changes: 3 additions & 3 deletions src/rest_search/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from aws_requests_auth.aws_auth import AWSRequestsAuth
from django.conf import settings
from elasticsearch import Elasticsearch, RequestsHttpConnection
from opensearchpy import OpenSearch, RequestsHttpConnection

__version__ = "0.12.0"

Expand Down Expand Up @@ -57,10 +57,10 @@ def __create_connection(self, config):
aws_service="es",
)

return Elasticsearch(**kwargs)
return OpenSearch(**kwargs)


def get_elasticsearch(indexer):
def get_opensearch(indexer):
return connections["default"]


Expand Down
2 changes: 1 addition & 1 deletion src/rest_search/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

def flush_updates(function):
"""
Decorator that flushes ElasticSearch updates.
Decorator that flushes OpenSearch updates.
"""

@functools.wraps(function)
Expand Down
6 changes: 3 additions & 3 deletions src/rest_search/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

class SearchMixin(object):
"""
Mixin to help build ElasticSearch queries.
Mixin to help build OpenSearch queries.
"""

def get_query(self):
"""
Returns the query to be executed by ElasticSearch.
Returns the query to be executed by OpenSearch.
"""
return self._score_query(self._build_query())

Expand Down Expand Up @@ -45,7 +45,7 @@ def _score_query(self, query):

class SearchForm(SearchMixin, forms.Form):
"""
Base form for building ElasticSearch queries.
Base form for building OpenSearch queries.
"""

def __init__(self, data, context={}):
Expand Down
12 changes: 6 additions & 6 deletions src/rest_search/indexers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

from django.db import models
from django.db.models.signals import post_delete, post_save
from elasticsearch.helpers import scan
from opensearchpy.helpers import scan

from rest_search import get_elasticsearch
from rest_search import get_opensearch

_REGISTERED_CLASSES = []

Expand All @@ -27,7 +27,7 @@ def __init__(self):
# Make a note of the field name.
self.pk_name = primary_key.name

# Determine how an `_id` from ElasticSearch is parsed to
# Determine how an `_id` from OpenSearch is parsed to
# a primary key value.
if isinstance(primary_key, models.UUIDField):
self.pk_from_string = uuid.UUID
Expand All @@ -50,11 +50,11 @@ def map_result_item(x):
return map(map_result_item, results)

def scan(self, **kwargs):
es = get_elasticsearch(self)
es = get_opensearch(self)
return scan(es, index=self.index, **kwargs)

def search(self, **kwargs):
es = get_elasticsearch(self)
es = get_opensearch(self)
return es.search(index=self.index, **kwargs)


Expand All @@ -67,7 +67,7 @@ def _get_registered():

def _instance_changed(sender, instance, **kwargs):
"""
Queues an update to the ElasticSearch index.
Queues an update to the OpenSearch index.
"""
from rest_search import queue_add

Expand Down
2 changes: 1 addition & 1 deletion src/rest_search/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

class FlushUpdatesMiddleware(MiddlewareMixin):
"""
Middleware that flushes ElasticSearch updates.
Middleware that flushes OpenSearch updates.
"""

def process_response(self, request, response):
Expand Down
20 changes: 10 additions & 10 deletions src/rest_search/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,35 @@

from celery import shared_task
from django.conf import settings
from elasticsearch.helpers import bulk
from opensearchpy.helpers import bulk

from rest_search import DEFAULT_INDEX_SETTINGS, get_elasticsearch
from rest_search import DEFAULT_INDEX_SETTINGS, get_opensearch
from rest_search.indexers import _get_registered

logger = logging.getLogger("rest_search")


def create_index():
"""
Creates the ElasticSearch indices if they do not exist.
Creates the OpenSearch indices if they do not exist.
"""
for indexer in _get_registered():
_create_index(indexer)


def delete_index():
"""
Deletes the ElasticSearch indices.
Deletes the OpenSearch indices.
"""
for indexer in _get_registered():
es = get_elasticsearch(indexer)
es = get_opensearch(indexer)
es.indices.delete(index=indexer.index, ignore=404)


@shared_task
def patch_index(updates):
"""
Performs a partial update of the ElasticSearch indices.
Performs a partial update of the OpenSearch indices.

Primary keys are received as strings.
"""
Expand All @@ -51,7 +51,7 @@ def patch_index(updates):
@shared_task
def update_index(remove=True):
"""
Performs a full update of the ElasticSearch indices.
Performs a full update of the OpenSearch indices.
"""
logger.info("Updating indices")

Expand All @@ -71,14 +71,14 @@ def _create_index(indexer):
if indexer.mappings is not None:
body["mappings"] = indexer.mappings

es = get_elasticsearch(indexer)
es = get_opensearch(indexer)
if not es.indices.exists(indexer.index):
logger.info("Creating index %s" % indexer.index)
es.indices.create(index=indexer.index, body=body)


def _delete_items(indexer, pks):
es = get_elasticsearch(indexer)
es = get_opensearch(indexer)

def mapper(pk):
return {
Expand All @@ -94,7 +94,7 @@ def _index_items(indexer, pks):
"""
Primary keys are manipulated in their native type (int, UUID).
"""
es = get_elasticsearch(indexer)
es = get_opensearch(indexer)
seen_pks = set()

def bulk_mapper(block_size=1000):
Expand Down
4 changes: 2 additions & 2 deletions src/rest_search/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def get(self, request, *args, **kwargs):
if sort:
body["sort"] = sort

# execute elasticsearch query
# execute opensearch query
indexer = self.get_indexer()
res = indexer.search(body=body)

Expand All @@ -53,7 +53,7 @@ def get_indexer(self):

def get_query(self):
"""
Returns the 'query' element of the ElasticSearch request body.
Returns the 'query' element of the OpenSearch request body.
"""
form = self.form_class(self.request.GET, context={"request": self.request})
if not form.is_valid():
Expand Down
20 changes: 10 additions & 10 deletions tests/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,25 @@ def tearDown(self):
}
}
)
@patch("rest_search.Elasticsearch")
def test_aws_auth(self, mock_elasticsearch):
@patch("rest_search.OpenSearch")
def test_aws_auth(self, mock_opensearch):
es = connections["default"]
self.assertIsNotNone(es)

self.assertEqual(mock_elasticsearch.call_count, 1)
self.assertEqual(mock_elasticsearch.call_args[0], ())
self.assertEqual(mock_opensearch.call_count, 1)
self.assertEqual(mock_opensearch.call_args[0], ())
self.assertEqual(
sorted(mock_elasticsearch.call_args[1].keys()),
sorted(mock_opensearch.call_args[1].keys()),
["connection_class", "host", "http_auth", "port", "use_ssl"],
)

@patch("rest_search.Elasticsearch")
def test_no_auth(self, mock_elasticsearch):
@patch("rest_search.OpenSearch")
def test_no_auth(self, mock_opensearch):
es = connections["default"]
self.assertIsNotNone(es)

self.assertEqual(mock_elasticsearch.call_count, 1)
self.assertEqual(mock_elasticsearch.call_args[0], ())
self.assertEqual(mock_opensearch.call_count, 1)
self.assertEqual(mock_opensearch.call_args[0], ())
self.assertEqual(
sorted(mock_elasticsearch.call_args[1].keys()), ["host", "port", "use_ssl"]
sorted(mock_opensearch.call_args[1].keys()), ["host", "port", "use_ssl"]
)
2 changes: 1 addition & 1 deletion tests/test_indexers.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def test_scan(self, mock_scan):
indexer = BookIndexer()
indexer.scan(body={"query": {"match_all": {}}})

@patch("elasticsearch.client.Elasticsearch.search")
@patch("opensearchpy.client.OpenSearch.search")
def test_search(self, mock_search):
mock_search.return_value = {
"_shards": {"failed": 0, "successful": 5, "total": 5},
Expand Down
10 changes: 5 additions & 5 deletions tests/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ def create_books(self):
book = Book.objects.create(id=1, title="Some book")
book.tags.set([Tag.objects.create(slug=slug) for slug in ["foo", "bar"]])

@patch("elasticsearch.client.indices.IndicesClient.exists")
@patch("elasticsearch.client.indices.IndicesClient.create")
@patch("opensearchpy.client.indices.IndicesClient.exists")
@patch("opensearchpy.client.indices.IndicesClient.create")
def test_create_index(self, mock_create, mock_exists):
mock_exists.return_value = False

Expand Down Expand Up @@ -83,8 +83,8 @@ def test_create_index(self, mock_create, mock_exists):
],
)

@patch("elasticsearch.client.indices.IndicesClient.exists")
@patch("elasticsearch.client.indices.IndicesClient.create")
@patch("opensearchpy.client.indices.IndicesClient.exists")
@patch("opensearchpy.client.indices.IndicesClient.create")
def test_create_index_exists(self, mock_create, mock_exists):
mock_exists.return_value = True

Expand All @@ -99,7 +99,7 @@ def test_create_index_exists(self, mock_create, mock_exists):
)
mock_create.assert_not_called()

@patch("elasticsearch.client.indices.IndicesClient.delete")
@patch("opensearchpy.client.indices.IndicesClient.delete")
def test_delete_index(self, mock_delete):
delete_index()

Expand Down
Loading