mirror of
https://github.com/hwchase17/langchain
synced 2024-11-10 01:10:59 +00:00
54adcd9e82
We add a tool and retriever for the [AskNews](https://asknews.app) platform with example notebooks. The retriever can be invoked with: ```py from langchain_community.retrievers import AskNewsRetriever retriever = AskNewsRetriever(k=3) retriever.invoke("impact of fed policy on the tech sector") ``` To retrieve 3 documents in then news related to fed policy impacts on the tech sector. The included notebook also includes deeper details about controlling filters such as category and time, as well as including the retriever in a chain. The tool is quite interesting, as it allows the agent to decide how to obtain the news by forming a query and deciding how far back in time to look for the news: ```py from langchain_community.tools.asknews import AskNewsSearch from langchain import hub from langchain.agents import AgentExecutor, create_openai_functions_agent from langchain_openai import ChatOpenAI tool = AskNewsSearch() instructions = """You are an assistant.""" base_prompt = hub.pull("langchain-ai/openai-functions-template") prompt = base_prompt.partial(instructions=instructions) llm = ChatOpenAI(temperature=0) asknews_tool = AskNewsSearch() tools = [asknews_tool] agent = create_openai_functions_agent(llm, tools, prompt) agent_executor = AgentExecutor( agent=agent, tools=tools, verbose=True, ) agent_executor.invoke({"input": "How is the tech sector being affected by fed policy?"}) ``` --------- Co-authored-by: Emre <e@emre.pm>
116 lines
3.5 KiB
Python
116 lines
3.5 KiB
Python
"""Util that calls AskNews api."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime, timedelta
|
|
from typing import Any, Dict, Optional
|
|
|
|
from langchain_core.pydantic_v1 import BaseModel, Extra, root_validator
|
|
from langchain_core.utils import get_from_dict_or_env
|
|
|
|
|
|
class AskNewsAPIWrapper(BaseModel):
|
|
"""Wrapper for AskNews API."""
|
|
|
|
asknews_sync: Any #: :meta private:
|
|
asknews_async: Any #: :meta private:
|
|
asknews_client_id: Optional[str] = None
|
|
"""Client ID for the AskNews API."""
|
|
asknews_client_secret: Optional[str] = None
|
|
"""Client Secret for the AskNews API."""
|
|
|
|
class Config:
|
|
"""Configuration for this pydantic object."""
|
|
|
|
extra = Extra.forbid
|
|
|
|
@root_validator()
|
|
def validate_environment(cls, values: Dict) -> Dict:
|
|
"""Validate that api credentials and python package exists in environment."""
|
|
|
|
asknews_client_id = get_from_dict_or_env(
|
|
values, "asknews_client_id", "ASKNEWS_CLIENT_ID"
|
|
)
|
|
asknews_client_secret = get_from_dict_or_env(
|
|
values, "asknews_client_secret", "ASKNEWS_CLIENT_SECRET"
|
|
)
|
|
|
|
try:
|
|
import asknews_sdk
|
|
|
|
except ImportError:
|
|
raise ImportError(
|
|
"AskNews python package not found. "
|
|
"Please install it with `pip install asknews`."
|
|
)
|
|
|
|
an_sync = asknews_sdk.AskNewsSDK(
|
|
client_id=asknews_client_id,
|
|
client_secret=asknews_client_secret,
|
|
scopes=["news"],
|
|
)
|
|
an_async = asknews_sdk.AsyncAskNewsSDK(
|
|
client_id=asknews_client_id,
|
|
client_secret=asknews_client_secret,
|
|
scopes=["news"],
|
|
)
|
|
|
|
values["asknews_sync"] = an_sync
|
|
values["asknews_async"] = an_async
|
|
values["asknews_client_id"] = asknews_client_id
|
|
values["asknews_client_secret"] = asknews_client_secret
|
|
|
|
return values
|
|
|
|
def search_news(
|
|
self, query: str, max_results: int = 10, hours_back: int = 0
|
|
) -> str:
|
|
"""Search news in AskNews API synchronously."""
|
|
if hours_back > 48:
|
|
method = "kw"
|
|
historical = True
|
|
start = int((datetime.now() - timedelta(hours=hours_back)).timestamp())
|
|
stop = int(datetime.now().timestamp())
|
|
else:
|
|
historical = False
|
|
method = "nl"
|
|
start = None
|
|
stop = None
|
|
|
|
response = self.asknews_sync.news.search_news(
|
|
query=query,
|
|
n_articles=max_results,
|
|
method=method,
|
|
historical=historical,
|
|
start_timestamp=start,
|
|
end_timestamp=stop,
|
|
return_type="string",
|
|
)
|
|
return response.as_string
|
|
|
|
async def asearch_news(
|
|
self, query: str, max_results: int = 10, hours_back: int = 0
|
|
) -> str:
|
|
"""Search news in AskNews API asynchronously."""
|
|
if hours_back > 48:
|
|
method = "kw"
|
|
historical = True
|
|
start = int((datetime.now() - timedelta(hours=hours_back)).timestamp())
|
|
stop = int(datetime.now().timestamp())
|
|
else:
|
|
historical = False
|
|
method = "nl"
|
|
start = None
|
|
stop = None
|
|
|
|
response = await self.asknews_async.news.search_news(
|
|
query=query,
|
|
n_articles=max_results,
|
|
method=method,
|
|
historical=historical,
|
|
start_timestamp=start,
|
|
end_timestamp=stop,
|
|
return_type="string",
|
|
)
|
|
return response.as_string
|