Skip to content

Lenso

Classes

Lenso

Bases: BaseSearchEngine[LensoResponse]

API client for the Lenso image search engine.

Lenso is a powerful AI-driven visual search engine that helps you find similar images, duplicates, recognize places, and discover related content.

Attributes:

Name Type Description
base_url str

The base URL for Lenso API.

SEARCH_TYPES Literal

Valid search type options: - "": All possible types in smaller quantities - "duplicates": Find duplicate images - "similar": Find visually similar images - "places": Recognize places in the image - "related": Find related content

SORT_TYPES Literal

Valid sort type options: - "SMART": Lenso's default smart sorting - "RANDOM": Randomly sorted results - "QUALITY_DESCENDING": Sort by quality, best to worst match - "QUALITY_ASCENDING": Sort by quality, worst to best match - "DATE_DESCENDING": Sort by date, newest to oldest - "DATE_ASCENDING": Sort by date, oldest to newest

Source code in PicImageSearch/engines/lenso.py
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
class Lenso(BaseSearchEngine[LensoResponse]):
    """API client for the Lenso image search engine.

    Lenso is a powerful AI-driven visual search engine that helps you find similar images,
    duplicates, recognize places, and discover related content.

    Attributes:
        base_url (str): The base URL for Lenso API.
        SEARCH_TYPES (Literal): Valid search type options:
            - "": All possible types in smaller quantities
            - "duplicates": Find duplicate images
            - "similar": Find visually similar images
            - "places": Recognize places in the image
            - "related": Find related content
        SORT_TYPES (Literal): Valid sort type options:
            - "SMART": Lenso's default smart sorting
            - "RANDOM": Randomly sorted results
            - "QUALITY_DESCENDING": Sort by quality, best to worst match
            - "QUALITY_ASCENDING": Sort by quality, worst to best match
            - "DATE_DESCENDING": Sort by date, newest to oldest
            - "DATE_ASCENDING": Sort by date, oldest to newest
    """

    SEARCH_TYPES = Literal["", "duplicates", "similar", "places", "related"]
    SORT_TYPES = Literal[
        "SMART",
        "RANDOM",
        "QUALITY_DESCENDING",
        "QUALITY_ASCENDING",
        "DATE_DESCENDING",
        "DATE_ASCENDING",
    ]

    def __init__(
        self,
        base_url: str = "https://lenso.ai",
        **request_kwargs: Any,
    ):
        """Initializes a Lenso API client with request configuration.

        Args:
            base_url (str): The base URL for Lenso API.
            **request_kwargs (Any): Additional arguments for network requests.
        """
        super().__init__(base_url, **request_kwargs)

    async def _upload_image(self, image_base64: str) -> str:
        """Uploads an image to Lenso API and retrieves the result hash.

        Args:
            image_base64 (str): Base64 encoded image data.

        Returns:
            str: The ID (hash) of the uploaded image.

        Raises:
            RuntimeError: If the upload fails or ID is not found in response.
        """
        endpoint = "api/upload"
        payload = {"image": f"data:image/jpeg;base64,{image_base64}"}
        resp = await self._make_request(method="post", endpoint=endpoint, json=payload)
        resp_json = json_loads(resp.text)

        if result_hash := resp_json.get("id"):
            return result_hash

        raise RuntimeError(
            f"Lenso Upload failed or ID not found. Status Code: {resp.status_code}, Response: {resp.text}"
        )

    async def search(
        self,
        url: Optional[str] = None,
        file: Union[str, bytes, Path, None] = None,
        search_type: SEARCH_TYPES = "",
        sort_type: SORT_TYPES = "SMART",
        **kwargs: Any,
    ) -> LensoResponse:
        """Performs a reverse image search on Lenso.

        This method supports two ways of searching:
            1. Search by image URL
            2. Search by uploading a local image file

        Args:
            url (Optional[str]): URL of the image to search.
            file (Union[str, bytes, Path, None]): Local image file, can be a path string, bytes data, or Path object.
            search_type (str): Type of search to perform. Must be one of SEARCH_TYPES.
            sort_type (str): Sorting method for results. Must be one of SORT_TYPES.
            **kwargs (Any): Additional arguments passed to the parent class.

        Raises:
            ValueError: If neither `url` nor `file` is provided.
            ValueError: If `search_type` or `sort_type` is invalid.
            RuntimeError: If image upload fails or response is invalid.
        """
        self._validate_args(url, file)

        if search_type and search_type not in self.SEARCH_TYPES.__args__:
            valid_types = '", "'.join(t for t in self.SEARCH_TYPES.__args__ if t)
            raise ValueError(
                f'Invalid search_type. Must be empty or one of: "{valid_types}"'
            )

        if sort_type not in self.SORT_TYPES.__args__:
            valid_sorts = '", "'.join(self.SORT_TYPES.__args__)
            raise ValueError(f'Invalid sort_type. Must be one of: "{valid_sorts}"')

        image_base64: str = ""
        result_hash: str = ""

        if url:
            image_bytes = await self.download(url)
            image_base64 = base64.b64encode(image_bytes).decode("utf-8")
            result_hash = await self._upload_image(image_base64)

        elif file:
            image_bytes = read_file(file)
            image_base64 = base64.b64encode(image_bytes).decode("utf-8")
            result_hash = await self._upload_image(image_base64)

        search_endpoint = "api/search"
        search_payload = {
            "image": {
                "id": result_hash,
                "data": f"data:image/jpeg;base64,{image_base64}",
            },
            "effects": {},
            "selection": {},
            "domain": "",
            "text": "",
            "page": 0,
            "type": search_type,
            "sort": sort_type,
            "seed": 0,
            "facial_search_consent": 0,
        }

        resp = await self._make_request(
            method="post", endpoint=search_endpoint, json=search_payload
        )
        resp_json = json_loads(resp.text)
        resp_url = f"{self.base_url}/en/results/{result_hash}"

        return LensoResponse(resp_json, resp_url)

Attributes

SEARCH_TYPES = Literal['', 'duplicates', 'similar', 'places', 'related'] class-attribute instance-attribute
SORT_TYPES = Literal['SMART', 'RANDOM', 'QUALITY_DESCENDING', 'QUALITY_ASCENDING', 'DATE_DESCENDING', 'DATE_ASCENDING'] class-attribute instance-attribute

Functions

__init__(base_url='https://lenso.ai', **request_kwargs)

Initializes a Lenso API client with request configuration.

Parameters:

Name Type Description Default
base_url str

The base URL for Lenso API.

'https://lenso.ai'
**request_kwargs Any

Additional arguments for network requests.

{}
Source code in PicImageSearch/engines/lenso.py
44
45
46
47
48
49
50
51
52
53
54
55
def __init__(
    self,
    base_url: str = "https://lenso.ai",
    **request_kwargs: Any,
):
    """Initializes a Lenso API client with request configuration.

    Args:
        base_url (str): The base URL for Lenso API.
        **request_kwargs (Any): Additional arguments for network requests.
    """
    super().__init__(base_url, **request_kwargs)
_upload_image(image_base64) async

Uploads an image to Lenso API and retrieves the result hash.

Parameters:

Name Type Description Default
image_base64 str

Base64 encoded image data.

required

Returns:

Name Type Description
str str

The ID (hash) of the uploaded image.

Raises:

Type Description
RuntimeError

If the upload fails or ID is not found in response.

Source code in PicImageSearch/engines/lenso.py
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
async def _upload_image(self, image_base64: str) -> str:
    """Uploads an image to Lenso API and retrieves the result hash.

    Args:
        image_base64 (str): Base64 encoded image data.

    Returns:
        str: The ID (hash) of the uploaded image.

    Raises:
        RuntimeError: If the upload fails or ID is not found in response.
    """
    endpoint = "api/upload"
    payload = {"image": f"data:image/jpeg;base64,{image_base64}"}
    resp = await self._make_request(method="post", endpoint=endpoint, json=payload)
    resp_json = json_loads(resp.text)

    if result_hash := resp_json.get("id"):
        return result_hash

    raise RuntimeError(
        f"Lenso Upload failed or ID not found. Status Code: {resp.status_code}, Response: {resp.text}"
    )
search(url=None, file=None, search_type='', sort_type='SMART', **kwargs) async

Performs a reverse image search on Lenso.

This method supports two ways of searching
  1. Search by image URL
  2. Search by uploading a local image file

Parameters:

Name Type Description Default
url Optional[str]

URL of the image to search.

None
file Union[str, bytes, Path, None]

Local image file, can be a path string, bytes data, or Path object.

None
search_type str

Type of search to perform. Must be one of SEARCH_TYPES.

''
sort_type str

Sorting method for results. Must be one of SORT_TYPES.

'SMART'
**kwargs Any

Additional arguments passed to the parent class.

{}

Raises:

Type Description
ValueError

If neither url nor file is provided.

ValueError

If search_type or sort_type is invalid.

RuntimeError

If image upload fails or response is invalid.

Source code in PicImageSearch/engines/lenso.py
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
async def search(
    self,
    url: Optional[str] = None,
    file: Union[str, bytes, Path, None] = None,
    search_type: SEARCH_TYPES = "",
    sort_type: SORT_TYPES = "SMART",
    **kwargs: Any,
) -> LensoResponse:
    """Performs a reverse image search on Lenso.

    This method supports two ways of searching:
        1. Search by image URL
        2. Search by uploading a local image file

    Args:
        url (Optional[str]): URL of the image to search.
        file (Union[str, bytes, Path, None]): Local image file, can be a path string, bytes data, or Path object.
        search_type (str): Type of search to perform. Must be one of SEARCH_TYPES.
        sort_type (str): Sorting method for results. Must be one of SORT_TYPES.
        **kwargs (Any): Additional arguments passed to the parent class.

    Raises:
        ValueError: If neither `url` nor `file` is provided.
        ValueError: If `search_type` or `sort_type` is invalid.
        RuntimeError: If image upload fails or response is invalid.
    """
    self._validate_args(url, file)

    if search_type and search_type not in self.SEARCH_TYPES.__args__:
        valid_types = '", "'.join(t for t in self.SEARCH_TYPES.__args__ if t)
        raise ValueError(
            f'Invalid search_type. Must be empty or one of: "{valid_types}"'
        )

    if sort_type not in self.SORT_TYPES.__args__:
        valid_sorts = '", "'.join(self.SORT_TYPES.__args__)
        raise ValueError(f'Invalid sort_type. Must be one of: "{valid_sorts}"')

    image_base64: str = ""
    result_hash: str = ""

    if url:
        image_bytes = await self.download(url)
        image_base64 = base64.b64encode(image_bytes).decode("utf-8")
        result_hash = await self._upload_image(image_base64)

    elif file:
        image_bytes = read_file(file)
        image_base64 = base64.b64encode(image_bytes).decode("utf-8")
        result_hash = await self._upload_image(image_base64)

    search_endpoint = "api/search"
    search_payload = {
        "image": {
            "id": result_hash,
            "data": f"data:image/jpeg;base64,{image_base64}",
        },
        "effects": {},
        "selection": {},
        "domain": "",
        "text": "",
        "page": 0,
        "type": search_type,
        "sort": sort_type,
        "seed": 0,
        "facial_search_consent": 0,
    }

    resp = await self._make_request(
        method="post", endpoint=search_endpoint, json=search_payload
    )
    resp_json = json_loads(resp.text)
    resp_url = f"{self.base_url}/en/results/{result_hash}"

    return LensoResponse(resp_json, resp_url)

Functions