Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add classmethod for initializing Sinequa class #18

Merged
merged 4 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 29 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,59 @@
# Pynequa
A python library to handle communication with Sinequa REST API.
A python library to handle communication with Sinequa REST API.

[![Documentation Status](https://readthedocs.org/projects/pynequa/badge/?version=latest)](https://pynequa.readthedocs.io/en/latest/?badge=latest)
![Build](https://github.com/NASA-IMPACT/pynequa/actions/workflows/pkg_build_check.yml/badge.svg)

> Sinequa is an enterprise search tool. It provides a cognitive search and analytics platform that helps organizations gain insights from their structured and unstructured data spread across various sources, including databases, documents, emails, websites, and more.

## Installation
## Installation

```
$ pip install pynequa
```

## Example Usage
```
import pynequa
import pynequa
from pynequa.models import QueryParams

# provide following config parameters
# provide following config parameters
config = {
"base_url": "",
"app_name": "",
"base_url": "",
"app_name": "",
"access_token":"",
"query_name": ""
}

#initialize a Sinequa connector instance
sinequa=pynequa.Sinequa(config=config)
# initialize a Sinequa connector instance
sinequa=pynequa.Sinequa.from_config(config)

# OR
# you can directly instantiate Sinequa using
sinequa = pynequa.Sinequa(
access_token: config["access_token"],
base_url: config["base_url"],
app_name: config["app_name"],
query_name: config["query_name"],
)

params = QueryParams()
params.search_text = "<your_search_text>"
..... #other params
# other params

#perform a search query operation
# perform a search query operation
results=sinequa.search_query(params)
```


## Feature Roadmap
Implement following REST endpoints to manage requests with Sinequa API.
## Feature Roadmap
Implement following REST endpoints to manage requests with Sinequa API.




**Search Endpoints:**
- [x] search.app
- [x] search.app
- [x] search.dataset
- [x] search.query
- [x] queryintent
Expand All @@ -64,12 +73,12 @@ Implement following REST endpoints to manage requests with Sinequa API.
- [ ] search.suggest
- [ ] search.custom
- [ ] suggestField
- [ ] engine.sql
- [ ] engine.sql

**Indexing Endpoints**
- [ ] indexing.collection
- [ ] indexing.customCollection
- [ ] indexing.partition
- [ ] indexing.partition

**Operating Task Endpoints**
- [ ] operation.actionStatus
Expand All @@ -83,15 +92,15 @@ Implement following REST endpoints to manage requests with Sinequa API.

**General Endpoints**
- [ ] audit.notify
- [ ] admin.config
- [ ] dev.plugin
- [ ] multi
- [ ] admin.config
- [ ] dev.plugin
- [ ] multi

## Development
Check [DEVELOPERS GUIDE](DEVELOPMENT.md) for details.
Check [DEVELOPERS GUIDE](DEVELOPMENT.md) for details.
## Contributing

When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the authors of this repository before making a change.
When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the authors of this repository before making a change.

## License

Expand Down
20 changes: 11 additions & 9 deletions pynequa/api/api.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import requests
import os
from typing import Dict

import os
import requests


class API:
'''
API Class handles all HTTP Requests
API Class handles all HTTP Requests

Attributes:
Attributes:
base_url(string): REST API base URL for Sinequa instance
access_token(string): token for Sinequa authentication
'''
base_url: str
access_token: str

def __init__(self, config) -> None:
self.access_token = config["access_token"]
self.base_url = config["base_url"]
def __init__(self, access_token: str, base_url: str) -> None:
if not access_token or not base_url:
raise ValueError("access_token and base_url must not be empty")

self.access_token = access_token
self.base_url = base_url

def _get_headers(self) -> Dict:
headers = {
Expand Down
46 changes: 39 additions & 7 deletions pynequa/core.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from pynequa.api import API
from __future__ import annotations
from typing import Optional, List, Dict

from pynequa.api import API
from pynequa.models import QueryParams, TreeParams


Expand All @@ -8,17 +10,47 @@ class Sinequa(API):
Sinequa API Client for Python

Attributes:
access_token(str): authentication token for Sinequa
base_url(str): base URL for hosted Sinequa instance
app_name(str): name of Sinequa app
query_name(str): name of search query web service
'''
app_name: str
query_name: str

def __init__(self, config: Dict) -> None:
super().__init__(config)
self.app_name = config["app_name"] # name of application
def __init__(
self,
access_token: str,
base_url: str,
app_name: str = "vanilla-search",
query_name: str = "query",
) -> None:
super().__init__(access_token=access_token, base_url=base_url)
NISH1001 marked this conversation as resolved.
Show resolved Hide resolved
self.app_name = app_name # name of application
# name of search query web service
self.query_name = config["query_name"]
self.query_name = query_name

@classmethod
def from_config(cls, cfg: Dict) -> Sinequa:
'''
This method creates an instance of Sinequa class from a configuration
dictionary.

Args:
cfg (Dict): A dictionary containing configuration parameters.
It should include the following keys:
- "access_token": A valid access token for authentication.
- "base_url": The base URL for the Sinequa API.
- "app_name": Name of the Sinequa application.
- "query_name": Name of the search query service.

Returns:
Sinequa: An instance of Sinequa class initialized with given configuration
'''
return cls(
access_token=cfg["access_token"],
base_url=cfg["base_url"],
app_name=cfg["app_name"],
query_name=cfg["query_name"],
)

@staticmethod
def _prepare_kwargs(payload: Dict, kwargs: Dict) -> Dict:
Expand Down
4 changes: 2 additions & 2 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def test_get(self, mock_get):
mock_get.return_value.status_code = 200
mock_get.return_value.json.return_value = sample_response

api = API(mock_config)
api = API(mock_config["access_token"], mock_config["base_url"])
resp = api.get("search.query")

self.assertEqual(resp.status_code, 200)
Expand All @@ -29,7 +29,7 @@ def test_post(self, mock_post):
mock_post.return_value.status_code = 200
mock_post.return_value.json.return_value = sample_response

api = API(mock_config)
api = API(mock_config["access_token"], mock_config["base_url"])
endpoint = "search.query"
payload = {
"app": "sba",
Expand Down
39 changes: 37 additions & 2 deletions tests/test_search_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,34 @@


class TestSinequaSearchQuery(unittest.TestCase):
"""
A unittest class for testing Sinequa search queries.

This class contains two test methods that evaluate the behavior of Sinequa
search queries under different authentication scenarios.

Test Methods:
- `test_search_query_without_auth`: Tests a search query without
authentication. It creates a Sinequa instance using provided
configuration, sends a search query, and checks the error code in
the response.

- `test_search_query_with_auth`: Tests a search query with
authentication. It retrieves an access token from environment
variables, creates a Sinequa instance using provided configuration,
sends a search query, and checks the method result in the response.

"""

def test_search_query_without_auth(self):
"""
Test a search query without authentication.

This test case creates a Sinequa instance with the given configuration,
sets up query parameters, sends a search query, and asserts that the
expected error code is returned in the response.
"""

config = {
"base_url": base_url,
"app_name": app_name,
Expand All @@ -19,11 +46,19 @@ def test_search_query_without_auth(self):
query_params = QueryParams()
query_params.search_text = "NASA"

sinequa = Sinequa(config=config)
sinequa = Sinequa.from_config(config)
resp = sinequa.search_query(query_params=query_params)
self.assertEqual(resp["ErrorCode"], 6)

def test_search_query_with_auth(self):
"""
Test a search query with authentication.

This test case retrieves an access token from environment variables,
creates a Sinequa instance with the given configuration, sets up query
parameters, sends a search query, and asserts that the method result in
the response is as expected.
"""
access_token = os.environ.get("SINEQUA_ACCESS_TOKEN")
config = {
"base_url": base_url,
Expand All @@ -34,7 +69,7 @@ def test_search_query_with_auth(self):
query_params = QueryParams()
query_params.search_text = "NASA"

sinequa = Sinequa(config=config)
sinequa = Sinequa.from_config(config)
resp = sinequa.search_query(query_params=query_params)
self.assertEqual(resp["methodresult"], "ok")

Expand Down