-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0a75b06
commit e04bdfb
Showing
6 changed files
with
260 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,22 @@ | ||
# CHANGELOG | ||
|
||
# 0.0.8 | ||
|
||
Async Support! | ||
|
||
* We now use the `httpx` package to provide sync and asyn support. | ||
|
||
```python | ||
import asyncio | ||
|
||
from kaginawa import AsyncKaginawa | ||
|
||
|
||
async def amain(): | ||
kagi_client = AsyncKaginawa(...) | ||
res = await kagi_client.generate(...) | ||
print(res.output) | ||
|
||
if __name__ == "__main__": | ||
asyncio.run(amain()) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
from pkg_resources import parse_version | ||
|
||
__version__ = parse_version("0.0.7") | ||
__version__ = parse_version("0.0.8") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
import json | ||
import os | ||
from typing import Optional | ||
|
||
import httpx | ||
|
||
from kaginawa.exceptions import KaginawaError | ||
from kaginawa.models import ( | ||
KaginawaEnrichResponse, | ||
KaginawaFastGPTResponse, | ||
KaginawaSummarizationResponse, | ||
) | ||
|
||
|
||
class AsyncKaginawa: | ||
"""The main client to the Kagi API""" | ||
|
||
def __init__( | ||
self, | ||
token: Optional[str] = None, | ||
session: Optional[httpx.AsyncClient] = None, | ||
api_base: str = "https://kagi.com/api", | ||
): | ||
"""Create a new instance of the Kagi API wrapper. | ||
Parameters: | ||
token (Optional[str], optional): The API access token to authenticate | ||
httpx. If this value is unset the library will attempt to read the | ||
environment variable KAGI_API_KEY. If both are unset an exception will | ||
be raised. | ||
session (Optional[httpx.Client], optional): An optional `httpx` | ||
session object to use for sending HTTP httpx. Defaults to `None`. | ||
api_base (str, optional): The base URL for the Kagi API endpoint. | ||
Defaults to "https://kagi.com/api". | ||
""" | ||
|
||
try: | ||
token = token or os.environ["KAGI_API_KEY"] | ||
except KeyError as e: | ||
raise KaginawaError("Value for `token` not given and env KAGI_API_KEY is unset") from e | ||
|
||
self.token = token | ||
self.api_base = api_base | ||
|
||
if not session: | ||
session = httpx.AsyncClient() | ||
|
||
self.session = session | ||
|
||
self.session.headers = {"Authorization": f"Bot {self.token}"} | ||
|
||
async def close(self): | ||
return await self.session.aclose() | ||
|
||
async def generate(self, query: str, cache: Optional[bool] = None): | ||
"""Generate a FastGPT response from a text query. | ||
Parameters: | ||
query (str): The prompt to send to FastGPT. | ||
cache (Optional[bool], optional): Allow cached responses. Defaults to `None`. | ||
Returns: | ||
KaginawaFastGPTResponse: A model representing the response. | ||
""" | ||
try: | ||
optional_params = {} | ||
|
||
if cache is not None: | ||
optional_params["cache"] = cache | ||
|
||
res = await self.session.post( | ||
f"{self.api_base}/v0/fastgpt", | ||
json={ | ||
"query": query, | ||
**optional_params, | ||
}, | ||
) | ||
|
||
res.raise_for_status() | ||
|
||
raw_response = res.json() | ||
print(json.dumps(raw_response, indent=2, sort_keys=True)) | ||
except httpx.HTTPError as e: | ||
raise KaginawaError("Error calling /v0/fastgpt") from e | ||
|
||
return KaginawaFastGPTResponse.from_raw(raw_response) | ||
|
||
async def enrich_web(self, query: str): | ||
"""Query the Teclis index for relevant web results for a given query. | ||
Parameters: | ||
query (str): The search query. | ||
Returns: | ||
KaginawaEnrichWebResponse: A model representing the response. | ||
""" | ||
|
||
try: | ||
res = await self.session.get( | ||
f"{self.api_base}/v0/enrich/web", | ||
params={"q": query}, | ||
) | ||
res.raise_for_status() | ||
|
||
raw_response = res.json() | ||
except httpx.HTTPError as e: | ||
raise KaginawaError("Error calling /v0/enrich/web") from e | ||
|
||
return KaginawaEnrichResponse.from_raw(raw_response).results[0] | ||
|
||
async def enrich_news(self, query: str): | ||
"""Query the Teclis index for relevant web results for a given query. | ||
Parameters: | ||
query (str): The search query. | ||
Returns: | ||
KaginawaEnrichWebResponse: A model representing the response. | ||
""" | ||
|
||
try: | ||
res = await self.session.get( | ||
f"{self.api_base}/v0/enrich/news", | ||
params={"q": query}, | ||
) | ||
res.raise_for_status() | ||
|
||
raw_response = res.json() | ||
except httpx.HTTPError as e: | ||
raise KaginawaError("Error calling /v0/enrich/web") from e | ||
|
||
return KaginawaEnrichResponse.from_raw(raw_response).results[0] | ||
|
||
async def summarize( | ||
self, | ||
url: Optional[str] = None, | ||
text: Optional[str] = None, | ||
engine: Optional[str] = None, | ||
summary_type: Optional[str] = None, | ||
target_language: Optional[str] = None, | ||
cache: Optional[bool] = None, | ||
): | ||
"""Summarize a URL or text snippet. | ||
Parameters: | ||
url (Optional[str], optional): The URL to summarize. This option is exclusive | ||
with the `text` parameter. Defaults to `None`. | ||
text (Optional[str], optional): The text snippet to summarize. This option is | ||
exclusive with the `url` parameter. Defaults to `None`. | ||
engine (Optional[str], optional): The summarization engine to use. There is a | ||
helper enum `KaginawaSummarizationEngine` with the valid values for this | ||
parameter. Defaults to `None`. | ||
summary_type (Optional[str], optional): The 'kind' of summary you would like | ||
the model to use. There is a helper enum KaginawaSummaryType with the valid | ||
values for this parameter. Defaults to `None`. | ||
target_language: (Optional[str], optional): The language CODE (eg. EN, ZH, FR) | ||
corresponding to the language you would like the summary in. See | ||
https://help.kagi.com/kagi/api/summarizer.html for valid language codes. | ||
Defaults to `None`. | ||
cache (Optional[bool], optional): Allow cached responses. Defaults to `None`. | ||
Returns: | ||
KaginawaSummarizationResponse: A model representing the response. | ||
""" | ||
try: | ||
params = {} | ||
|
||
if not (bool(url) ^ bool(text)): | ||
raise KaginawaError("You must provide exactly one of 'url' or 'text'.") | ||
|
||
if url: | ||
params["url"] = url | ||
|
||
if text: | ||
params["text"] = text | ||
|
||
if engine: | ||
params["engine"] = engine | ||
|
||
if summary_type: | ||
params["summary_type"] = summary_type | ||
|
||
if target_language: | ||
params["target_language"] = target_language | ||
|
||
if cache is not None: | ||
params["cache"] = cache | ||
|
||
res = await self.session.post( | ||
f"{self.api_base}/v0/summarize", | ||
data=params, | ||
) | ||
|
||
raw_response = res.json() | ||
except httpx.HTTPError as e: | ||
raise KaginawaError("Error calling /v0/summarize") from e | ||
|
||
return KaginawaSummarizationResponse.from_raw(raw_response) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
requests>=2 | ||
httpx>=0.25.0 |