Skip to content

Commit

Permalink
Upd package for MeiliSearch v0.11 (#88)
Browse files Browse the repository at this point in the history
* Upd version

* Add method to use faceting sub routes (#90)

* Remane apikey into api_key (#93)

* Implement faceting in search (#94)

* Implement faceting in search

* Upd test

* Clear all indexes before starting tests in a certain context (#95)

* Clear all indexes before starting tests in a certain context

* Update meilisearch/tests/__init__.py

Co-authored-by: Samuel Jimenez <[email protected]>

Co-authored-by: Samuel Jimenez <[email protected]>

* Upd version

* Add method to use faceting sub routes (#90)

* Remane apikey into api_key (#93)

* Implement faceting in search (#94)

* Implement faceting in search

* Upd test

* Fix parameter default value (#97)

* Add test with multiple facetFilters (#98)

* Change create_index prototype (#99)

* Change create_index prototype

* Update meilisearch/client.py

Co-authored-by: cvermand <[email protected]>

* Update meilisearch/index.py

Co-authored-by: cvermand <[email protected]>

Co-authored-by: cvermand <[email protected]>

Co-authored-by: Samuel Jimenez <[email protected]>
Co-authored-by: cvermand <[email protected]>
  • Loading branch information
3 people authored Jun 15, 2020
1 parent 04bfb17 commit f61935e
Show file tree
Hide file tree
Showing 19 changed files with 276 additions and 56 deletions.
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
- [⚙️ Development Workflow](#️-development-workflow)
- [Install dependencies](#install-dependencies)
- [Tests and Linter](#tests-and-linter)
- [Want to debug?](#want-to-debug)
- [Release](#release)

## 🔧 Installation
Expand Down Expand Up @@ -66,8 +67,8 @@ NB: you can also download MeiliSearch from **Homebrew** or **APT**.
import meilisearch

client = meilisearch.Client('http://127.0.0.1:7700', 'masterKey')
index = client.create_index(uid='books') # If your index does not exist
index = client.get_index('books') # If you already created your index
index = client.create_index('books') # If your index does not exist
index = client.get_index('books') # If you already created your index

documents = [
{ 'book_id': 123, 'title': 'Pride and Prejudice' },
Expand Down Expand Up @@ -106,7 +107,7 @@ Output:
## 🤖 Compatibility with MeiliSearch

This package is compatible with the following MeiliSearch versions:
- `v0.10.X`
- `v0.11.X`

## 🎬 Examples

Expand All @@ -117,9 +118,9 @@ You can check out [the API documentation](https://docs.meilisearch.com/reference
#### Create an index <!-- omit in toc -->
```python
# Create an index
client.create_index(uid='books')
client.create_index('books')
# Create an index and give the primary-key
client.create_index(uid='books', primary_key='book_id')
client.create_index('books', {'primaryKey': 'book_id'})

This comment has been minimized.

Copy link
@vipinsaini1989

vipinsaini1989 Jun 23, 2020

constantly getting error while using that method. Fixed using
client.create_index(uid='books',options={'primaryKey':'book_id'})

ref: #99

This comment has been minimized.

Copy link
@curquiza

curquiza Jun 23, 2020

Author Member

Hello @vipinsaini1989!
Are you sure you are using the v0.11.0 of meilisearch-python?

I'm not able to reproduce your error.

client.create_index(uid='books',options={'primaryKey':'book_id'})
and
client.create_index('books', {'primaryKey':'book_id'})
both work.

(but not client.create_index(uid='books', {'primaryKey':'book_id'}))

```

#### List all indexes <!-- omit in toc -->
Expand Down Expand Up @@ -253,6 +254,20 @@ $ pipenv run pytest meilisearch
$ pipenv run pylint meilisearch
```

### Want to debug?

Import `pdb` in your file and use it:

```python
import pdb

...
pdb.set_trace() # create a break point
...
```

More information [about pdb](https://docs.python.org/3/library/pdb.html).

### Release

MeiliSearch tools follow the [Semantic Versioning Convention](https://semver.org/).
Expand Down
30 changes: 20 additions & 10 deletions datasets/small_movies.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
"title": "Shazam!",
"poster": "https://image.tmdb.org/t/p/w1280/xnopI5Xtky18MPhK40cZAGAOVeV.jpg",
"overview": "A boy is given the ability to become an adult superhero in times of need with a single magic word.",
"release_date": 1553299200
"release_date": 1553299200,
"genre": "action"
},
{
"id": "299537",
"title": "Captain Marvel",
"poster": "https://image.tmdb.org/t/p/w1280/AtsgWhDnHTq68L0lLsUrCnM7TjG.jpg",
"overview": "The story follows Carol Danvers as she becomes one of the universe’s most powerful heroes when Earth is caught in the middle of a galactic war between two alien races. Set in the 1990s, Captain Marvel is an all-new adventure from a previously unseen period in the history of the Marvel Cinematic Universe.",
"release_date": 1551830400
"release_date": 1551830400,
"genre": "action"
},
{
"id": "522681",
Expand All @@ -25,7 +27,8 @@
"title": "How to Train Your Dragon: The Hidden World",
"poster": "https://image.tmdb.org/t/p/w1280/xvx4Yhf0DVH8G4LzNISpMfFBDy2.jpg",
"overview": "As Hiccup fulfills his dream of creating a peaceful dragon utopia, Toothless’ discovery of an untamed, elusive mate draws the Night Fury away. When danger mounts at home and Hiccup’s reign as village chief is tested, both dragon and rider must make impossible decisions to save their kind.",
"release_date": 1546473600
"release_date": 1546473600,
"genre": "cartoon"
},
{
"id": "450465",
Expand All @@ -46,14 +49,16 @@
"title": "Dumbo",
"poster": "https://image.tmdb.org/t/p/w1280/279PwJAcelI4VuBtdzrZASqDPQr.jpg",
"overview": "A young elephant, whose oversized ears enable him to fly, helps save a struggling circus, but when the circus plans a new venture, Dumbo and his friends discover dark secrets beneath its shiny veneer.",
"release_date": 1553644800
"release_date": 1553644800,
"genre": "cartoon"
},
{
"id": "299536",
"title": "Avengers: Infinity War",
"poster": "https://image.tmdb.org/t/p/w1280/7WsyChQLEftFiDOVTGkv3hFpyyt.jpg",
"overview": "As the Avengers and their allies have continued to protect the world from threats too large for any one hero to handle, a new danger has emerged from the cosmic shadows: Thanos. A despot of intergalactic infamy, his goal is to collect all six Infinity Stones, artifacts of unimaginable power, and use them to inflict his twisted will on all of reality. Everything the Avengers have fought for has led up to this moment - the fate of Earth and existence itself has never been more uncertain.",
"release_date": 1524618000
"release_date": 1524618000,
"genre": "action"
},
{
"id": "458723",
Expand All @@ -74,21 +79,24 @@
"title": "Cars",
"poster": "https://image.tmdb.org/t/p/w1280/5damnMcRFKSjhCirgX3CMa88MBj.jpg",
"overview": "Lightning McQueen, a hotshot rookie race car driven to succeed, discovers that life is about the journey, not the finish line, when he finds himself unexpectedly detoured in the sleepy Route 66 town of Radiator Springs. On route across the country to the big Piston Cup Championship in California to compete against two seasoned pros, McQueen gets to know the town's offbeat characters.",
"release_date": 1149728400
"release_date": 1149728400,
"genre": "cartoon"
},
{
"id": "299534",
"title": "Avengers: Endgame",
"poster": "https://image.tmdb.org/t/p/w1280/dHjLaIUHXcMBt7YxK1TKWK1end9.jpg",
"overview": "After the devastating events of Avengers: Infinity War, the universe is in ruins due to the efforts of the Mad Titan, Thanos. With the help of remaining allies, the Avengers must assemble once more in order to undo Thanos' actions and restore order to the universe once and for all, no matter what consequences may be in store.",
"release_date": 1556067600
"release_date": 1556067600,
"genre": "action"
},
{
"id": "324857",
"title": "Spider-Man: Into the Spider-Verse",
"poster": "https://image.tmdb.org/t/p/w1280/iiZZdoQBEYBv6id8su7ImL0oCbD.jpg",
"overview": "Miles Morales is juggling his life between being a high school student and being a spider-man. When Wilson 'Kingpin' Fisk uses a super collider, others from across the Spider-Verse are transported to this dimension.",
"release_date": 1544140800
"release_date": 1544140800,
"genre": "action"
},
{
"id": "157433",
Expand Down Expand Up @@ -137,7 +145,8 @@
"title": "Aquaman",
"poster": "https://image.tmdb.org/t/p/w1280/5Kg76ldv7VxeX9YlcQXiowHgdX6.jpg",
"overview": "Once home to the most advanced civilization on Earth, Atlantis is now an underwater kingdom ruled by the power-hungry King Orm. With a vast army at his disposal, Orm plans to conquer the remaining oceanic people and then the surface world. Standing in his way is Arthur Curry, Orm's half-human, half-Atlantean brother and true heir to the throne.",
"release_date": 1544140800
"release_date": 1544140800,
"genre": "action"
},
{
"id": "512196",
Expand Down Expand Up @@ -186,7 +195,8 @@
"title": "Fantastic Beasts: The Crimes of Grindelwald",
"poster": "https://image.tmdb.org/t/p/w1280/fMMrl8fD9gRCFJvsx0SuFwkEOop.jpg",
"overview": "Gellert Grindelwald has escaped imprisonment and has begun gathering followers to his cause—elevating wizards above all non-magical beings. The only one capable of putting a stop to him is the wizard he once called his closest friend, Albus Dumbledore. However, Dumbledore will need to seek help from the wizard who had thwarted Grindelwald once before, his former student Newt Scamander, who agrees to help, unaware of the dangers that lie ahead. Lines are drawn as love and loyalty are tested, even among the truest friends and family, in an increasingly divided wizarding world.",
"release_date": 1542153600
"release_date": 1542153600,
"genre": "fantasy"
},
{
"id": "399579",
Expand Down
2 changes: 1 addition & 1 deletion meilisearch/_httprequests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class HttpRequests:
def __init__(self, config):
self.config = config
self.headers = {
'X-Meili-Api-Key': self.config.apikey,
'X-Meili-Api-Key': self.config.api_key,
'Content-Type': 'application/json'
}

Expand Down
13 changes: 6 additions & 7 deletions meilisearch/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self, url, apiKey=None):
self.config = Config(url, apiKey)
self.http = HttpRequests(self.config)

def create_index(self, uid, primary_key=None, name=None):
def create_index(self, uid, options=None):
"""Create an index.
If the argument `uid` isn't passed in, it will be generated
Expand All @@ -35,10 +35,9 @@ def create_index(self, uid, primary_key=None, name=None):
----------
uid: str
UID of the index
primary_key: str, optional
Attribute used as unique document identifier
name: str, optional
Name of the index
options: dict, optional
Options passed during index creation (ex: primaryKey)
Returns
-------
index : Index
Expand All @@ -48,8 +47,8 @@ def create_index(self, uid, primary_key=None, name=None):
HTTPError
In case of any other error found here https://docs.meilisearch.com/references/#errors-status-code
"""
index = Index(self.config, uid=uid)
index.create(self.config, uid=uid, primary_key=primary_key, name=name)
index = Index(self.config, uid)
index.create(self.config, uid, options)
return index

def get_indexes(self):
Expand Down
7 changes: 4 additions & 3 deletions meilisearch/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@ class Paths():
stop_words = 'stop-words'
synonyms = 'synonyms'
accept_new_fields = 'accept-new-fields'
attributes_for_faceting = 'attributes-for-faceting'

def __init__(self, url, apikey=None):
def __init__(self, url, api_key=None):
"""
Parameters
----------
url : str
The url to the MeiliSearch API (ex: http://localhost:7700)
apikey : str
api_key : str
The optional API key to access MeiliSearch
"""

self.url = url
self.apikey = apikey
self.api_key = api_key
self.paths = self.Paths()
81 changes: 65 additions & 16 deletions meilisearch/index.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import urllib
from datetime import datetime
from time import sleep
Expand Down Expand Up @@ -83,13 +84,15 @@ def get_primary_key(self):
return self.info()['primaryKey']

@staticmethod
def create(config, **body):
def create(config, uid, options=None):
"""Create an index.
Parameters
----------
body: **kwargs
Accepts uid, name and primaryKey as parameter.
uid: str
UID of the index
options: dict, optional
Options passed during index creation (ex: primaryKey)
Returns
-------
Expand All @@ -100,16 +103,9 @@ def create(config, **body):
HTTPError
In case of any error found here https://docs.meilisearch.com/references/#errors-status-code
"""
payload = {}
uid = body.get('uid', None)
if uid is not None:
payload['uid'] = uid
name = body.get('name', None)
if name is not None:
payload['name'] = name
primary_key = body.get('primary_key', None)
if primary_key is not None:
payload['primaryKey'] = primary_key
if options is None:
options = {}
payload = {'uid': uid, **options}
return HttpRequests(config).post(config.paths.index, payload)

@staticmethod
Expand Down Expand Up @@ -243,13 +239,18 @@ def search(self, query, opt_params=None):
results: `dict`
Dictionnary with hits, offset, limit, processingTime and initial query
"""
# Query parameters parsing
if opt_params is None:
opt_params = {}
search_param = {'q': query}
for key in opt_params:
if isinstance(opt_params[key], list):
if key in ('facetsDistribution', 'facetFilters'):
opt_params[key] = json.dumps(opt_params[key])
elif isinstance(opt_params[key], list):
opt_params[key] = ','.join(opt_params[key])
params = {**search_param, **opt_params}
params = {
'q': query,
**opt_params
}
return self.http.get(
'{}/{}/{}?{}'.format(
self.config.paths.index,
Expand Down Expand Up @@ -814,6 +815,54 @@ def update_accept_new_fields(self, body):
body
)

# ATTRIBUTES FOR FACETING SUB-ROUTES

def get_attributes_for_faceting(self):
"""
Get attributes for faceting of an index
Returns
----------
settings: `list`
List containing the attributes for faceting of the index
"""
return self.http.get(
self.__settings_url_for(self.config.paths.attributes_for_faceting)
)

def update_attributes_for_faceting(self, body):
"""
Update attributes for faceting of an index
Parameters
----------
body: `list`
List containing the attributes for faceting
Returns
----------
update: `dict`
Dictionnary containing an update id to track the action:
https://docs.meilisearch.com/references/updates.html#get-an-update-status
"""
return self.http.post(
self.__settings_url_for(self.config.paths.attributes_for_faceting),
body
)

def reset_attributes_for_faceting(self):
"""Reset attributes for faceting of an index to default values
Returns
----------
update: `dict`
Dictionnary containing an update id to track the action:
https://docs.meilisearch.com/references/updates.html#get-an-update-status
"""
return self.http.delete(
self.__settings_url_for(self.config.paths.attributes_for_faceting),
)

def __settings_url_for(self, sub_route):
return '{}/{}/{}/{}'.format(
self.config.paths.index,
Expand Down
5 changes: 5 additions & 0 deletions meilisearch/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
MASTER_KEY = 'masterKey'
BASE_URL = 'http://127.0.0.1:7700'

def clear_all_indexes(client):
indexes = client.get_indexes()
for index in indexes:
client.get_index(index['uid']).delete()
3 changes: 2 additions & 1 deletion meilisearch/tests/client/test_client_stats_meilisearch.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import meilisearch
from meilisearch.tests import BASE_URL, MASTER_KEY
from meilisearch.tests import BASE_URL, MASTER_KEY, clear_all_indexes

class TestStats:

Expand All @@ -10,6 +10,7 @@ class TestStats:
index2 = None

def setup_class(self):
clear_all_indexes(self.client)
self.index = self.client.create_index(uid='indexUID')
self.index_2 = self.client.create_index(uid='indexUID2')

Expand Down
3 changes: 2 additions & 1 deletion meilisearch/tests/client/test_client_sysinfo_meilisearch.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import meilisearch
from meilisearch.tests import BASE_URL, MASTER_KEY
from meilisearch.tests import BASE_URL, MASTER_KEY, clear_all_indexes

class TestSysInfo:

Expand All @@ -9,6 +9,7 @@ class TestSysInfo:
index = None

def setup_class(self):
clear_all_indexes(self.client)
self.index = self.client.create_index(uid='indexUID')

def teardown_class(self):
Expand Down
3 changes: 2 additions & 1 deletion meilisearch/tests/client/test_client_version_meilisearch.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import meilisearch
from meilisearch.tests import BASE_URL, MASTER_KEY
from meilisearch.tests import BASE_URL, MASTER_KEY, clear_all_indexes

class TestVersion:
""" TESTS: version route """
Expand All @@ -8,6 +8,7 @@ class TestVersion:
index = None

def setup_class(self):
clear_all_indexes(self.client)
self.index = self.client.create_index(uid='indexUID')

def teardown_class(self):
Expand Down
Loading

0 comments on commit f61935e

Please sign in to comment.