diff --git a/edenai_apis/api_keys/linkup_settings_template.json b/edenai_apis/api_keys/linkup_settings_template.json new file mode 100644 index 00000000..d24eaefd --- /dev/null +++ b/edenai_apis/api_keys/linkup_settings_template.json @@ -0,0 +1,3 @@ +{ + "api_key": "" +} diff --git a/edenai_apis/apis/__init__.py b/edenai_apis/apis/__init__.py index 32cdd7ab..c7c4071b 100644 --- a/edenai_apis/apis/__init__.py +++ b/edenai_apis/apis/__init__.py @@ -24,6 +24,7 @@ from .google import GoogleApi from .hireability import HireabilityApi from .klippa import KlippaApi +from .linkup import LinkupApi from .lovoai import LovoaiApi from .meaningcloud import MeaningcloudApi from .meta import MetaApi diff --git a/edenai_apis/apis/linkup/__init__.py b/edenai_apis/apis/linkup/__init__.py new file mode 100644 index 00000000..72aed1ac --- /dev/null +++ b/edenai_apis/apis/linkup/__init__.py @@ -0,0 +1 @@ +from .linkup_api import LinkupApi \ No newline at end of file diff --git a/edenai_apis/apis/linkup/info.json b/edenai_apis/apis/linkup/info.json new file mode 100644 index 00000000..178844ae --- /dev/null +++ b/edenai_apis/apis/linkup/info.json @@ -0,0 +1,11 @@ +{ + "text": { + "search": { + "version": "v1.0", + "constraints": { + "depth": ["standard", "deep"], + "outputType": ["searchResults", "sourcedAnswer"] + } + } + } +} diff --git a/edenai_apis/apis/linkup/linkup_api.py b/edenai_apis/apis/linkup/linkup_api.py new file mode 100644 index 00000000..0846b0c8 --- /dev/null +++ b/edenai_apis/apis/linkup/linkup_api.py @@ -0,0 +1,80 @@ +from edenai_apis.features.provider.provider_interface import ProviderInterface +from edenai_apis.loaders.loaders import load_provider, ProviderDataEnum +from edenai_apis.utils.exception import ProviderException +from linkup import LinkupClient +from typing import Dict, List, Optional +from pydantic import BaseModel + + +class SearchResult(BaseModel): + type: str + name: Optional[str] + url: Optional[str] + content: Optional[str] + + +class StandardizedResponse(BaseModel): + results: List[SearchResult] + + +class ApiResponse(BaseModel): + original_response: Dict + standardized_response: StandardizedResponse + + +class LinkupApi(ProviderInterface): + provider_name = "linkup" + + def __init__(self, api_keys: Dict = {}): + self.api_settings = load_provider( + ProviderDataEnum.KEY, self.provider_name, api_keys=api_keys + ) + self.client = LinkupClient(api_key=self.api_settings["api_key"]) + + def text__search( + self, query: str, texts: list = None, similarity_metric: str = "cosine", model: str = None + ): + try: + output_type = "sourcedAnswer" + depth = "standard" + + if model and ":" in model: + params = model.split(":") + if len(params) >= 1: + output_type = params[0] + if len(params) >= 2: + depth = params[1] + + payload = { + "query": query, + "depth": depth, + "output_type": output_type + } + + response = self.client.search(**payload) + + if not hasattr(response, "sources") or not isinstance(response.sources, list): + raise ProviderException("Invalid format for response.sources; expected a list.") + + standardized_response = StandardizedResponse( + results=[ + SearchResult( + type="text", + name=getattr(source, "name", None), + url=getattr(source, "url", None), + content=getattr(source, "snippet", None), + ) + for source in response.sources + ] + ) + + return ApiResponse( + original_response={ + "answer": response.answer, + "sources": response.sources, + }, + standardized_response=standardized_response + ) + + except Exception as e: + raise ProviderException(f"Error during Linkup API call: {str(e)}") \ No newline at end of file diff --git a/edenai_apis/apis/linkup/outputs/text/search_output.json b/edenai_apis/apis/linkup/outputs/text/search_output.json new file mode 100644 index 00000000..749d813e --- /dev/null +++ b/edenai_apis/apis/linkup/outputs/text/search_output.json @@ -0,0 +1,66 @@ +{ + "original_response": { + "answer": "Rome, founded in 753 B.C. by Romulus, is a city rich in history and culture. It boasts various transport options, including two airports: Fiumicino (FCO) and Ciampino (CIA). For travelers, public transport is advised due to the city\u2019s hilly terrain and heavy tourist traffic. Rome offers a multitude of attractions such as the Colosseum and Vatican, with numerous resources available for insights and travel tips.", + "sources": [ + { + "name": "Rome guide - Rome travel guide", + "url": "https://www.travelplan.it/pdf/rome_guide.pdf", + "snippet": "The founding of Rome is enveloped in myth: the story goes that the first city center sprang up in 753 B.C. on the Palatine hill, built by Romulus after he had killed his twin brother Remus." + }, + { + "name": "TRAVEL GUIDE MAGAZINE - mrdanielrowland.com", + "url": "https://mrdanielrowland.com/Travel_Guides_mrdanielrowland/ROME_Travel_Guide_free_with_maps.pdf", + "snippet": "Rome has two airports - Fiumicino (FCO) and Ciampino (CIA), but the main one is Leonardo da Vinci International Airport in Fiumicino." + }, + { + "name": "ROME - Tripadvisor", + "url": "https://cdn.tripadvisor.com/pdfs/Guides/TA_Rome_Guide.pdf", + "snippet": "In addition to the best hotels, restaurants and attractions for every type of traveler, you\u2019ll get great advice about what to pack, how to get around and where to find the best views." + }, + { + "name": "Rome - Monocle", + "url": "https://monocle.com/workspace/uploads/file/travel/v2_19_rome_web-pdf-58ada7aacf00a.pdf", + "snippet": "Seven Hills, Rome\u2019s pavements can be steep, slippery and choked with tourists so it\u2019s often best to get to grips with public transport." + }, + { + "name": "Rome Travel Guide", + "url": "http://li.ijcaonline.org/About/browse/Documents/Rome%20Travel%20Guide.pdf", + "snippet": "Immerse yourself in the rich tapestry of Rome's enduring heritage as you follow insightful itineraries." + } + ] + }, + "standardized_response": { + "results": [ + { + "type": "text", + "name": "Rome guide - Rome travel guide", + "url": "https://www.travelplan.it/pdf/rome_guide.pdf", + "content": "The founding of Rome is enveloped in myth: the story goes that the first city center sprang up in 753 B.C. on the Palatine hill, built by Romulus after he had killed his twin brother Remus." + }, + { + "type": "text", + "name": "TRAVEL GUIDE MAGAZINE - mrdanielrowland.com", + "url": "https://mrdanielrowland.com/Travel_Guides_mrdanielrowland/ROME_Travel_Guide_free_with_maps.pdf", + "content": "Rome has two airports - Fiumicino (FCO) and Ciampino (CIA), but the main one is Leonardo da Vinci International Airport in Fiumicino." + }, + { + "type": "text", + "name": "ROME - Tripadvisor", + "url": "https://cdn.tripadvisor.com/pdfs/Guides/TA_Rome_Guide.pdf", + "content": "In addition to the best hotels, restaurants and attractions for every type of traveler, you\u2019ll get great advice about what to pack, how to get around and where to find the best views." + }, + { + "type": "text", + "name": "Rome - Monocle", + "url": "https://monocle.com/workspace/uploads/file/travel/v2_19_rome_web-pdf-58ada7aacf00a.pdf", + "content": "Seven Hills, Rome\u2019s pavements can be steep, slippery and choked with tourists so it\u2019s often best to get to grips with public transport." + }, + { + "type": "text", + "name": "Rome Travel Guide", + "url": "http://li.ijcaonline.org/About/browse/Documents/Rome%20Travel%20Guide.pdf", + "content": "Immerse yourself in the rich tapestry of Rome's enduring heritage as you follow insightful itineraries." + } + ] + } +} \ No newline at end of file