diff --git a/README.md b/README.md index 2fdbb93..c0711b6 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ benefit from Linkup services to the full extent. 📝 - ✅ **Simple and intuitive API client.** - 🔍 **Support all Linkup entrypoints and parameters.** -- ⚡ **Supports synchronous and asynchronous requests.** -- 🔒 **Handles authentication and request management.** +- ⚡ **Support synchronous and asynchronous calls.** +- 🔒 **Handle authentication and request management.** ## 📦 Installation @@ -90,9 +90,10 @@ The `search` function also supports three output types: user-defined schema ```python -from linkup import LinkupClient, LinkupSourcedAnswer from typing import Any +from linkup import LinkupClient, LinkupSourcedAnswer + client = LinkupClient() # API key can be read from the environment variable or passed as an argument search_response: Any = client.search( query="What are the 3 major events in the life of Abraham Lincoln?", @@ -102,18 +103,22 @@ search_response: Any = client.search( ) assert isinstance(search_response, LinkupSourcedAnswer) print(search_response.model_dump()) -# Response: -# { -# answer="The three major events in the life of Abraham Lincoln are: 1. ...", -# sources=[ -# { -# "name": "HISTORY", -# "url": "https://www.history.com/topics/us-presidents/abraham-lincoln", -# "snippet": "Abraham Lincoln - Facts & Summary - HISTORY ..." -# }, -# ... -# ] -# } +``` + +Which prints: + +```bash +{ + answer="The three major events in the life of Abraham Lincoln are: 1. ...", + sources=[ + { + "name": "HISTORY", + "url": "https://www.history.com/topics/us-presidents/abraham-lincoln", + "snippet": "Abraham Lincoln - Facts & Summary - HISTORY ..." + }, + ... + ] +} ``` Check the code or the @@ -138,18 +143,65 @@ fetch_response: LinkupFetchResponse = client.fetch( include_raw_html=True, ) print(fetch_response.model_dump()) -# Response: -# { -# markdown="Get started for free, no credit card required...", -# raw_html="......" -# } +``` + +Which prints: + +```bash +{ + markdown="Get started for free, no credit card required...", + raw_html="......" +} ``` Check the code or the [official documentation](https://docs.linkup.so/pages/documentation/api-reference/endpoint/post-fetch) for the detailed list of available parameters. +#### ⌛ Asynchronous Calls + +All the Linkup main functions come with an asynchronous counterpart, with the same behavior and the +same name prefixed by `async_` (e.g. `async_search` for `search`). This should be favored in +production use cases to avoid blocking the main thread while waiting for the Linkup API to respond. +This makes possible to call the Linkup API several times concurrently for instance. + +```python +import asyncio +from typing import Any + +from linkup import LinkupClient, LinkupSourcedAnswer + +async def main() -> None: + client = LinkupClient() # API key can be read from the environment variable or passed as an argument + search_response: Any = await client.async_search( + query="What are the 3 major events in the life of Abraham Lincoln?", + depth="deep", # "standard" or "deep" + output_type="sourcedAnswer", # "searchResults" or "sourcedAnswer" or "structured" + structured_output_schema=None, # must be filled if output_type is "structured" + ) + assert isinstance(search_response, LinkupSourcedAnswer) + print(search_response.model_dump()) + +asyncio.run(main()) +``` + +Which prints: + +```bash +{ + answer="The three major events in the life of Abraham Lincoln are: 1. ...", + sources=[ + { + "name": "HISTORY", + "url": "https://www.history.com/topics/us-presidents/abraham-lincoln", + "snippet": "Abraham Lincoln - Facts & Summary - HISTORY ..." + }, + ... + ] +} +``` + #### 📚 More Examples See the `examples/` directory for more examples and documentation, for instance on how to use Linkup -entrypoints using asynchronous functions. +entrypoints using asynchronous functions to call the Linkup API several times concurrenly. diff --git a/pyproject.toml b/pyproject.toml index 222a691..0227fdd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,10 +55,14 @@ line-length = 100 target-version = "py39" [tool.ruff.lint] -select = ["E", "F", "I", "S", "UP"] +extend-ignore = ["D107"] +pydocstyle = { convention = "google" } +select = ["D", "E", "F", "I", "S", "UP"] [tool.ruff.lint.extend-per-file-ignores] -"tests/**/*_test.py" = ["S101"] +"examples/*.py" = ["D"] +"src/linkup/__init__.py" = ["D104"] +"tests/**/*test.py" = ["D", "S101"] [build-system] build-backend = "hatchling.build" diff --git a/src/linkup/client.py b/src/linkup/client.py index 6f3a9b0..8779f23 100644 --- a/src/linkup/client.py +++ b/src/linkup/client.py @@ -1,3 +1,5 @@ +"""Linkup client, the entrypoint for Linkup functions.""" + import json import os from datetime import date diff --git a/src/linkup/errors.py b/src/linkup/errors.py index 5d6c108..5f8c6c4 100644 --- a/src/linkup/errors.py +++ b/src/linkup/errors.py @@ -1,3 +1,6 @@ +"""Linkup custom errors.""" + + class LinkupInvalidRequestError(Exception): """Invalid request error, raised when the Linkup API returns a 400 status code. diff --git a/src/linkup/types.py b/src/linkup/types.py index 1038eef..c4a8621 100644 --- a/src/linkup/types.py +++ b/src/linkup/types.py @@ -1,3 +1,5 @@ +"""Input and output types for Linkup functions.""" + from typing import Any, Literal, Optional, Union from pydantic import BaseModel, ConfigDict, Field