{ "info": { "author": "Christopher Rabotin", "author_email": "christopher.rabotin@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python :: 2" ], "description": "Bungiesearch\n============\n\n|Build Status| |Coverage Status|\n\n.. contents:: Table of contents\n :depth: 2\n\nPurpose\n=======\n\nBungiesearch is a Django wrapper for\n`elasticsearch-dsl-py `__.\nIt inherits from elasticsearch-dsl-py's ``Search`` class, so all the\nfabulous features developed by the elasticsearch-dsl-py team are also\navailable in Bungiesearch. In addition, just like ``Search``,\nBungiesearch is a lazy searching class (and iterable), meaning you can\ncall functions in a row, or do something like the following.\n\n.. code:: python\n\n lazy = Article.objects.search.query('match', _all='Description')\n print len(lazy) # Prints the number of hits by only fetching the number of items.\n for item in lazy[5:10]:\n print item\n\nFeatures\n========\n\n- Core Python friendly\n\n - Iteration (``[x for x in lazy_search]``)\n - Get items (``lazy_search[10]``)\n - Number of hits via ``len`` (``len(lazy_search)``)\n\n- Index management\n\n - Creating and deleting an index.\n - Creating, updating and deleting doctypes and their mappings.\n - Update index doctypes.\n\n- Django Model Mapping\n\n - Very easy mapping (no lies).\n - Automatic model mapping (and supports undefined models by\n returning a ``Result`` instance of ``elasticsearch-dsl-py``).\n - Efficient database fetching:\n\n - One fetch for all items of a given model.\n - Fetches only desired fields.\n\n- Django Manager\n\n - Easy model integration:\n ``MyModel.search.query(\"match\", _all=\"something to search\")``.\n - Search aliases (search shortcuts with as many parameters as\n wanted): ``Tweet.object.bungie_title_search(\"bungie\")`` or\n ``Article.object.bungie_title_search(\"bungie\")``, where\n ``bungie_title_search`` is uniquely defined.\n\n- Django signals\n\n - Connect to post save and pre delete signals for the elasticsearch\n index to correctly reflect the database (almost) at all times.\n\n- Requirements\n\n - Django >= 1.7\n - Python 2.7 (**no Python 3 support yet**)\n\nFeature examples\n----------------\n\nSee section \"Full example\" at the bottom of page to see the code needed\nto perform these following examples. ### Query a word (or list thereof)\non a managed model.\n\n``Article.objects.search.query('match', _all='Description')``\n\nUse a search alias on a model's manager.\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n``Article.objects.bsearch_title_search('title')``\n\nUse a search alias on a bungiesearch instance.\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n``Article.objects.search.bsearch_title_search('title').bsearch_titlefilter('filter this title')``\n\nIterate over search results\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code:: python\n\n # Will print the Django model instance.\n for result in Article.objects.search.query('match', _all='Description'):\n print result\n\nFetch a single item\n~~~~~~~~~~~~~~~~~~~\n\n.. code:: python\n\n Article.objects.search.query('match', _all='Description')[0]\n\nGet the number of returned items\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code:: python\n\n print len(Article.objects.search.query('match', _all='Description'))\n\nDeferred model instantiation\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code:: python\n\n # Will print the Django model instance's primary key. Will only fetch the `pk` field from the database.\n for result in Article.objects.search.query('match', _all='Description').only('pk'):\n print result.pk\n\nElasticsearch limited field fetching\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code:: python\n\n # Will print the Django model instance. However, elasticsearch's response only has the `_id` field.\n for result in Article.objects.search.query('match', _all='Description').fields('_id'):\n print result\n\nGet a specific number of items with an offset.\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThis is actually elasticseach-dsl-py functionality, but it's\ndemonstrated here because we can iterate over the results via\nBungiesearch.\n\n.. code:: python\n\n for item in Article.objects.bsearch_title_search('title').only('pk').fields('_id')[5:7]:\n print item\n\nLazy objects\n~~~~~~~~~~~~\n\n.. code:: python\n\n lazy = Article.objects.bsearch_title_search('title')\n print len(lazy)\n for item in lazy.filter('range', effective_date={'lte': '2014-09-22'}):\n print item\n\nInstallation\n============\n\nUnless noted otherwise, each step is required.\n\nInstall the package\n-------------------\n\nThe easiest way is to install the package from PyPi:\n\n``pip install bungiesearch``\n\n**Note:** Check your version of Django after installing bungiesearch. It\nwas reported to me directly that installing bungiesearch may upgrade\nyour version of Django, although I haven't been able to confirm that\nmyself. Bungiesearch depends on Django 1.7 and above.\n\nIn Django\n---------\n\nUpdating your Django models\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n**Note:** this part is only needed if you want to be able to use search\naliases, which allow you to define shortcuts to complex queries,\navailable directly from your Django models. I think it's extremely\npractical.\n\n1. Open your ``models.py`` file.\n2. Add the bungiesearch manager import:\n ``from bungiesearch.managers import BungiesearchManager``\n3. Find the model, or models, you wish to index on Elasticsearch and set\n them to be managed by Bungiesearch by adding the objects field to\n them, as such: ``objects = BungiesearchManager()``. You should now\n have a Django model `similar to\n this `__.\n\nCreating bungiesearch search indexes\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe search indexes define how bungiesearch should serialize each of the\nmodel's objects. It effectively defines how your object is serialized\nand how the ES index should be structured. These are referred to as\n`ModelIndex `__\\ es.\n\nA good practice here is to have all the bungiesearch stuff in its own\npackage. For example, for the section of the Sparrho platform that uses\nDjango, we have a package called ``search`` where we define the search\nindexes, and a subpackage called ``aliases`` which has the many aliases\nwe use (more on that latter).\n\n1. Create a subclass of ``ModelIndex``, which you can import from from\n ``bungiesearch.indices import ModelIndex``, in a new module\n preferably.\n2. In this class, define a class called ``Meta``: it will hold meta\n information of this search index for bungiesearch's internal working.\n3. Import the Django model you want to index (from your models file)\n and, in the Meta class, define a field called ``model``, which must\n be set to the model you want indexed.\n4. By default, bungiesearch will index every field of your model. This\n may not always be desired, so you can define which fields must be\n excluded in this ``Meta`` class, via the exclude field.\n5. There are plenty of options, so definitely have a read through the\n documentation for\n `ModelIndex `__.\n\nHere's `an\nexample `__ of a\nsearch index. There can be many such definitions in a file.\n\nDjango settings\n~~~~~~~~~~~~~~~\n\nThis is the final required step. Here's the `full\ndocumentation `__ of\nthis step.\n\n1. Open your settings file and add a ``BUNGIESEARCH`` variable, which\n must be a dictionary.\n2. Define ``URLS`` as a list of URLs (which can contain only one) of\n your ES servers.\n3. Define the ``INDICES`` key as a dictionary where the key is the name\n of the index on ES that you want, and the value is the full Python\n path to the module which has all the ModelIndex classes for to be\n indexed on that index name.\n4. Set ``ALIASES`` to an empty dictionary (until you define any search\n aliases).\n5. You can keep other values as their defaults.\n\nIn your shell\n-------------\n\nCreate the ES indexes\n~~~~~~~~~~~~~~~~~~~~~\n\nFrom your shell, in the Django environment, run the following:\n\n``python manage.py search_index --create``\n\nStart populating the index\n--------------------------\n\nRun the following which will take each of the objects in your model,\nserialize them, and add them to the elasticsearch index.\n\n``python manage.py search_index --update``\n\n**Note:** With additional parameters, you can limit the number of\ndocuments to be indexed, as well as set conditions on whether they\nshould be indexed based on updated time for example.\n\nIn Elasticsearch\n----------------\n\nYou can now open your elasticsearch dashboard, such as Elastic HQ, and\nsee that your index is created with the appropriate mapping and has\nitems that are indexed.\n\nQuick start example\n===================\n\nThis example is from the ``test`` folder. It may be partially out-dated,\nso please refer to the ``test`` folder for the latest version.\n\nProcedure\n---------\n\n1. In your models.py file (or your managers.py), import bungiesearch and\n use it as a model manager.\n2. Define one or more ModelIndex subclasses which define the mapping\n between your Django model and elasticsearch.\n3. (Optional) Define SearchAlias subclasses which make it trivial to\n call complex elasticsearch-dsl-py functions.\n4. Add a BUNGIESEARCH variable in your Django settings, which must\n contain the elasticsearch URL(s), the modules for the indices, the\n modules for the search aliases and the signal definitions.\n\nExample\n-------\n\nHere's the code which is applicable to the previous examples. ### Django\nModel\n\n.. code:: python\n\n from django.db import models\n from bungiesearch.managers import BungiesearchManager\n\n class Article(models.Model):\n title = models.TextField(db_index=True)\n authors = models.TextField(blank=True)\n description = models.TextField(blank=True)\n link = models.URLField(max_length=510, unique=True, db_index=True)\n published = models.DateTimeField(null=True)\n created = models.DateTimeField(auto_now_add=True)\n updated = models.DateTimeField(null=True)\n tweet_count = models.IntegerField()\n raw = models.BinaryField(null=True)\n source_hash = models.BigIntegerField(null=True)\n missing_data = models.CharField(blank=True, max_length=255)\n positive_feedback = models.PositiveIntegerField(null=True, blank=True, default=0)\n negative_feedback = models.PositiveIntegerField(null=True, blank=True, default=0)\n popularity_index = models.IntegerField(default=0)\n\n objects = BungiesearchManager()\n\n class Meta:\n app_label = 'core'\n\nModelIndex\n~~~~~~~~~~\n\nThe following ModelIndex will generate a mapping containing all fields\nfrom ``Article``, minus those defined in ``ArticleIndex.Meta.exclude``.\nWhen the mapping is generated, each field will the most appropriate\n`elasticsearch core\ntype `__,\nwith default attributes (as defined in bungiesearch.fields).\n\nThese default attributes can be overwritten with\n``ArticleIndex.Meta.hotfixes``: each dictionary key must be field\ndefined either in the model or in the ModelIndex subclass\n(``ArticleIndex`` in this case).\n\n.. code:: python\n\n from core.models import Article\n from bungiesearch.fields import DateField, StringField\n from bungiesearch.indices import ModelIndex\n\n\n class ArticleIndex(ModelIndex):\n effectived_date = DateField(eval_as='obj.created if obj.created and obj.published > obj.created else obj.published')\n meta_data = StringField(eval_as='\" \".join([fld for fld in [obj.link, str(obj.tweet_count), obj.raw] if fld])')\n\n class Meta:\n model = Article\n exclude = ('raw', 'missing_data', 'negative_feedback', 'positive_feedback', 'popularity_index', 'source_hash')\n hotfixes = {'updated': {'null_value': '2013-07-01'},\n 'title': {'boost': 1.75},\n 'description': {'boost': 1.35},\n 'full_text': {'boost': 1.125}}\n\nSearchAlias\n~~~~~~~~~~~\n\nDefines a search alias for one or more models (in this case only for\n``core.models.Article``).\n\n.. code:: python\n\n from core.models import Article\n from bungiesearch.aliases import SearchAlias\n\n\n class SearchTitle(SearchAlias):\n def alias_for(self, title):\n return self.search_instance.query('match', title=title)\n\n class Meta:\n models = (Article,)\n alias_name = 'title_search' # This is optional. If none is provided, the name will be the class name in lower case.\n\n class InvalidAlias(SearchAlias):\n def alias_for_does_not_exist(self, title):\n return title\n\n class Meta:\n models = (Article,)\n\nDjango settings\n~~~~~~~~~~~~~~~\n\n.. code:: python\n\n BUNGIESEARCH = {\n 'URLS': [os.getenv('ELASTIC_SEARCH_URL')],\n 'INDICES': {'bungiesearch_demo': 'core.search_indices'},\n 'ALIASES': {'bsearch': 'myproject.search_aliases'},\n 'SIGNALS': {'BUFFER_SIZE': 1} # uses BungieSignalProcessor\n }\n\nDocumentation\n=============\n\nModelIndex\n----------\n\nA ``ModelIndex`` defines mapping and object extraction for indexing of a\ngiven Django model.\n\nAny Django model to be managed by bungiesearch must have a defined\nModelIndex subclass. This subclass must contain a subclass called\n``Meta`` which must have a ``model`` attribute (sets the model which it\nrepresents).\n\nClass attributes\n~~~~~~~~~~~~~~~~\n\nAs detailed below, the doc type mapping will contain fields from the\nmodel it related to. However, one may often need to index fields which\ncorrespond to either a concatenation of fields of the model or some\nlogical operation.\n\nBungiesearch makes this very easy: simply define a class attribute as\nwhichever core type, and set to the ``eval_as`` constructor parameter to\na one line Python statement. The object is referenced as ``obj`` (not\n``self`` nor ``object``, just ``obj``).\n\nExample\n^^^^^^^\n\nThis is a partial example as the Meta subclass is not defined, yet\nmandatory (cf. below).\n\n.. code:: python\n\n from bungiesearch.fields import DateField, StringField\n from bungiesearch.indices import ModelIndex\n\n class ArticleIndex(ModelIndex):\n effective_date = DateField(eval_as='obj.created if obj.created and obj.published > obj.created else obj.published')\n meta_data = StringField(eval_as='\" \".join([fld for fld in [obj.link, str(obj.tweet_count), obj.raw] if fld])')\n\nHere, both ``effective_date`` and ``meta_data`` will be part of the doc\ntype mapping, but won't be reversed mapped since those fields do not\nexist in the model.\n\nThis can also be used to index foreign keys:\n\n.. code:: python\n\n some_field_name = StringField(eval_as='\",\".join([item for item in obj.some_foreign_relation.values_list(\"some_field\", flat=True)]) if obj.some_foreign_relation else \"\"')\n\nClass methods\n~~~~~~~~~~~~~\n\nmatches\\_indexing\\_condition\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nOverride this function to specify whether an item should be indexed or\nnot. This is useful when defining multiple indices (and ModelIndex\nclasses) for a given model. This method's signature and super class code\nis as follows, and allows indexing of all items.\n\n.. code:: python\n\n def matches_indexing_condition(self, item):\n return True\n\nFor example, if a given elasticsearch index should contain only item\nwhose title starts with ``\"Awesome\"``, then this method can be\noverridden as follows.\n\n.. code:: python\n\n def matches_indexing_condition(self, item):\n return item.title.startswith(\"Awesome\")\n\nMeta subclass attributes\n~~~~~~~~~~~~~~~~~~~~~~~~\n\n**Note**: in the following, any variable defined a being a ``list``\ncould also be a ``tuple``. ##### model *Required:* defines the Django\nmodel for which this ModelIndex is applicable.\n\nfields\n^^^^^^\n\n*Optional:* list of fields (or columns) which must be fetched when\nserializing the object for elasticsearch, or when reverse mapping the\nobject from elasticsearch back to a Django Model instance. By default,\nall fields will be fetched. Setting this *will* restrict which fields\ncan be fetched and may lead to errors when serializing the object. It is\nrecommended to use the ``exclude`` attribute instead (cf. below).\n\nexclude\n^^^^^^^\n\n*Optional:* list of fields (or columns) which must not be fetched when\nserializing or deserializing the object.\n\nhotfixes\n^^^^^^^^\n\n*Optional:* a dictionary whose keys are index fields and whose values\nare dictionaries which define `core type\nattributes `__.\nBy default, there aren't any special settings, apart for String fields,\nwhere the\n`analyzer `__\nis set to\n```snowball`` `__\n(``{'analyzer': 'snowball'}``).\n\nadditional\\_fields\n^^^^^^^^^^^^^^^^^^\n\n*Optional:* additional fields to fetch for mapping, may it be for\n``eval_as`` fields or when returning the object from the database.\n\nid\\_field\n^^^^^^^^^\n\n*Optional:* the model field to use as a unique ID for elasticsearch's\nmetadata ``_id``. Defaults to ``id`` (also called\n```pk`` `__).\n\nupdated\\_field\n^^^^^^^^^^^^^^\n\n*Optional:* set the model's field which can be filtered on dates in\norder to find when objects have been updated. Note, this is *mandatory*\nto use ``--start`` and/or ``--end`` when updating index (with\n``search_index --update``).\n\noptimize\\_queries\n^^^^^^^^^^^^^^^^^\n\n*Optional:* set to True to make efficient queries when automatically\nmapping to database objects. This will *always* restrict fetching to the\nfields set in ``fields`` and in ``additional_fields``. *Note:* You can\nalso perform an optimal database query with ``.only('__model')``, which\nwill use the same fields as ``optimize_queries``, or\n``.only('__fields')``, which will use the fields provided in the\n``.fields()`` call.\n\nindexing\\_query\n^^^^^^^^^^^^^^^\n\n*Optional:* set to a QuerySet instance to specify the query used when\nthe search\\_index command is ran to index. This **does not** affect how\neach piece of content is indexed.\n\ndefault\n^^^^^^^\n\nEnables support for a given model to be indexed on several elasticsearch\nindices. Set to ``False`` on all but the default index. **Note**: if all\nmanaged models are set with ``default=False`` then Bungiesearch will\nfail to find and index that model.\n\nExample\n~~~~~~~\n\nIndexes all objects of ``Article``, as long as their ``updated``\ndatetime is less than `21 October 2015\n04:29 `__.\n\n.. code:: python\n\n from core.models import Article\n from bungiesearch.indices import ModelIndex\n from datetime import datetime\n\n class ArticleIndex(ModelIndex):\n\n def matches_indexing_condition(self, item):\n return item.updated < datetime.datetime(2015, 10, 21, 4, 29)\n\n class Meta:\n model = Article\n id_field = 'id' # That's actually the default value, so it's not really needed.\n exclude = ('raw', 'missing_data', 'negative_feedback', 'positive_feedback', 'popularity_index', 'source_hash')\n hotfixes = {'updated': {'null_value': '2013-07-01'},\n 'title': {'boost': 1.75},\n 'description': {'boost': 1.35},\n 'full_text': {'boost': 1.125}}\n optimized_queries = True\n indexing_query = Article.objects.defer(*exclude).select_related().all().prefetch_related('tags')\n\nSearchAlias\n-----------\n\nA ``SearchAlias`` define search shortcuts (somewhat similar to `Django\nmanagers `__).\nOften times, a given search will be used in multiple parts of the code.\nSearchAliases allow you define those queries, filters, or any\nbungiesearch/elasticsearch-dsl-py calls as an alias.\n\nA search alias is either applicable to a ``list`` (or ``tuple``) of\nmanaged models, or to any bungiesearch instance. It's very simple, so\nhere's an example which is detailed right below.\n\nExample\n~~~~~~~\n\nThe most simple implementation of a SearchAlias is as follows. This\nsearch alias can be called via ``Article.objects.bungie_title`` (or\n``Article.objects.search.bungie_title``), supposing that the namespace\nis set to ``None`` in the settings (cf. below).\n\nDefinition\n^^^^^^^^^^\n\n.. code:: python\n\n from bungiesearch.aliases import SearchAlias\n\n class Title(SearchAlias):\n def alias_for(self, title):\n return self.search_instance.query('match', title=title)\n\nUsage\n^^^^^\n\n.. code:: python\n\n Article.objects.bungie_title('title')\n\nMethod overwrite\n~~~~~~~~~~~~~~~~\n\nAny implementation needs to inherit from\n``bungiesearch.aliases.SearchAlias`` and overwrite ``alias_for``. You\ncan set as many or as little parameters as you want for that function\n(since bungiesearch only return the pointer to that function without\nactually calling it).\n\nSince each managed model has its own doc type, ``self.search_instance``\nis a bungiesearch instance set to search the specific doctype.\n\nMeta subclass attributes\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nAlthough not mandatory, the ``Meta`` subclass enabled custom naming and\nmodel restrictions for a search alias.\n\nmodels\n^^^^^^\n\n*Optional:* ``list`` (or ``tuple``) of Django models which are allowed\nto use this search alias. If a model which is not allowed to use this\nSearchAlias tries it, a ``ValueError`` will be raised.\n\nalias\\_name\n^^^^^^^^^^^\n\n*Optional:* A string corresponding the suffix name of this search alias.\nDefaults to the lower case class name.\n\n**WARNING**: As explained in the \"Settings\" section below, all search\naliases in a given module share the prefix (or namespace). This is to\nprevent aliases from accidently overwriting Django manager function\n(e.g. ``update`` or ``get``). In other words, if you define the\n``alias_name`` to ``test``, then it must be called as\n``model_obj.objects.$prefix$_test`` where ``$prefix$`` is the prefix\ndefined in the settings. This prefix is also applicable to search\naliases which are available via bungiesearch instances directly. Hence,\none can define in one module search utilities (e.g. ``regex`` and\n``range``) and define model specific aliases (e.g. ``title``) in another\nmodule, and use both in conjunction as such:\n``Article.objects.search.bungie_title('search title').utils_range(field='created', gte='2014-05-20', as_query=True)``.\nThese aliases can be concatenated ad vitam aeternam.\n\nSophisticated example\n~~~~~~~~~~~~~~~~~~~~~\n\nThis example shows that we can have some fun with search aliases. In\nthis case, we define a Range alias which is applicable to any field on\nany model.\n\n.. code:: python\n\n class Range(SearchAlias):\n def alias_for(self, field, gte=None, lte=None, boost=None, as_query=False):\n body = {field: {}}\n if gte:\n body[field]['gte'] = gte\n if lte:\n body[field]['lte'] = lte\n if boost:\n if not as_query:\n logging.warning('Boost is not applicable to search alias Range when not used as a query.')\n else:\n body[field]['boost'] = boost\n if as_query:\n return self.search_instance.query({'range': body})\n return self.search_instance.filter({'range': body})\n\nWe can use it as such\n``Article.objects.bungie_range(field='created', gte='2014-05-20', as_query=True)``.\n\nSettings\n--------\nAdd 'bungiesearch' to INSTALLED_APPS.\n\nYou must define ``BUNGIESEARCH`` in your Django settings in order for\nbungiesearch to know elasticsearch URL(s) and which index name contains\nmappings for each ModelIndex.\n\n.. code:: python\n\n BUNGIESEARCH = {\n 'URLS': ['localhost'], # No leading http:// or the elasticsearch client will complain.\n 'INDICES': {'main_index': 'myproject.myapp.myindices'} # Must be a module path.\n 'ALIASES': {'bsearch': 'myproject.search_aliases'},\n 'SIGNALS': {'BUFFER_SIZE': 1},\n 'TIMEOUT': 5\n }\n\nURLS\n~~~~\n\n*Required:* must be a list of URLs which host elasticsearch instance(s).\nThis is directly sent to elasticsearch-dsl-py, so any issue with\nmultiple URLs should be refered to them.\n\nINDICES\n~~~~~~~\n\n*Required:* must be a dictionary where each key is the name of an\nelasticsearch index and each value is a path to a Python module\ncontaining classes which inherit from\n``bungiesearch.indices.ModelIndex`` (cf. below).\n\nALIASES\n~~~~~~~\n\n*Optional:* a dictionary whose key is the alias namespace and whose\nvalue is the Python module containing classes which inherit from\n``bungiesearch.aliases.SearchAlias``. If the namespace is ``None``, then\nthe alias will be named ``bungie``. If the namespace is an empty string,\nthere will be no alias namespace. The provided namespace will be\nappended by an underscore. In the example above, each search alias\ndefined in ``myproject.search_aliases`` will be referenced as\n``$ModelObj$.objects.bsearch_$alias$``, where ``$ModelObj$`` is a Django\nmodel and ``$alias$`` is the name of the search alias.\n\nThe purpose is to not accidently overwrite Django's default manager\nfunctions with search aliases.\n\nSIGNALS\n~~~~~~~\n\n*Optional:* if it exists, it must be a dictionary (even empty), and will\nconnect to the ``post save`` and ``pre delete`` model functions of *all*\nmodels using ``bungiesearch.managers.BungiesearchManager`` as a manager.\nOne may also define a signal processor class for more custom\nfunctionality by placing the string value of the module path under a key\ncalled ``SIGNAL_CLASS`` in the dictionary value of ``SIGNALS`` and\ndefining ``setup`` and ``teardown`` methods, which take ``model`` as the\nonly parameter. These methods connect and disconnect the signal\nprocessing class to django signals (signals are connected to each model\nwhich uses a BungiesearchManager).\n\nIf ``SIGNALS`` is not defined in the settings, *none* of the models\nmanaged by BungiesearchManager will automatically update the index when\na new item is created or deleted.\n\nBUFFER\\_SIZE\n^^^^^^^^^^^^\n\n*Optional:* an integer representing the number of items to buffer before\nmaking a bulk index update, defaults to ``100``.\n\n**WARNING**: if your application is shut down before the buffer is\nemptied, then any buffered instance *will not* be indexed on\nelasticsearch. Hence, a possibly better implementation is wrapping\n``post_save_connector`` and ``pre_delete_connector`` from\n``bungiesearch.signals`` in a celery task. It is not implemented as such\nhere in order to not require ``celery``.\n\nTIMEOUT\n~~~~~~~\n\n*Optional:* Elasticsearch connection timeout in seconds. Defaults to\n``5``.\n\nTesting\n=======\n\nThe easiest way to run the tests is to install all dev dependencies using\n``./setup.sh`` then run ``./test.sh``\n\nAll Bungiesearch tests are in ``tests/core/test_bungiesearch.py``. You\ncan run the tests by creating a Python virtual environment, installing\nthe requirements from ``requirements.txt``, installing the package\n(``pip install .``) and running ``python tests/manage.py test``. Make\nsure to update ``tests/settings.py`` to use your own elasticsearch URLs,\nor update the ELASTIC\\_SEARCH\\_URL environment variable.\n\n.. |Build Status| image:: https://travis-ci.org/Sparrho/bungiesearch.svg?branch=master\n :target: https://travis-ci.org/Sparrho/bungiesearch\n.. |Coverage Status| image:: https://coveralls.io/repos/Sparrho/bungiesearch/badge.svg?branch=master&service=github\n :target: https://coveralls.io/github/Sparrho/bungiesearch?branch=master", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ChristopherRabotin/bungiesearch", "keywords": "elasticsearch haystack django bungiesearch", "license": "BSD-3", "maintainer": null, "maintainer_email": null, "name": "bungiesearch", "package_url": "https://pypi.org/project/bungiesearch/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/bungiesearch/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/ChristopherRabotin/bungiesearch" }, "release_url": "https://pypi.org/project/bungiesearch/1.3.0/", "requires_dist": null, "requires_python": null, "summary": "A Django elasticsearch wrapper and helper using elasticsearch-dsl-py high level library.", "version": "1.3.0" }, "last_serial": 1846445, "releases": { "1.0.2": [ { "comment_text": "", "digests": { "md5": "3d5dfd50f284764515b19ab65add51c5", "sha256": "798acb79f857bae524ad32995834158380f3ebeb0ae1ab248f5b55ebd7774263" }, "downloads": -1, "filename": "bungiesearch-1.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3d5dfd50f284764515b19ab65add51c5", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 38586, "upload_time": "2015-06-05T16:46:50", "url": "https://files.pythonhosted.org/packages/b4/07/139ad3d51174510790696ea6392a164131642ac17ba95b2656175a11aa1d/bungiesearch-1.0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f3340b5d2f47f06b2ffdf3cecc38f6cd", "sha256": "681f5904b9d78ebb169d0d3d5a1b344602d0a17aecf47a11d10ef9b96b0f7086" }, "downloads": -1, "filename": "bungiesearch-1.0.2.tar.gz", "has_sig": false, "md5_digest": "f3340b5d2f47f06b2ffdf3cecc38f6cd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30146, "upload_time": "2015-06-05T16:46:54", "url": "https://files.pythonhosted.org/packages/f2/3b/6f8c5b822aaba9c0f9e57f57822fcffc527cab8c7458435a91d147c0f026/bungiesearch-1.0.2.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "fd62df76b0988a672db3b35358c79a77", "sha256": "64a413b087d4db8c94626c69628770f5a1c3dcb39303c1aebfce2b2f9696d207" }, "downloads": -1, "filename": "bungiesearch-1.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "fd62df76b0988a672db3b35358c79a77", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 40866, "upload_time": "2015-06-26T11:39:58", "url": "https://files.pythonhosted.org/packages/9d/0b/4152e541ceded5d982e86c530f4af81855c63f03063eb9be06e9b98afae0/bungiesearch-1.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9e957a11fb73b0c3f7ef2ec46e3ccf9b", "sha256": "4367dc614c41112e65bf7a1b3f823b5fa78ec6c79dfbb2b3c3377d83c443a62d" }, "downloads": -1, "filename": "bungiesearch-1.1.0.tar.gz", "has_sig": false, "md5_digest": "9e957a11fb73b0c3f7ef2ec46e3ccf9b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32379, "upload_time": "2015-06-26T11:40:02", "url": "https://files.pythonhosted.org/packages/02/23/03d09ae14cbbab61c6a8fab07a7669098522c31691f3e09599ca1368e8fa/bungiesearch-1.1.0.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "d4211f5ac1c7cbe848433a435a8e3b8d", "sha256": "809ed85c84025d0cd1b2825ce394e7572b7dbb8f12b7a331ca78c728ddbcaa1b" }, "downloads": -1, "filename": "bungiesearch-1.2.0.tar.gz", "has_sig": false, "md5_digest": "d4211f5ac1c7cbe848433a435a8e3b8d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 37805, "upload_time": "2015-08-07T15:37:49", "url": "https://files.pythonhosted.org/packages/84/bf/93552fab7bdd66772731331b8ce83dff3454323cab06caa9816e45949374/bungiesearch-1.2.0.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "9e06cf398f84c3d87472f16d3cca1902", "sha256": "ec9979d3f1cdb15d0065f9a27c4ac90389f8c58bde0e85388b3cf410e3135395" }, "downloads": -1, "filename": "bungiesearch-1.2.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9e06cf398f84c3d87472f16d3cca1902", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 48066, "upload_time": "2015-08-10T10:45:29", "url": "https://files.pythonhosted.org/packages/2a/a4/596c5c581e83c08f0bf79fe519d568456a960c80b0778c12a85a84f5f57b/bungiesearch-1.2.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1ee84abde71f724269cc050b94b1309e", "sha256": "662f7a702e441f7662cc2233493935830f638f32b5b80a5460a4810a562339fb" }, "downloads": -1, "filename": "bungiesearch-1.2.1.tar.gz", "has_sig": false, "md5_digest": "1ee84abde71f724269cc050b94b1309e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 47213, "upload_time": "2015-08-10T10:45:25", "url": "https://files.pythonhosted.org/packages/c7/d4/7ac190569459bbfa472404c1d60671c715a41cf5e9513800324ffd06c823/bungiesearch-1.2.1.tar.gz" } ], "1.2.2": [ { "comment_text": "", "digests": { "md5": "972eac11859a4d76d8a725d0b239ff6f", "sha256": "f2a190660d6d88fe79a57f5eeb33d596c8c7b633b74d6a73e39064249c46ca2a" }, "downloads": -1, "filename": "bungiesearch-1.2.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "972eac11859a4d76d8a725d0b239ff6f", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 48363, "upload_time": "2015-11-05T12:19:40", "url": "https://files.pythonhosted.org/packages/76/fd/f4a842d9a52f30b44b2be84861c0902bc186d5d29e5dc90853a2356a476d/bungiesearch-1.2.2-py2.py3-none-any.whl" } ], "1.3.0": [ { "comment_text": "", "digests": { "md5": "fccd780fa6c4f5dc672a91d09b4c3968", "sha256": "eafb5fa8236f087edc2bf94a1416b173823a3dfcecb4f94d2e303136b717bb00" }, "downloads": -1, "filename": "bungiesearch-1.3.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "fccd780fa6c4f5dc672a91d09b4c3968", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 48566, "upload_time": "2015-12-04T13:02:00", "url": "https://files.pythonhosted.org/packages/2b/a0/d95640a1ea3af48de5338caa887b11e814ba791e244d3f8e4e5b8d89da37/bungiesearch-1.3.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "732e4de9dbb9264af7abd816d2fd5dd1", "sha256": "973aa0d5e85e97fecf66932173e1ed5923745c23977e4068706e332d22147ad3" }, "downloads": -1, "filename": "bungiesearch-1.3.0.tar.gz", "has_sig": false, "md5_digest": "732e4de9dbb9264af7abd816d2fd5dd1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 47907, "upload_time": "2015-12-04T13:01:55", "url": "https://files.pythonhosted.org/packages/21/27/642df321ba9adea9de114e5659c01aef5af2e01a90ee6f0f9326538626a9/bungiesearch-1.3.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "fccd780fa6c4f5dc672a91d09b4c3968", "sha256": "eafb5fa8236f087edc2bf94a1416b173823a3dfcecb4f94d2e303136b717bb00" }, "downloads": -1, "filename": "bungiesearch-1.3.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "fccd780fa6c4f5dc672a91d09b4c3968", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 48566, "upload_time": "2015-12-04T13:02:00", "url": "https://files.pythonhosted.org/packages/2b/a0/d95640a1ea3af48de5338caa887b11e814ba791e244d3f8e4e5b8d89da37/bungiesearch-1.3.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "732e4de9dbb9264af7abd816d2fd5dd1", "sha256": "973aa0d5e85e97fecf66932173e1ed5923745c23977e4068706e332d22147ad3" }, "downloads": -1, "filename": "bungiesearch-1.3.0.tar.gz", "has_sig": false, "md5_digest": "732e4de9dbb9264af7abd816d2fd5dd1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 47907, "upload_time": "2015-12-04T13:01:55", "url": "https://files.pythonhosted.org/packages/21/27/642df321ba9adea9de114e5659c01aef5af2e01a90ee6f0f9326538626a9/bungiesearch-1.3.0.tar.gz" } ] }