Full-text multi-table search application for Django. Easy to install and use, with good performance.

django-watson

Build Status PyPI GitHub license

django-watson is a fast multi-model full-text search plugin for Django.

It is easy to install and use, and provides high quality search results.

Features

  • Search across multiple models.
  • Order results by relevance.
  • No need to install additional third-party modules or services.
  • Fast and scaleable enough for most use cases.
  • Supports Django 1.11+, Python 3.6+.

Documentation

Please read the Getting Started guide for more information.

Download instructions, bug reporting and links to full documentation can be found at the main project website.

You can keep up to date with the latest announcements by joining the django-watson discussion group.

Contributing

Bug reports, bug fixes, and new features are always welcome. Please raise issues on the django-watson github repository, and submit pull requests for any new code.

You can run the test suite yourself from within a virtual environment with the following commands.

    pip install psycopg2 mysqlclient -e .
    tests/runtests.py
    tests/runtests.py -d psql
    tests/runtests.py -d mysql

More information

The django-watson project was developed by Dave Hall. You can get the code from the django-watson project site.

Dave Hall is a freelance web developer, based in Cambridge, UK. You can usually find him on the Internet in a number of different places:

Owner
Dave Hall
Experienced Python, Rust and Typescript developer. Equally comfortable in the cloud, or down to the metal on embedded hardware.
Dave Hall
Comments
  • Building the index from scratch takes a while

    Building the index from scratch takes a while

    170000 records took about an hour to build. Can we parallelize some of the work so that for example each model will use a different process to build it's index? We could use the ProcessPoolExecutor if it's available. What do you think?

  • AppRegistryNotReady exception

    AppRegistryNotReady exception

    Hello,

    I can't register a model in watson anymore since I've upgraded to Django 1.9.

    It raises a AppRegistryNotReady exception. I'm using an AppConfig for my module set in my init.py file :

    from django.apps import AppConfig
    from watson import search as watson
    
    class ProduitsConfig(AppConfig):
        name = "moderation.apps.produits"
    
        def ready(self):
            ProduitModel = self.get_model("Produit")
            watson.register(ProduitModel, fields=("nom", "marque__nom", "marque__pays__nom", "marque__region__nom", "type", "couleur"))
    

    When I comment the watson import and the register line, I don't have any error.

    Am I missing something ?

  • Inconsistent behaviour of full text search on different postgres versions

    Inconsistent behaviour of full text search on different postgres versions

    >>> watson.search(u"&")
    *** DatabaseError: FEHLER:  Syntaxfehler in tsquery: »&:*«
    

    ("FEHLER" == error in german)

    also I quite don't understand this:

    >>> watson.filter(jobs, "Geophys")
    [<Job: Professor in Geophysics>, <Job: Assistant or Associate Professor in Structural Geology-Active Tectonics>]
    >>> watson.filter(jobs, "Geophysics")
    []
    

    with the following (simplified) model.py file

    from django.db import models
    import watson
    
    class Job(models.Model):
        title = models.CharField(max_length=80)
        job_description = models.TextField()
    
        def __unicode__(self):
            return "%s" % (self.title)
    
    watson.register(Job, fields=("title", "job_description",))
    
  • AttributeError at /search/ 'NoneType' object has no attribute '_meta'

    AttributeError at /search/ 'NoneType' object has no attribute '_meta'

    I've been bashing against the wall for a few hours now.

    I've tried a host of different things, but am stumped (and clueless).

    I suspect it's related to my project setup: meaning, I have two apps in my django project: api, which houses the models, and website, which is a 'naked' app with no models (just the views, templates, and urls). website imports api.models. I am registering the models with watson in the api app, and the search engine works flawlessly from the command line.

    Thanks...

    AttributeError at /search/
    'NoneType' object has no attribute '_meta'
    Request Method: GET
    Request URL:    http://localhost:8000/search/?q=voices
    Django Version: 1.7.4
    Exception Type: AttributeError
    Exception Value:    
    'NoneType' object has no attribute '_meta'
    Exception Location: /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/watson/templatetags/watson.py in search_result_item, line 33
    Python Executable:  /Users/dbinetti/.virtualenvs/barberscore/bin/python2.7
    Python Version: 2.7.9
    Python Path:    
    ['/Users/dbinetti/.virtualenvs/barberscore/bin',
     '/Users/dbinetti/Repos/barberscore/project',
     '/Users/dbinetti/.virtualenvs/barberscore/lib/python27.zip',
     '/Users/dbinetti/.virtualenvs/barberscore/lib/python2.7',
     '/Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/plat-darwin',
     '/Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/plat-mac',
     '/Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/plat-mac/lib-scriptpackages',
     '/Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/lib-tk',
     '/Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/lib-old',
     '/Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/lib-dynload',
     '/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7',
     '/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin',
     '/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk',
     '/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac',
     '/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages',
     '/Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages']
    Server time:    Thu, 29 Jan 2015 13:35:55 -0800
    Error during template rendering
    
    In template /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/watson/templates/watson/includes/search_results.html, error at line 6
    'NoneType' object has no attribute '_meta'
    1   {% load watson %}
    2   {% if search_results %}
    3       <ul class="search-results">
    4           {% for search_result in search_results %}
    5               <li>
    6                   {% search_result_item search_result %}
    7               </li>
    8           {% endfor %}
    9       </ul>
    10  {% endif %}
    Traceback Switch to copy-and-paste view
    
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/core/handlers/base.py in get_response
                    response = response.render() ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/response.py in render
                self.content = self.rendered_content ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/response.py in rendered_content
            content = template.render(context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/base.py in render
                return self._render(context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/base.py in _render
            return self.nodelist.render(context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/base.py in render
                    bit = self.render_node(node, context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/debug.py in render_node
                return node.render(context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/defaulttags.py in render
                    return nodelist.render(context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/base.py in render
                    bit = self.render_node(node, context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/debug.py in render_node
                return node.render(context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/base.py in render
                        return func(*resolved_args, **resolved_kwargs) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/watson/templatetags/watson.py in search_results
            return template.loader.render_to_string("watson/includes/search_results.html", context) ...
    ▼ Local vars
    Variable    Value
    search_results  
    [<SearchEntry: Voices of Gotham (rename)>, <SearchEntry: Voices of Gotham>, <SearchEntry: Voices of California (rename)>, <SearchEntry: Voices of California>, <SearchEntry: Voices in Harmony (rename)>, <SearchEntry: Voices in Harmony>]
    context 
    [{'False': False, 'None': None, 'True': True}, {u'paginator': None, u'search_results': [<SearchEntry: Voices of Gotham (rename)>, <SearchEntry: Voices of Gotham>, <SearchEntry: Voices of California (rename)>, <SearchEntry: Voices of California>, <SearchEntry: Voices in Harmony (rename)>, <SearchEntry: Voices in Harmony>], u'object_list': [<SearchEntry: Voices of Gotham (rename)>, <SearchEntry: Voices of Gotham>, <SearchEntry: Voices of California (rename)>, <SearchEntry: Voices of California>, <SearchEntry: Voices in Harmony (rename)>, <SearchEntry: Voices in Harmony>], u'page_obj': None, u'query': u'voices', u'is_paginated': False, u'view': <watson.views.SearchView object at 0x10e9f6050>}, {u'csrf_token': <django.utils.functional.__proxy__ object at 0x10ea77510>, 'perms': <django.contrib.auth.context_processors.PermWrapper object at 0x10ea77650>, u'request': <WSGIRequest
    path:/search/,
    GET:<QueryDict: {u'q': [u'voices']}>,
    POST:<QueryDict: {}>,
    COOKIES:{'csrftoken': 'mGEwVxCd6Jga16ll5LHCZmZUTE1FzPkc', 'djdt': 'show'},
    META:{'AWS_ACCESS_KEY_ID': 'AKIAIASRKQ66PJ7KIAZQ',
     'AWS_MEDIA_BUCKET_NAME': 'barberscore-files-dev',
     'AWS_SECRET_ACCESS_KEY': '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',
     'AWS_STATIC_BUCKET_NAME': 'barberscore-static-dev',
     'Apple_PubSub_Socket_Render': '/private/tmp/com.apple.launchd.mC1p9mCyGI/Render',
     'CONTENT_LENGTH': '',
     'CONTENT_TYPE': 'text/plain',
     u'CSRF_COOKIE': u'mGEwVxCd6Jga16ll5LHCZmZUTE1FzPkc',
     'DATABASE_URL': 'postgres://[email protected]/barberscore',
     'DJANGO_DEBUG': 'True',
     'DJANGO_SETTINGS_MODULE': 'settings.dev',
     'DOMAIN': 'localhost',
     'EDITOR': '/Applications/Sublime Text.app/Contents/MacOS/Sublime Text',
     'FULL_NAME': 'David Binetti',
     'GATEWAY_INTERFACE': 'CGI/1.1',
     'HOME': '/Users/dbinetti',
     'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
     'HTTP_ACCEPT_ENCODING': 'gzip, deflate, sdch',
     'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.8',
     'HTTP_CONNECTION': 'keep-alive',
     'HTTP_COOKIE': 'csrftoken=mGEwVxCd6Jga16ll5LHCZmZUTE1FzPkc; djdt=show',
     'HTTP_HOST': 'localhost:8000',
     'HTTP_REFERER': 'http://localhost:8000/',
     'HTTP_USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36',
     'LANG': 'en_US.UTF-8',
     'LOGNAME': 'dbinetti',
     'OLDPWD': '/Users/dbinetti',
     'PATH': '/Users/dbinetti/.virtualenvs/barberscore/bin:/usr/local/bin:/usr/local/sbin:/usr/local/opt/ruby/bin:/usr/local/heroku/bin:/opt/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin',
     'PATH_INFO': u'/search/',
     'PGDATA': '/usr/local/var/postgres',
     'PORT': '8000',
     'PROJECT_HOME': '/Users/dbinetti/Repos',
     'PS1': '\\[\\033[0;32m\\](barberscore)$ \\[\\033[0;00m\\]',
     'PWD': '/Users/dbinetti/Repos/barberscore',
     'PYTHONDONTWRITEBYTECODE': 'True',
     'PYTHONPATH': '/Users/dbinetti/Repos/barberscore/project/',
     'QUERY_STRING': 'q=voices',
     'REMOTE_ADDR': '127.0.0.1',
     'REMOTE_HOST': '',
     'REQUEST_METHOD': 'GET',
     'REUSE_DB': '1',
     'RUN_MAIN': 'true',
     'SCRIPT_NAME': u'',
     'SECRET_KEY': 'x*c*ud&+g-j#%#uj)=m)^yrr!g9#@rw_x8+wzio5qg5gid!o7+',
     'SERVER_NAME': '1.0.0.127.in-addr.arpa',
     'SERVER_PORT': '8000',
     'SERVER_PROTOCOL': 'HTTP/1.1',
     'SERVER_SOFTWARE': 'WSGIServer/0.1 Python/2.7.9',
     'SHELL': '/bin/bash',
     'SHLVL': '1',
     'SSH_AUTH_SOCK': '/private/tmp/com.apple.launchd.nDeR0gqMf7/Listeners',
     'TERM': 'xterm-256color',
     'TERM_PROGRAM': 'Apple_Terminal',
     'TERM_PROGRAM_VERSION': '343.6',
     'TERM_SESSION_ID': '537B5640-762B-42F8-9612-F257ED943BEB',
     'TMPDIR': '/var/folders/fr/_d9wg7416219y9vhpwv05g4r0000gn/T/',
     'TWILIO_ACCOUNT_SID': 'ACb1b9bca9ccef183757e6ebdb64d063c3',
     'TWILIO_ADMIN_NUMBER': '+15005550006',
     'TWILIO_ADMIN_SID': 'PNc708ea5ce72d401fa043e0cb55c4e6b1',
     'TWILIO_AUTH_TOKEN': '41bd31f387ba44b7bfd7cf4965ce06f7',
     'TZ': 'US/Pacific',
     'USER': 'dbinetti',
     'USER_EMAIL': '[email protected]',
     'VIRTUALENVWRAPPER_HOOK_DIR': '/Users/dbinetti/.virtualenvs',
     'VIRTUALENVWRAPPER_PROJECT_FILENAME': '.project',
     'VIRTUALENVWRAPPER_PYTHON': '/usr/local/bin/python',
     'VIRTUALENVWRAPPER_SCRIPT': '/usr/local/bin/virtualenvwrapper.sh',
     'VIRTUALENVWRAPPER_VIRTUALENV': '/usr/local/bin/virtualenv',
     'VIRTUALENVWRAPPER_VIRTUALENV_ARGS': '--no-site-packages',
     'VIRTUAL_ENV': '/Users/dbinetti/.virtualenvs/barberscore',
     'WORKON_HOME': '/Users/dbinetti/.virtualenvs',
     'XPC_FLAGS': '0x0',
     'XPC_SERVICE_NAME': '0',
     '_': '/Users/dbinetti/.virtualenvs/barberscore/bin/django-admin',
     '__CF_USER_TEXT_ENCODING': '0x1F5:0x0:0x0',
     'wsgi.errors': <open file '<stderr>', mode 'w' at 0x10c4031e0>,
     'wsgi.file_wrapper': <class wsgiref.util.FileWrapper at 0x10d6b8738>,
     'wsgi.input': <socket._fileobject object at 0x10dafaa50>,
     'wsgi.multiprocess': False,
     'wsgi.multithread': True,
     'wsgi.run_once': False,
     'wsgi.url_scheme': 'http',
     'wsgi.version': (1, 0),
     (u'watson.search_context_middleware_active', <watson.middleware.SearchContextMiddleware object at 0x10db721d0>): True}>, 'messages': <django.contrib.messages.storage.fallback.FallbackStorage object at 0x10db80250>, u'TIME_ZONE': 'US/Pacific', u'STATIC_URL': '/static/', u'LANGUAGES': (('af', 'Afrikaans'), ('ar', 'Arabic'), ('ast', 'Asturian'), ('az', 'Azerbaijani'), ('bg', 'Bulgarian'), ('be', 'Belarusian'), ('bn', 'Bengali'), ('br', 'Breton'), ('bs', 'Bosnian'), ('ca', 'Catalan'), ('cs', 'Czech'), ('cy', 'Welsh'), ('da', 'Danish'), ('de', 'German'), ('el', 'Greek'), ('en', 'English'), ('en-au', 'Australian English'), ('en-gb', 'British English'), ('eo', 'Esperanto'), ('es', 'Spanish'), ('es-ar', 'Argentinian Spanish'), ('es-mx', 'Mexican Spanish'), ('es-ni', 'Nicaraguan Spanish'), ('es-ve', 'Venezuelan Spanish'), ('et', 'Estonian'), ('eu', 'Basque'), ('fa', 'Persian'), ('fi', 'Finnish'), ('fr', 'French'), ('fy', 'Frisian'), ('ga', 'Irish'), ('gl', 'Galician'), ('he', 'Hebrew'), ('hi', 'Hindi'), ('hr', 'Croatian'), ('hu', 'Hungarian'), ('ia', 'Interlingua'), ('id', 'Indonesian'), ('io', 'Ido'), ('is', 'Icelandic'), ('it', 'Italian'), ('ja', 'Japanese'), ('ka', 'Georgian'), ('kk', 'Kazakh'), ('km', 'Khmer'), ('kn', 'Kannada'), ('ko', 'Korean'), ('lb', 'Luxembourgish'), ('lt', 'Lithuanian'), ('lv', 'Latvian'), ('mk', 'Macedonian'), ('ml', 'Malayalam'), ('mn', 'Mongolian'), ('mr', 'Marathi'), ('my', 'Burmese'), ('nb', 'Norwegian Bokmal'), ('ne', 'Nepali'), ('nl', 'Dutch'), ('nn', 'Norwegian Nynorsk'), ('os', 'Ossetic'), ('pa', 'Punjabi'), ('pl', 'Polish'), ('pt', 'Portuguese'), ('pt-br', 'Brazilian Portuguese'), ('ro', 'Romanian'), ('ru', 'Russian'), ('sk', 'Slovak'), ('sl', 'Slovenian'), ('sq', 'Albanian'), ('sr', 'Serbian'), ('sr-latn', 'Serbian Latin'), ('sv', 'Swedish'), ('sw', 'Swahili'), ('ta', 'Tamil'), ('te', 'Telugu'), ('th', 'Thai'), ('tr', 'Turkish'), ('tt', 'Tatar'), ('udm', 'Udmurt'), ('uk', 'Ukrainian'), ('ur', 'Urdu'), ('vi', 'Vietnamese'), ('zh-cn', 'Simplified Chinese'), ('zh-hans', 'Simplified Chinese'), ('zh-hant', 'Traditional Chinese'), ('zh-tw', 'Traditional Chinese')), 'user': <SimpleLazyObject: <function <lambda> at 0x10db6aaa0>>, u'LANGUAGE_CODE': 'en-us', 'DEFAULT_MESSAGE_LEVELS': {'DEBUG': 10, 'INFO': 20, 'WARNING': 30, 'SUCCESS': 25, 'ERROR': 40}, u'LANGUAGE_BIDI': False, u'MEDIA_URL': '/media/'}, {}]
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/loader.py in render_to_string
            return t.render(Context(dictionary)) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/base.py in render
                return self._render(context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/base.py in _render
            return self.nodelist.render(context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/base.py in render
                    bit = self.render_node(node, context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/debug.py in render_node
                return node.render(context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/defaulttags.py in render
                    return nodelist.render(context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/base.py in render
                    bit = self.render_node(node, context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/debug.py in render_node
                return node.render(context) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/defaulttags.py in render
                                nodelist.append(node.render(context)) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/django/template/base.py in render
                        return func(*resolved_args, **resolved_kwargs) ...
    ▶ Local vars
    /Users/dbinetti/.virtualenvs/barberscore/lib/python2.7/site-packages/watson/templatetags/watson.py in search_result_item
            "app_label": obj._meta.app_label, ...
    ▼ Local vars
    Variable    Value
    obj 
    None
    search_result   
    <SearchEntry: Voices of Gotham (rename)>
    context 
    [{'False': False, 'None': None, 'True': True}, [{'False': False, 'None': None, 'True': True}, {u'paginator': None, u'search_results': [<SearchEntry: Voices of Gotham (rename)>, <SearchEntry: Voices of Gotham>, <SearchEntry: Voices of California (rename)>, <SearchEntry: Voices of California>, <SearchEntry: Voices in Harmony (rename)>, <SearchEntry: Voices in Harmony>], u'object_list': [<SearchEntry: Voices of Gotham (rename)>, <SearchEntry: Voices of Gotham>, <SearchEntry: Voices of California (rename)>, <SearchEntry: Voices of California>, <SearchEntry: Voices in Harmony (rename)>, <SearchEntry: Voices in Harmony>], u'page_obj': None, u'query': u'voices', u'is_paginated': False, u'view': <watson.views.SearchView object at 0x10e9f6050>}, {u'csrf_token': <django.utils.functional.__proxy__ object at 0x10ea77510>, 'perms': <django.contrib.auth.context_processors.PermWrapper object at 0x10ea77650>, u'request': <WSGIRequest
    path:/search/,
    GET:<QueryDict: {u'q': [u'voices']}>,
    POST:<QueryDict: {}>,
    COOKIES:{'csrftoken': 'mGEwVxCd6Jga16ll5LHCZmZUTE1FzPkc', 'djdt': 'show'},
    META:{'AWS_ACCESS_KEY_ID': 'AKIAIASRKQ66PJ7KIAZQ',
     'AWS_MEDIA_BUCKET_NAME': 'barberscore-files-dev',
     'AWS_SECRET_ACCESS_KEY': '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',
     'AWS_STATIC_BUCKET_NAME': 'barberscore-static-dev',
     'Apple_PubSub_Socket_Render': '/private/tmp/com.apple.launchd.mC1p9mCyGI/Render',
     'CONTENT_LENGTH': '',
     'CONTENT_TYPE': 'text/plain',
     u'CSRF_COOKIE': u'mGEwVxCd6Jga16ll5LHCZmZUTE1FzPkc',
     'DATABASE_URL': 'postgres://[email protected]/barberscore',
     'DJANGO_DEBUG': 'True',
     'DJANGO_SETTINGS_MODULE': 'settings.dev',
     'DOMAIN': 'localhost',
     'EDITOR': '/Applications/Sublime Text.app/Contents/MacOS/Sublime Text',
     'FULL_NAME': 'David Binetti',
     'GATEWAY_INTERFACE': 'CGI/1.1',
     'HOME': '/Users/dbinetti',
     'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
     'HTTP_ACCEPT_ENCODING': 'gzip, deflate, sdch',
     'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.8',
     'HTTP_CONNECTION': 'keep-alive',
     'HTTP_COOKIE': 'csrftoken=mGEwVxCd6Jga16ll5LHCZmZUTE1FzPkc; djdt=show',
     'HTTP_HOST': 'localhost:8000',
     'HTTP_REFERER': 'http://localhost:8000/',
     'HTTP_USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36',
     'LANG': 'en_US.UTF-8',
     'LOGNAME': 'dbinetti',
     'OLDPWD': '/Users/dbinetti',
     'PATH': '/Users/dbinetti/.virtualenvs/barberscore/bin:/usr/local/bin:/usr/local/sbin:/usr/local/opt/ruby/bin:/usr/local/heroku/bin:/opt/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin',
     'PATH_INFO': u'/search/',
     'PGDATA': '/usr/local/var/postgres',
     'PORT': '8000',
     'PROJECT_HOME': '/Users/dbinetti/Repos',
     'PS1': '\\[\\033[0;32m\\](barberscore)$ \\[\\033[0;00m\\]',
     'PWD': '/Users/dbinetti/Repos/barberscore',
     'PYTHONDONTWRITEBYTECODE': 'True',
     'PYTHONPATH': '/Users/dbinetti/Repos/barberscore/project/',
     'QUERY_STRING': 'q=voices',
     'REMOTE_ADDR': '127.0.0.1',
     'REMOTE_HOST': '',
     'REQUEST_METHOD': 'GET',
     'REUSE_DB': '1',
     'RUN_MAIN': 'true',
     'SCRIPT_NAME': u'',
     'SECRET_KEY': 'x*c*ud&+g-j#%#uj)=m)^yrr!g9#@rw_x8+wzio5qg5gid!o7+',
     'SERVER_NAME': '1.0.0.127.in-addr.arpa',
     'SERVER_PORT': '8000',
     'SERVER_PROTOCOL': 'HTTP/1.1',
     'SERVER_SOFTWARE': 'WSGIServer/0.1 Python/2.7.9',
     'SHELL': '/bin/bash',
     'SHLVL': '1',
     'SSH_AUTH_SOCK': '/private/tmp/com.apple.launchd.nDeR0gqMf7/Listeners',
     'TERM': 'xterm-256color',
     'TERM_PROGRAM': 'Apple_Terminal',
     'TERM_PROGRAM_VERSION': '343.6',
     'TERM_SESSION_ID': '537B5640-762B-42F8-9612-F257ED943BEB',
     'TMPDIR': '/var/folders/fr/_d9wg7416219y9vhpwv05g4r0000gn/T/',
     'TWILIO_ACCOUNT_SID': 'ACb1b9bca9ccef183757e6ebdb64d063c3',
     'TWILIO_ADMIN_NUMBER': '+15005550006',
     'TWILIO_ADMIN_SID': 'PNc708ea5ce72d401fa043e0cb55c4e6b1',
     'TWILIO_AUTH_TOKEN': '41bd31f387ba44b7bfd7cf4965ce06f7',
     'TZ': 'US/Pacific',
     'USER': 'dbinetti',
     'USER_EMAIL': '[email protected]',
     'VIRTUALENVWRAPPER_HOOK_DIR': '/Users/dbinetti/.virtualenvs',
     'VIRTUALENVWRAPPER_PROJECT_FILENAME': '.project',
     'VIRTUALENVWRAPPER_PYTHON': '/usr/local/bin/python',
     'VIRTUALENVWRAPPER_SCRIPT': '/usr/local/bin/virtualenvwrapper.sh',
     'VIRTUALENVWRAPPER_VIRTUALENV': '/usr/local/bin/virtualenv',
     'VIRTUALENVWRAPPER_VIRTUALENV_ARGS': '--no-site-packages',
     'VIRTUAL_ENV': '/Users/dbinetti/.virtualenvs/barberscore',
     'WORKON_HOME': '/Users/dbinetti/.virtualenvs',
     'XPC_FLAGS': '0x0',
     'XPC_SERVICE_NAME': '0',
     '_': '/Users/dbinetti/.virtualenvs/barberscore/bin/django-admin',
     '__CF_USER_TEXT_ENCODING': '0x1F5:0x0:0x0',
     'wsgi.errors': <open file '<stderr>', mode 'w' at 0x10c4031e0>,
     'wsgi.file_wrapper': <class wsgiref.util.FileWrapper at 0x10d6b8738>,
     'wsgi.input': <socket._fileobject object at 0x10dafaa50>,
     'wsgi.multiprocess': False,
     'wsgi.multithread': True,
     'wsgi.run_once': False,
     'wsgi.url_scheme': 'http',
     'wsgi.version': (1, 0),
     (u'watson.search_context_middleware_active', <watson.middleware.SearchContextMiddleware object at 0x10db721d0>): True}>, 'messages': <django.contrib.messages.storage.fallback.FallbackStorage object at 0x10db80250>, u'TIME_ZONE': 'US/Pacific', u'STATIC_URL': '/static/', u'LANGUAGES': (('af', 'Afrikaans'), ('ar', 'Arabic'), ('ast', 'Asturian'), ('az', 'Azerbaijani'), ('bg', 'Bulgarian'), ('be', 'Belarusian'), ('bn', 'Bengali'), ('br', 'Breton'), ('bs', 'Bosnian'), ('ca', 'Catalan'), ('cs', 'Czech'), ('cy', 'Welsh'), ('da', 'Danish'), ('de', 'German'), ('el', 'Greek'), ('en', 'English'), ('en-au', 'Australian English'), ('en-gb', 'British English'), ('eo', 'Esperanto'), ('es', 'Spanish'), ('es-ar', 'Argentinian Spanish'), ('es-mx', 'Mexican Spanish'), ('es-ni', 'Nicaraguan Spanish'), ('es-ve', 'Venezuelan Spanish'), ('et', 'Estonian'), ('eu', 'Basque'), ('fa', 'Persian'), ('fi', 'Finnish'), ('fr', 'French'), ('fy', 'Frisian'), ('ga', 'Irish'), ('gl', 'Galician'), ('he', 'Hebrew'), ('hi', 'Hindi'), ('hr', 'Croatian'), ('hu', 'Hungarian'), ('ia', 'Interlingua'), ('id', 'Indonesian'), ('io', 'Ido'), ('is', 'Icelandic'), ('it', 'Italian'), ('ja', 'Japanese'), ('ka', 'Georgian'), ('kk', 'Kazakh'), ('km', 'Khmer'), ('kn', 'Kannada'), ('ko', 'Korean'), ('lb', 'Luxembourgish'), ('lt', 'Lithuanian'), ('lv', 'Latvian'), ('mk', 'Macedonian'), ('ml', 'Malayalam'), ('mn', 'Mongolian'), ('mr', 'Marathi'), ('my', 'Burmese'), ('nb', 'Norwegian Bokmal'), ('ne', 'Nepali'), ('nl', 'Dutch'), ('nn', 'Norwegian Nynorsk'), ('os', 'Ossetic'), ('pa', 'Punjabi'), ('pl', 'Polish'), ('pt', 'Portuguese'), ('pt-br', 'Brazilian Portuguese'), ('ro', 'Romanian'), ('ru', 'Russian'), ('sk', 'Slovak'), ('sl', 'Slovenian'), ('sq', 'Albanian'), ('sr', 'Serbian'), ('sr-latn', 'Serbian Latin'), ('sv', 'Swedish'), ('sw', 'Swahili'), ('ta', 'Tamil'), ('te', 'Telugu'), ('th', 'Thai'), ('tr', 'Turkish'), ('tt', 'Tatar'), ('udm', 'Udmurt'), ('uk', 'Ukrainian'), ('ur', 'Urdu'), ('vi', 'Vietnamese'), ('zh-cn', 'Simplified Chinese'), ('zh-hans', 'Simplified Chinese'), ('zh-hant', 'Traditional Chinese'), ('zh-tw', 'Traditional Chinese')), 'user': <SimpleLazyObject: <function <lambda> at 0x10db6aaa0>>, u'LANGUAGE_CODE': 'en-us', 'DEFAULT_MESSAGE_LEVELS': {'DEBUG': 10, 'INFO': 20, 'WARNING': 30, 'SUCCESS': 25, 'ERROR': 40}, u'LANGUAGE_BIDI': False, u'MEDIA_URL': '/media/'}, {}]]
    Request information
    
    GET
    Variable    Value
    q   
    u'voices'
    POST
    No POST data
    FILES
    No FILES data
    COOKIES
    Variable    Value
    csrftoken   
    'mGEwVxCd6Jga16ll5LHCZmZUTE1FzPkc'
    djdt    
    'show'
    META
    Variable    Value
    DOMAIN  
    'localhost'
    wsgi.multiprocess   
    False
    RUN_MAIN    
    'true'
    HTTP_REFERER    
    'http://localhost:8000/'
    PROJECT_HOME    
    '/Users/dbinetti/Repos'
    HTTP_ACCEPT_LANGUAGE    
    'en-US,en;q=0.8'
    SERVER_PROTOCOL 
    'HTTP/1.1'
    SERVER_SOFTWARE 
    'WSGIServer/0.1 Python/2.7.9'
    TERM_PROGRAM_VERSION    
    '343.6'
    TMPDIR  
    '/var/folders/fr/_d9wg7416219y9vhpwv05g4r0000gn/T/'
    PGDATA  
    '/usr/local/var/postgres'
    REQUEST_METHOD  
    'GET'
    LOGNAME 
    'dbinetti'
    USER    
    'dbinetti'
    PATH    
    '/Users/dbinetti/.virtualenvs/barberscore/bin:/usr/local/bin:/usr/local/sbin:/usr/local/opt/ruby/bin:/usr/local/heroku/bin:/opt/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'
    QUERY_STRING    
    'q=voices'
    HOME    
    '/Users/dbinetti'
    SECRET_KEY  
    'x*c*ud&+g-j#%#uj)=m)^yrr!g9#@rw_x8+wzio5qg5gid!o7+'
    VIRTUALENVWRAPPER_SCRIPT    
    '/usr/local/bin/virtualenvwrapper.sh'
    PORT    
    '8000'
    TERM_PROGRAM    
    'Apple_Terminal'
    LANG    
    'en_US.UTF-8'
    TERM    
    'xterm-256color'
    SHELL   
    '/bin/bash'
    VIRTUALENVWRAPPER_PYTHON    
    '/usr/local/bin/python'
    HTTP_COOKIE 
    'csrftoken=mGEwVxCd6Jga16ll5LHCZmZUTE1FzPkc; djdt=show'
    SERVER_NAME 
    '1.0.0.127.in-addr.arpa'
    REMOTE_ADDR 
    '127.0.0.1'
    SHLVL   
    '1'
    TWILIO_ACCOUNT_SID  
    'ACb1b9bca9ccef183757e6ebdb64d063c3'
    XPC_FLAGS   
    '0x0'
    wsgi.url_scheme 
    'http'
    USER_EMAIL  
    '[email protected]'
    SERVER_PORT 
    '8000'
    CONTENT_LENGTH  
    ''
    VIRTUALENVWRAPPER_VIRTUALENV    
    '/usr/local/bin/virtualenv'
    HTTP_CONNECTION 
    'keep-alive'
    HTTP_USER_AGENT 
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36'
    VIRTUALENVWRAPPER_VIRTUALENV_ARGS   
    '--no-site-packages'
    WORKON_HOME 
    '/Users/dbinetti/.virtualenvs'
    TERM_SESSION_ID 
    '537B5640-762B-42F8-9612-F257ED943BEB'
    XPC_SERVICE_NAME    
    '0'
    CONTENT_TYPE    
    'text/plain'
    REUSE_DB    
    '1'
    PYTHONPATH  
    '/Users/dbinetti/Repos/barberscore/project/'
    SSH_AUTH_SOCK   
    '/private/tmp/com.apple.launchd.nDeR0gqMf7/Listeners'
    VIRTUAL_ENV 
    '/Users/dbinetti/.virtualenvs/barberscore'
    TWILIO_AUTH_TOKEN   
    '41bd31f387ba44b7bfd7cf4965ce06f7'
    TWILIO_ADMIN_NUMBER 
    '+15005550006'
    EDITOR  
    '/Applications/Sublime Text.app/Contents/MacOS/Sublime Text'
    wsgi.input  
    <socket._fileobject object at 0x10dafaa50>
    Apple_PubSub_Socket_Render  
    '/private/tmp/com.apple.launchd.mC1p9mCyGI/Render'
    PS1 
    '\\[\\033[0;32m\\](barberscore)$ \\[\\033[0;00m\\]'
    DJANGO_DEBUG    
    'True'
    FULL_NAME   
    'David Binetti'
    wsgi.multithread    
    True
    TZ  
    'US/Pacific'
    PYTHONDONTWRITEBYTECODE 
    'True'
    AWS_ACCESS_KEY_ID   
    'AKIAIASRKQ66PJ7KIAZQ'
    _   
    '/Users/dbinetti/.virtualenvs/barberscore/bin/django-admin'
    HTTP_ACCEPT 
    'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
    VIRTUALENVWRAPPER_PROJECT_FILENAME  
    '.project'
    wsgi.file_wrapper   
    ''
    wsgi.version    
    (1, 0)
    VIRTUALENVWRAPPER_HOOK_DIR  
    '/Users/dbinetti/.virtualenvs'
    TWILIO_ADMIN_SID    
    'PNc708ea5ce72d401fa043e0cb55c4e6b1'
    wsgi.run_once   
    False
    CSRF_COOKIE 
    u'mGEwVxCd6Jga16ll5LHCZmZUTE1FzPkc'
    OLDPWD  
    '/Users/dbinetti'
    GATEWAY_INTERFACE   
    'CGI/1.1'
    SCRIPT_NAME 
    u''
    wsgi.errors 
    <open file '<stderr>', mode 'w' at 0x10c4031e0>
    __CF_USER_TEXT_ENCODING 
    '0x1F5:0x0:0x0'
    DATABASE_URL    
    'postgres://[email protected]/barberscore'
    PWD 
    '/Users/dbinetti/Repos/barberscore'
    (u'watson.search_context_middleware_active', <watson.middleware.SearchContextMiddleware object at 0x10db721d0>) 
    True
    DJANGO_SETTINGS_MODULE  
    'settings.dev'
    AWS_SECRET_ACCESS_KEY   
    '+pT4Toz1NDtJ7CvBtBm0U15jBB0k6DiigJULmChP'
    HTTP_HOST   
    'localhost:8000'
    AWS_STATIC_BUCKET_NAME  
    'barberscore-static-dev'
    REMOTE_HOST 
    ''
    HTTP_ACCEPT_ENCODING    
    'gzip, deflate, sdch'
    AWS_MEDIA_BUCKET_NAME   
    'barberscore-files-dev'
    PATH_INFO   
    u'/search/'
    Settings
    Using settings module settings.dev
    Setting Value
    USE_L10N    
    True
    USE_THOUSAND_SEPARATOR  
    False
    CSRF_COOKIE_SECURE  
    False
    LANGUAGE_CODE   
    'en-us'
    ROOT_URLCONF    
    'urls'
    MANAGERS    
    ()
    TEST_NON_SERIALIZED_APPS    
    []
    DEFAULT_CHARSET 
    'utf-8'
    SESSION_SERIALIZER  
    'django.contrib.sessions.serializers.JSONSerializer'
    STATIC_ROOT 
    '/static/'
    ALLOWED_HOSTS   
    ['localhost']
    MESSAGE_STORAGE 
    'django.contrib.messages.storage.fallback.FallbackStorage'
    EMAIL_SUBJECT_PREFIX    
    '[Django] '
    SEND_BROKEN_LINK_EMAILS 
    False
    STATICFILES_FINDERS 
    ('django.contrib.staticfiles.finders.FileSystemFinder',
     'django.contrib.staticfiles.finders.AppDirectoriesFinder')
    SESSION_CACHE_ALIAS 
    'default'
    SESSION_COOKIE_DOMAIN   
    None
    SESSION_COOKIE_NAME 
    'sessionid'
    ADMIN_FOR   
    ()
    TIME_INPUT_FORMATS  
    ('%H:%M:%S', '%H:%M:%S.%f', '%H:%M')
    DATABASES   
    {'default': {'ATOMIC_REQUESTS': False,
                 'AUTOCOMMIT': True,
                 'CONN_MAX_AGE': 0,
                 'ENGINE': 'django.db.backends.postgresql_psycopg2',
                 'HOST': 'localhost',
                 'NAME': 'barberscore',
                 'OPTIONS': {},
                 'PASSWORD': u'********************',
                 'PORT': '',
                 'TEST': {'CHARSET': None,
                          'COLLATION': None,
                          'MIRROR': None,
                          'NAME': None},
                 'TIME_ZONE': 'UTC',
                 'USER': 'dbinetti'}}
    FILE_UPLOAD_DIRECTORY_PERMISSIONS   
    None
    AWS_PRELOAD_METADATA    
    True
    FILE_UPLOAD_PERMISSIONS 
    None
    FILE_UPLOAD_HANDLERS    
    ('django.core.files.uploadhandler.MemoryFileUploadHandler',
     'django.core.files.uploadhandler.TemporaryFileUploadHandler')
    DEFAULT_CONTENT_TYPE    
    'text/html'
    DATABASE_URL    
    'postgres://[email protected]/barberscore'
    APPEND_SLASH    
    True
    FIRST_DAY_OF_WEEK   
    0
    DATABASE_ROUTERS    
    []
    DEFAULT_TABLESPACE  
    ''
    YEAR_MONTH_FORMAT   
    'F Y'
    STATICFILES_STORAGE 
    'django.contrib.staticfiles.storage.StaticFilesStorage'
    CACHES  
    {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}}
    DOMAIN  
    'localhost'
    SERVER_EMAIL    
    '[email protected]'
    SESSION_COOKIE_PATH 
    '/'
    SILENCED_SYSTEM_CHECKS  
    []
    MIDDLEWARE_CLASSES  
    ('corsheaders.middleware.CorsMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'watson.middleware.SearchContextMiddleware')
    USE_I18N    
    False
    THOUSAND_SEPARATOR  
    ','
    SECRET_KEY  
    u'********************'
    LANGUAGE_COOKIE_NAME    
    'django_language'
    DEFAULT_INDEX_TABLESPACE    
    ''
    TRANSACTIONS_MANAGED    
    False
    LOGGING_CONFIG  
    'logging.config.dictConfig'
    TEMPLATE_LOADERS    
    ('django.template.loaders.filesystem.Loader',
     'django.template.loaders.app_directories.Loader')
    WSGI_APPLICATION    
    'wsgi.application'
    TEMPLATE_DEBUG  
    True
    X_FRAME_OPTIONS 
    'SAMEORIGIN'
    CSRF_COOKIE_NAME    
    'csrftoken'
    FORCE_SCRIPT_NAME   
    None
    USE_X_FORWARDED_HOST    
    False
    SIGNING_BACKEND 
    'django.core.signing.TimestampSigner'
    SESSION_COOKIE_SECURE   
    False
    CACHE_MIDDLEWARE_KEY_PREFIX 
    u'********************'
    CSRF_COOKIE_DOMAIN  
    None
    FILE_CHARSET    
    'utf-8'
    DEBUG   
    True
    PHONENUMBER_DEFAULT_REGION  
    'US'
    LANGUAGE_COOKIE_DOMAIN  
    None
    AWS_ACCESS_KEY_ID   
    u'********************'
    DEFAULT_FILE_STORAGE    
    'django.core.files.storage.FileSystemStorage'
    INSTALLED_APPS  
    ('utils',
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'django.contrib.admin',
     'django.contrib.admindocs',
     'django.contrib.humanize',
     'timezone_field',
     'easy_select2',
     'corsheaders',
     'watson',
     'noncense',
     'rest_framework',
     'api',
     'website')
    LANGUAGES   
    (('af', 'Afrikaans'),
     ('ar', 'Arabic'),
     ('ast', 'Asturian'),
     ('az', 'Azerbaijani'),
     ('bg', 'Bulgarian'),
     ('be', 'Belarusian'),
     ('bn', 'Bengali'),
     ('br', 'Breton'),
     ('bs', 'Bosnian'),
     ('ca', 'Catalan'),
     ('cs', 'Czech'),
     ('cy', 'Welsh'),
     ('da', 'Danish'),
     ('de', 'German'),
     ('el', 'Greek'),
     ('en', 'English'),
     ('en-au', 'Australian English'),
     ('en-gb', 'British English'),
     ('eo', 'Esperanto'),
     ('es', 'Spanish'),
     ('es-ar', 'Argentinian Spanish'),
     ('es-mx', 'Mexican Spanish'),
     ('es-ni', 'Nicaraguan Spanish'),
     ('es-ve', 'Venezuelan Spanish'),
     ('et', 'Estonian'),
     ('eu', 'Basque'),
     ('fa', 'Persian'),
     ('fi', 'Finnish'),
     ('fr', 'French'),
     ('fy', 'Frisian'),
     ('ga', 'Irish'),
     ('gl', 'Galician'),
     ('he', 'Hebrew'),
     ('hi', 'Hindi'),
     ('hr', 'Croatian'),
     ('hu', 'Hungarian'),
     ('ia', 'Interlingua'),
     ('id', 'Indonesian'),
     ('io', 'Ido'),
     ('is', 'Icelandic'),
     ('it', 'Italian'),
     ('ja', 'Japanese'),
     ('ka', 'Georgian'),
     ('kk', 'Kazakh'),
     ('km', 'Khmer'),
     ('kn', 'Kannada'),
     ('ko', 'Korean'),
     ('lb', 'Luxembourgish'),
     ('lt', 'Lithuanian'),
     ('lv', 'Latvian'),
     ('mk', 'Macedonian'),
     ('ml', 'Malayalam'),
     ('mn', 'Mongolian'),
     ('mr', 'Marathi'),
     ('my', 'Burmese'),
     ('nb', 'Norwegian Bokmal'),
     ('ne', 'Nepali'),
     ('nl', 'Dutch'),
     ('nn', 'Norwegian Nynorsk'),
     ('os', 'Ossetic'),
     ('pa', 'Punjabi'),
     ('pl', 'Polish'),
     ('pt', 'Portuguese'),
     ('pt-br', 'Brazilian Portuguese'),
     ('ro', 'Romanian'),
     ('ru', 'Russian'),
     ('sk', 'Slovak'),
     ('sl', 'Slovenian'),
     ('sq', 'Albanian'),
     ('sr', 'Serbian'),
     ('sr-latn', 'Serbian Latin'),
     ('sv', 'Swedish'),
     ('sw', 'Swahili'),
     ('ta', 'Tamil'),
     ('te', 'Telugu'),
     ('th', 'Thai'),
     ('tr', 'Turkish'),
     ('tt', 'Tatar'),
     ('udm', 'Udmurt'),
     ('uk', 'Ukrainian'),
     ('ur', 'Urdu'),
     ('vi', 'Vietnamese'),
     ('zh-cn', 'Simplified Chinese'),
     ('zh-hans', 'Simplified Chinese'),
     ('zh-hant', 'Traditional Chinese'),
     ('zh-tw', 'Traditional Chinese'))
    COMMENTS_ALLOW_PROFANITIES  
    False
    TWILIO_AUTH_TOKEN   
    u'********************'
    STATIC_STORAGE  
    'django.contrib.staticfiles.storage.StaticFilesStorage'
    STATICFILES_DIRS    
    ()
    PHONENUMBER_DEFAULT_FORMAT  
    'NATIONAL'
    SECURE_PROXY_SSL_HEADER 
    ('HTTP_X_FORWARDED_PROTO', 'https')
    LANGUAGE_COOKIE_AGE 
    None
    SESSION_COOKIE_HTTPONLY 
    True
    AWS_SECRET_ACCESS_KEY   
    u'********************'
    DEBUG_PROPAGATE_EXCEPTIONS  
    False
    INTERNAL_IPS    
    ()
    AWS_MEDIA_BUCKET_NAME   
    'barberscore-files-dev'
    MONTH_DAY_FORMAT    
    'F j'
    LOGIN_URL   
    'login'
    SESSION_EXPIRE_AT_BROWSER_CLOSE 
    False
    TIME_FORMAT 
    'P'
    AUTH_USER_MODEL 
    'noncense.User'
    DATE_INPUT_FORMATS  
    ('%Y-%m-%d',
     '%m/%d/%Y',
     '%m/%d/%y',
     '%b %d %Y',
     '%b %d, %Y',
     '%d %b %Y',
     '%d %b, %Y',
     '%B %d %Y',
     '%B %d, %Y',
     '%d %B %Y',
     '%d %B, %Y')
    AUTHENTICATION_BACKENDS 
    ('noncense.backends.MobileBackend',
     'django.contrib.auth.backends.ModelBackend')
    EMAIL_HOST_PASSWORD 
    u'********************'
    PASSWORD_RESET_TIMEOUT_DAYS 
    u'********************'
    SESSION_FILE_PATH   
    None
    CACHE_MIDDLEWARE_ALIAS  
    'default'
    TWILIO_ACCOUNT_SID  
    'ACb1b9bca9ccef183757e6ebdb64d063c3'
    SESSION_SAVE_EVERY_REQUEST  
    False
    NUMBER_GROUPING 
    0
    SESSION_ENGINE  
    'django.contrib.sessions.backends.db'
    CSRF_FAILURE_VIEW   
    'django.views.csrf.csrf_failure'
    CSRF_COOKIE_PATH    
    '/'
    LOGIN_REDIRECT_URL  
    'home'
    PROJECT_ROOT    
    '/Users/dbinetti/Repos/barberscore/project'
    DECIMAL_SEPARATOR   
    '.'
    SELECT2_USE_BUNDLED_JQUERY  
    False
    MESSAGE_TAGS    
    {40: 'danger'}
    LOCALE_PATHS    
    ()
    TEMPLATE_STRING_IF_INVALID  
    ''
    LOGOUT_URL  
    'logout'
    EMAIL_USE_TLS   
    False
    FIXTURE_DIRS    
    ()
    EMAIL_HOST  
    'localhost'
    DATE_FORMAT 
    'N j, Y'
    MEDIA_ROOT  
    '/Users/dbinetti/Repos/barberscore/project/media'
    DEFAULT_EXCEPTION_REPORTER_FILTER   
    'django.views.debug.SafeExceptionReporterFilter'
    ADMINS  
    ()
    FORMAT_MODULE_PATH  
    None
    DEFAULT_FROM_EMAIL  
    '[email protected]'
    REST_FRAMEWORK  
    {'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.AllowAny']}
    MEDIA_URL   
    '/media/'
    DATETIME_FORMAT 
    'N j, Y, P'
    TEMPLATE_DIRS   
    ()
    DISALLOWED_USER_AGENTS  
    ()
    ALLOWED_INCLUDE_ROOTS   
    ()
    LOGGING 
    {'disable_existing_loggers': True,
     'formatters': {'simple': {'format': '%(levelname)s %(message)s'}},
     'handlers': {'console': {'class': 'logging.StreamHandler',
                              'formatter': 'simple',
                              'level': 'DEBUG'}},
     'loggers': {'api': {'handlers': ['console'], 'level': 'DEBUG'},
                 'noncense': {'handlers': ['console'], 'level': 'DEBUG'},
                 'utils': {'handlers': ['console'], 'level': 'DEBUG'},
                 'website': {'handlers': ['console'], 'level': 'DEBUG'}},
     'version': 1}
    PREPEND_WWW 
    False
    SHORT_DATE_FORMAT   
    'm/d/Y'
    PROJECT_NAME    
    'barberscore'
    TEST_RUNNER 
    'django.test.runner.DiscoverRunner'
    IGNORABLE_404_URLS  
    ()
    TIME_ZONE   
    'US/Pacific'
    CORS_ORIGIN_ALLOW_ALL   
    True
    FILE_UPLOAD_MAX_MEMORY_SIZE 
    2621440
    EMAIL_BACKEND   
    'django.core.mail.backends.smtp.EmailBackend'
    EMAIL_USE_SSL   
    False
    TEMPLATE_CONTEXT_PROCESSORS 
    ('django.contrib.auth.context_processors.auth',
     'django.core.context_processors.debug',
     'django.core.context_processors.i18n',
     'django.core.context_processors.media',
     'django.core.context_processors.static',
     'django.core.context_processors.tz',
     'django.contrib.messages.context_processors.messages',
     'django.core.context_processors.request')
    MEDIA_STORAGE   
    'django.core.files.storage.FileSystemStorage'
    SESSION_COOKIE_AGE  
    1209600
    SETTINGS_MODULE 
    'settings.dev'
    USE_ETAGS   
    False
    LANGUAGES_BIDI  
    ('he', 'ar', 'fa', 'ur')
    FILE_UPLOAD_TEMP_DIR    
    None
    CSRF_COOKIE_AGE 
    31449600
    STATIC_URL  
    '/static/'
    EMAIL_PORT  
    25
    USE_TZ  
    True
    SHORT_DATETIME_FORMAT   
    'm/d/Y P'
    PASSWORD_HASHERS    
    u'********************'
    ABSOLUTE_URL_OVERRIDES  
    {}
    LANGUAGE_COOKIE_PATH    
    '/'
    MIGRATION_MODULES   
    {}
    CACHE_MIDDLEWARE_SECONDS    
    600
    CSRF_COOKIE_HTTPONLY    
    False
    DATETIME_INPUT_FORMATS  
    ('%Y-%m-%d %H:%M:%S',
     '%Y-%m-%d %H:%M:%S.%f',
     '%Y-%m-%d %H:%M',
     '%Y-%m-%d',
     '%m/%d/%Y %H:%M:%S',
     '%m/%d/%Y %H:%M:%S.%f',
     '%m/%d/%Y %H:%M',
     '%m/%d/%Y',
     '%m/%d/%y %H:%M:%S',
     '%m/%d/%y %H:%M:%S.%f',
     '%m/%d/%y %H:%M',
     '%m/%d/%y')
    AWS_STATIC_BUCKET_NAME  
    'barberscore-static-dev'
    EMAIL_HOST_USER 
    ''
    PROFANITIES_LIST    
    u'********************'
    You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 500 page.
    
  • ./manage.py buildwatson extremely slow on 0,5 million rows

    ./manage.py buildwatson extremely slow on 0,5 million rows

    In my Postgresql db, there are around 438 972 rows that should be tracked by watson. The problem is that full index build (using the buildwatson management command) is extremely slow.

    (cb)[email protected] /srv/www/cb $ time ./manage.py buildwatson
    
    Killed
    
    real    123m22.753s
    

    Here the process was killed probably because it reached some system limits. It had been running for more than two hours and didn't finish.

    These are register commands I use:

      watson.register(Crag, fields=('normalized_name', 'country'))
      watson.register(Member.objects.all(), fields=('normalized_name', 'user', 'country'))
      watson.register(Event, fields=('normalized_name', 'country'))
      watson.register(Route, fields=('normalized_name', 'crag__name', 'crag__normalized_name'))
    

    The majority of all objects is contained in the Route model (more than 400 000).

    I would be very happy if the time could be reduced somehow.

  • Django 1.7 does not recognize data migrations properly

    Django 1.7 does not recognize data migrations properly

    First, a warning - this may be related to my setup only. But sharing it anyway since it might affect someone else too.

    My webapp uses django-nose for testing. As I was moving it to Django 1.7, I noticed that several of my tests were failing with error similar to this:

        return self.cursor.execute(sql, params)
    ProgrammingError: column watson_searchentry.search_tsv does not exist
    LINE 1: SELECT (ts_rank_cd(watson_searchentry.search_tsv, to_tsquery...
    

    A bit of digging revealed that migrations for watson were not running properly. Django 1.7.1 was claiming that watson was an "unmigrated app" as it had old style "South" migrations which were not being applied during my test run.

    I did try to convert them to new format following Django migrations tutorial, but the migration involving "installwatson" was ignored.

    I ended up resolving it by creating a new data migration for watson (using "python manage.py makemigration --empty watson" and updating the migration file so it looks like this:

    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    
    from django.db import models, migrations
    from django.core.management import call_command
    from watson.registration import get_backend
    
    
    def install_watson(apps, schema_editor):
        '''watson needs to be installed in the environment once DB is recreated
        (e.g. during tests). Django 1.7 didn't pick it up during conversion
        from south migrations to this is a workaround
        '''
        ## call_command("installwatson", verbosity=0)
    
        # the command above has problem with @atomic decorator, so we do it
        # manually
    
    
        backend = get_backend()
        if backend.requires_installation:
            backend.do_install()
    
    
    class Migration(migrations.Migration):
    
        dependencies = [
            ('watson', '0001_initial'),
        ]
    
        operations = [
            migrations.RunPython(install_watson),
        ]
    

    Sharing it here just in case someone else runs into the same issue.

  • Registering models with django-watson

    Registering models with django-watson

    I dont understand where i need to add this thanks to help me

    from django.apps import AppConfig
    import watson
    
    class YourAppConfig(AppConfig):
        name = "your_app"
        def ready(self):
            YourModel = self.get_model("YourModel")
            watson.register(YourModel)
    
  • removing patterns import

    removing patterns import

    urls.py raises the following ImportError on Django 1.10:

      File "/Users/simon/files/Projects/language5/env/lib/python2.7/site-packages/watson/urls.py", line 5, in <module>
        from django.conf.urls import url, patterns
    ImportError: cannot import name patterns
    

    ... and patterns isn't needed, so this removes the offending import.

    Also, I think https://github.com/etianen/django-watson/pull/148 can be closed as outdated/fixed.

  • watson.register not working

    watson.register not working

    did watson.register(MyModel) in AppConfig.ready(), watson.search('search term') returned an empty list.

    did watson.register(MyModel) in models.py, watson.search('search term') returned an empty list.

    did watson.register(MyModel) in shell, watson.search('search term') returned an empty list.

    MyModel is filled will models. These models have CharFields and TextFields.

    I'm running Django 1.7 and followed all the instructions for installation, I can see watson_searchentry in my postgresql database. To be clear, I did both manage.py installwatson and manage.py buildwatson. I did manage.py makemigrations, manage.py makemigrations watson (created 0001_initial.py), manage.py migrate (no migrations), manage.py migrate watson (no migrations).

    watson is in my INSTALLED_APPS.

    Here is some code:

    #apps.py
    
    from django.apps import AppConfig
    import watson
    
    class LinksAppConfig(AppConfig):
        name = 'links'
        def ready(self):
              Link = self.get_model('Link')
              watson.register(Link)
    
    #shell 
    in   >> import watson
    in   >> watson.search('charlie')
    out >> []
    

    Link has some models with the name 'charlie' in them.

    Please help

  • Indexing data only appears to work on save (cleared on buildwatson)

    Indexing data only appears to work on save (cleared on buildwatson)

    I'm having difficulty understanding what is going on with my installation. Let's take this fictional model (I'm using pretty much the same thing):

    class Entry(models.Model):
        title = models.CharField(max_length=255)
        excerpt = models.TextField(blank=True)
        content = models.TextField(blank=True)
        authors = models.ManyToManyField('zinnia.Author', related_name='entries', blank=True, null=False)
        categories = models.ManyToManyField('zinnia.Category', related_name='entries', blank=True, null=True)
        creation_date = models.DateTimeField(default=timezone.now)
        published_date = models.DateTimeField(default=timezone.now)
    
        published = BlogEntryPublishedManager()  # Returns Entries with a published date in the past
    
    
    class EntrySearchAdapter(watson.SearchAdapter):
    
        """ Custom search adapter to improve priority of various fields. """
    
        def get_title(self, obj):
            return obj.title
    
        def get_description(self, obj):
            return obj.excerpt
    
    watson.register(zinnia_entry.published.all()), EntrySearchAdapter, fields=("content", "excerpt", "title", "authors", "categories", "creation_date"))
    

    If I run ./manage.py buildwatson --engine=default on a fresh db (with existing Entry's), I see no new rows added to the table:

    mysql> select * from watson_searchentry;
    Empty set (0.00 sec)
    

    If I save one of the existing entries, everything looks ok now:

    mysql> select * from watson_searchentry;
    ...the serialized content...
    1 row in set (0.00 sec)
    

    If I run ./manage.py buildwatson --engine=default again, it's all empty:

    mysql> select * from watson_searchentry;
    Empty set (0.00 sec)
    
    1. Am I misunderstanding the workflow required to build/refresh the index for existing data?
    2. Why does buildwatson default to the admin engine? Shouldn't it be default?
  • Clearing the database-cached data?

    Clearing the database-cached data?

    I have a platform where advertisements often get marked as "deleted" if they are not renewed. The problem is that they still appear registered on watson, leading to a 404 error. I believe, in my case, I will have to rebuild the whole search table every time I update watson. Is there any command to clear the table, @etianen ? I want to use it before I run build watson.

  • Using non numeric primary keys

    Using non numeric primary keys

    Hi !

    I am using Django Hash ID for my primary keys of my models (https://github.com/nshafer/django-hashid-field). When building indexes of the models django-watson is expecting numeric primary keys. Would it be possible to handle both string and numeric primary keys ? Or do you advise a better strategy for using django-watson in my case ?

    Here is the error log when running buildwatson command:

    Traceback (most recent call last):
      File "/Users/johndoe/repos/myproject/application/./manage.py", line 22, in <module>
        main()
      File "/Users/johndoe/repos/myproject/application/./manage.py", line 18, in main
        execute_from_command_line(sys.argv)
      File "/Users/johndoe/.pyenv/versions/myproject_application/lib/python3.9/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
        utility.execute()
      File "/Users/johndoe/.pyenv/versions/myproject_application/lib/python3.9/site-packages/django/core/management/__init__.py", line 440, in execute
        self.fetch_command(subcommand).run_from_argv(self.argv)
      File "/Users/johndoe/.pyenv/versions/myproject_application/lib/python3.9/site-packages/django/core/management/base.py", line 414, in run_from_argv
        self.execute(*args, **cmd_options)
      File "/Users/johndoe/.pyenv/versions/myproject_application/lib/python3.9/site-packages/django/core/management/base.py", line 460, in execute
        output = self.handle(*args, **options)
      File "/Users/johndoe/.pyenv/versions/myproject_application/lib/python3.9/site-packages/watson/management/commands/buildwatson.py", line 187, in handle
        refreshed_model_count += rebuild_index_for_model(
      File "/Users/johndoe/.pyenv/versions/myproject_application/lib/python3.9/site-packages/watson/management/commands/buildwatson.py", line 74, in rebuild_index_for_model
        _bulk_save_search_entries(iter_search_entries(), batch_size=batch_size_)
      File "/Users/johndoe/.pyenv/versions/myproject_application/lib/python3.9/site-packages/watson/search.py", line 207, in _bulk_save_search_entries
        search_entry_batch = list(islice(search_entries, 0, batch_size))
      File "/Users/johndoe/.pyenv/versions/myproject_application/lib/python3.9/site-packages/watson/management/commands/buildwatson.py", line 47, in iter_search_entries
        for search_entry in search_engine_._update_obj_index_iter(obj):
      File "/Users/johndoe/.pyenv/versions/myproject_application/lib/python3.9/site-packages/watson/search.py", line 510, in _update_obj_index_iter
        object_id_int, search_entries = self._get_entries_for_obj(obj)
      File "/Users/johndoe/.pyenv/versions/myproject_application/lib/python3.9/site-packages/watson/search.py", line 480, in _get_entries_for_obj
        object_id_int = int(obj.pk)
    
    ValueError: invalid literal for int() with base 10: 'OzZYA4y3q9X5VMGg'
    

    Here OzZYA4y3q9X5VMGg is the hash id of my model (which is the primary key).

    Thank you very much 🙏 !

  • Search for a subset by filtering on related model fields

    Search for a subset by filtering on related model fields

    Hello,

    Thanks for creating and maintaining this great package!

    I've run into a situation where I would like to search a subset of models by filtering on a related model's field, like this:

    watson.search("Search terms", models=(MyModel.objects.filter(related__is_public=True),))

    When I try this, I get a django.db.utils.ProgrammingError: column reference "id" is ambiguous error.

    Not sure if i'm missing a configuration, or if this isn't feasible at the moment. Would be great to know a way how to do this.

    Thanks!

    P.S. Here is the actual db error I'm working with, incase something else is going on:

    ERROR:  column reference "id" is ambiguous at character 578
    STATEMENT:  SELECT (ts_rank_cd(watson_searchentry.search_tsv, to_tsquery('pg_catalog.simple', '$$c$$:*'))) AS "watson_rank", "watson_searchentry"."id", "watson_searchentry"."engine_slug", "watson_searchentry"."content_type_id", "watson_searchentry"."object_id", "watson_searchentry"."object_id_int", "watson_searchentry"."title", "watson_searchentry"."description", "watson_searchentry"."content", "watson_searchentry"."url", "watson_searchentry"."meta_encoded" FROM "watson_searchentry" WHERE ("watson_searchentry"."engine_slug" = 'bread' AND "watson_searchentry"."object_id" IN (SELECT ("id"::text) AS "watson_pk_str" FROM "services_servicefirm" U0 INNER JOIN "professionals_company" U1 ON (U0."company_id" = U1."id") WHERE (U1."claimed_on" IS NOT NULL AND U1."deleted_on" IS NULL AND U1."is_public" = true AND U0."deleted_on" IS NULL AND U0."is_public" = true AND U0."membership_is_active" = true)) AND "watson_searchentry"."content_type_id" = 124 AND (search_tsv @@ to_tsquery('pg_catalog.simple', '$$c$$:*'))) ORDER BY "watson_rank" DESC  LIMIT 21
    

    from

    filters = dict(
        company__claimed_on__isnull=False,
        company__deleted_on=None,
        deleted_on=None,
        company__is_public=True,
        is_public=True,
        membership_is_active=True,
    )
    
    watson.search("Search terms", models=(ServiceFirm.objects.filter(**filters),))
    
  • psycopg2.errors.UndefinedTable: relation

    psycopg2.errors.UndefinedTable: relation "watson_searchentry" does not exist

    We are seeing this error when you deploy our project. This was working fine till last week or so but not sure what was changed in Watson. Could someone look at it.

    /home/../env/bin/python manage.py makemigrations
    /home/../env/bin/python manage.py migrate
    /home/../env/bin/pip install django-watson
    /home/../bin/python manage.py installwatson
    + /home/../env/bin/python manage.py installwatson
    Traceback (most recent call last):
      File "/home/../env/lib/python3.8/site-packages/django/db/backends/utils.py", line 82, in _execute
        return self.cursor.execute(sql)
    psycopg2.errors.UndefinedTable: relation "watson_searchentry" does not exist
    The above exception was the direct cause of the following exception:
    .........
    ........
    django.db.utils.ProgrammingError: relation "watson_searchentry" does not exist
    script returned exit code 2
    

    Here is the list of versions that we are in our django based web application:

    Django version: 3.1.6
    Python version: 3.8
    Pip version: 21.2.4
    virtualenv version: 20.4.3
    django-watson version: 1.5.5
    
  • Added --slice-queryset argument

    Added --slice-queryset argument

    Came across your library and wanted to integrate it for a client, great work!

    However when I was deploying on a relatively big database (2M rows, big model with lots of text data), the process was always getting killed on PythonAnywhere while using all the CPU and ram available, without creating a single index in watson_searchentry.

    So I tinkered a bit and found that .iterator() is the issue in my case (limited resources, MySQL database too), buildwatson doesn't get to create any index, eventually changed the code to slice instead of .iterator and it got through.

    I add an argument to buildwatson called --slice-queryset to slice it instead of iterate, if that works for others in some cases.

  • Possible to search with partial match?

    Possible to search with partial match?

    I love this library and have been using it on all websites. However, there is one issue that need solution.

    If I search 'example', result is given. If I search 'some extra text example' no results given.

    Is it possible to get result even if a single word matches instead of full words matching?

  • expose metadata also in .filter() results

    expose metadata also in .filter() results

    Currently when using .search() you can access the metadata of each searchresult using result.meta['xxxx'] or result.meta.xxxx.

    When using .filter() on en existing queryset, this metadata is not exposed. Would be helpful to access the metadata here as it could contain data not available in the queryset models or the result of some expensive calculation performed during indexing.

Related tags
Full text search for flask.

flask-msearch Installation To install flask-msearch: pip install flask-msearch # when MSEARCH_BACKEND = "whoosh" pip install whoosh blinker # when MSE

Sep 2, 2022
GitScanner is a script to make it easy to search for Exposed Git through an advanced Google search.
GitScanner is a script to make it easy to search for Exposed Git through an advanced Google search.

GitScanner Legal disclaimer Usage of GitScanner for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to

Oct 28, 2022
A fast, efficiency python package for searching and getting search results with many different search engines

search A fast, efficiency python package for searching and getting search results with many different search engines. Installation To install the pack

Oct 6, 2022
Deep Image Search - AI-Based Image Search Engine
 Deep Image Search - AI-Based Image Search Engine

Deep Image Search is an AI-based image search engine that includes deep transfer learning features Extraction and tree-based vectorized search technique.

Dec 5, 2022
Search emails from a domain through search engines
Search emails from a domain through search engines

EmailFinder - search emails through Search Engines

Nov 29, 2022
Image search service based on imgsmlr extension of PostgreSQL. Support image search by image.
Image search service based on imgsmlr extension of PostgreSQL. Support image search by image.

imgsmlr-server Image search service based on imgsmlr extension of PostgreSQL. Support image search by image. This is a sample application of imgsmlr.

Nov 4, 2022
Reverse-ikea-image-search - A simple image of ikea search using jina.ai

IKEA Reverse Image Search This is a demo project to fetch ikea product images(IK

Mar 8, 2022
A play store search application programming interface ( API )

Play-Store-API A play store search application programming interface ( API ) Made with Python3

Oct 21, 2022
Modular search for Django

Haystack Author: Daniel Lindsley Date: 2013/07/28 Haystack provides modular search for Django. It features a unified, familiar API that allows you to

Dec 1, 2022
Google Project: Search and auto-complete sentences within given input text files, manipulating data with complex data-structures.
Google Project: Search and auto-complete sentences within given input text files, manipulating data with complex data-structures.

Auto-Complete Google Project In this project there is an implementation for one feature of Google's search engines - AutoComplete. Autocomplete, or wo

Jun 20, 2022
This project is a sample demo of Arxiv search related to AI/ML Papers built using Streamlit, sentence-transformers and Faiss.
This project is a sample demo of Arxiv search related to AI/ML Papers built using Streamlit, sentence-transformers and Faiss.

This project is a sample demo of Arxiv search related to AI/ML Papers built using Streamlit, sentence-transformers and Faiss.

Oct 30, 2022
txtai executes machine-learning workflows to transform data and build AI-powered semantic search applications.
txtai executes machine-learning workflows to transform data and build AI-powered semantic search applications.

txtai executes machine-learning workflows to transform data and build AI-powered semantic search applications.

Nov 30, 2022
🔍 Messages Searcher is make for search custom message in all channels in guild and dm.
🔍 Messages Searcher is make for search custom message in all channels in guild and dm.

?? Messages Searcher is make for search custom message in all channels in guild and dm.

Oct 29, 2022
Inverted index creation and query search mechanism on Wikipedia pages.

WikiPedia Search Engine Step 1 : Installing Requirements Install "stemming" module for python using pip. Step 2 : Parsing the Data To parse the data,

Nov 27, 2021
ForFinder is a search tool for folder and files
ForFinder is a search tool for folder and files

ForFinder is a search tool for folder and files. You can use that when you Source Code Analysis at your project's local files or other projects that you are download. Enter a root path and keyword to ForFinder.

Oct 25, 2022
Jina allows you to build deep learning-powered search-as-a-service in just minutes
Jina allows you to build deep learning-powered search-as-a-service in just minutes

Cloud-native neural search framework for any kind of data

Nov 30, 2022
Senginta is All in one Search Engine Scrapper for used by API or Python Module. It's Free!
Senginta is All in one Search Engine Scrapper for used by API or Python Module. It's Free!

Senginta is All in one Search Engine Scrapper. With traditional scrapping, Senginta can be powerful to get result from any Search Engine, and convert to Json. Now support only for Google Product Search Engine (GShop, GVideo and many too) and Baidu Search Engine.

Nov 21, 2022
Google Search Engine Results Pages (SERP) in locally, no API key, no signup required

Local SERP Google Search Engine Results Pages (SERP) in locally, no API key, no signup required Make sure the chromedriver and required package are in

Jun 29, 2021
A web search server for ParlAI, including Blenderbot2.
A web search server for ParlAI, including Blenderbot2.

Description A web search server for ParlAI, including Blenderbot2. Querying the server: The server reacting correctly: Uses html2text to strip the mar

Nov 30, 2022