Skip to content

Bing

Classes

Bing

Bases: BaseSearchEngine[BingResponse]

API client for the Bing image search engine.

Used for performing reverse image searches using Bing's API.

Attributes:

Name Type Description
base_url str

The base URL for Bing searches.

Source code in PicImageSearch/engines/bing.py
 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
156
157
class Bing(BaseSearchEngine[BingResponse]):
    """API client for the Bing image search engine.

    Used for performing reverse image searches using Bing's API.

    Attributes:
        base_url (str): The base URL for Bing searches.
    """

    def __init__(self, **request_kwargs: Any):
        """Initializes a Bing API client with specified configurations.

        Args:
            **request_kwargs (Any): Additional arguments for network requests.
        """
        base_url = "https://www.bing.com"
        super().__init__(base_url, **request_kwargs)

    async def _upload_image(self, file: Union[str, bytes, Path]) -> tuple[str, str]:
        """Uploads an image to Bing and retrieves the BCID.

        Args:
            file (Union[str, bytes, Path]): Local image file, can be a path string, bytes data, or Path object.

        Returns:
            tuple[str, str]: A tuple containing:
                - The BCID (Bing Correlation ID) associated with the uploaded image
                - The response URL from Bing's search page

        Raises:
            ValueError: If the BCID cannot be found in the response page.
        """
        endpoint = "images/search?view=detailv2&iss=sbiupload"
        image_base64 = b64encode(read_file(file)).decode("utf-8")
        files = {
            "cbir": "sbi",
            "imageBin": image_base64,
        }
        resp = await self._make_request(method="post", endpoint=endpoint, files=files)

        if match := re.search(r"(bcid_[A-Za-z0-9-.]+)", resp.text):
            return match[1], str(resp.url)
        else:
            raise ValueError("BCID not found on page.")

    async def _get_insights(
        self, bcid: Optional[str] = None, image_url: Optional[str] = None
    ) -> dict[str, Any]:
        """Retrieves image insights from Bing using either BCID or image URL.

        This method handles two search scenarios:
            1. Search by image URL directly
            2. Search by BCID (obtained after uploading an image)

        Args:
            bcid (Optional[str]): The BCID (Bing Correlation ID) retrieved after uploading an image.
            image_url (Optional[str]): The URL of the image to search for.

        Returns:
            dict: The JSON response containing insights about the image.

        Raises:
            ValueError: If neither bcid nor image_url is provided.
        """
        endpoint = (
            "images/api/custom/knowledge"
            "?rshighlight=true&textDecorations=true&internalFeatures=share"
            "&nbl=1&FORM=SBIHMP&safeSearch=off&mkt=en-us&setLang=en-us&IID=idpins&SFX=1"
        )

        if image_url:
            headers = {
                "Referer": (
                    f"{self.base_url}/images/search?"
                    f"view=detailv2&iss=sbi&FORM=SBIHMP&sbisrc=UrlPaste"
                    f"&q=imgurl:{image_url}&idpbck=1"
                )
            }
            files = {
                "knowledgeRequest": (
                    None,
                    json_dumps({"imageInfo": {"url": image_url, "source": "Url"}}),
                )
            }
            resp = await self._make_request(
                method="post", endpoint=endpoint, headers=headers, files=files
            )

        else:
            endpoint += f"&insightsToken={bcid}"
            headers = {
                "Referer": f"{self.base_url}/images/search?insightsToken={bcid}",
            }
            data = {"imageInfo": {"imageInsightsToken": bcid}, "knowledgeRequest": {}}
            if self.client:
                self.client.cookies.clear()
            resp = await self._make_request(
                method="post", endpoint=endpoint, headers=headers, data=data
            )

        return json_loads(resp.text)  # type: ignore

    async def search(
        self,
        url: Optional[str] = None,
        file: Union[str, bytes, Path, None] = None,
        **kwargs: Any,
    ) -> BingResponse:
        """Performs a reverse image search on Bing.

        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.
            **kwargs (Any): Additional arguments passed to the parent class.

        Returns:
            BingResponse: An object containing the search results and metadata.

        Raises:
            ValueError: If neither `url` nor `file` is provided.
            ValueError: If BCID cannot be found when uploading an image.

        Note:
            - Only one of `url` or `file` should be provided.
            - The search process involves multiple HTTP requests to Bing's API.
        """
        self._validate_args(url, file)

        if url:
            resp_url = (
                f"{self.base_url}/images/search?"
                f"view=detailv2&iss=sbi&FORM=SBIHMP&sbisrc=UrlPaste"
                f"&q=imgurl:{url}&idpbck=1"
            )
            resp_json = await self._get_insights(image_url=url)

        elif file:
            bcid, resp_url = await self._upload_image(file)
            resp_json = await self._get_insights(bcid=bcid)

        return BingResponse(resp_json, resp_url)

Functions

__init__(**request_kwargs)

Initializes a Bing API client with specified configurations.

Parameters:

Name Type Description Default
**request_kwargs Any

Additional arguments for network requests.

{}
Source code in PicImageSearch/engines/bing.py
22
23
24
25
26
27
28
29
def __init__(self, **request_kwargs: Any):
    """Initializes a Bing API client with specified configurations.

    Args:
        **request_kwargs (Any): Additional arguments for network requests.
    """
    base_url = "https://www.bing.com"
    super().__init__(base_url, **request_kwargs)
search(url=None, file=None, **kwargs) async

Performs a reverse image search on Bing.

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
**kwargs Any

Additional arguments passed to the parent class.

{}

Returns:

Name Type Description
BingResponse BingResponse

An object containing the search results and metadata.

Raises:

Type Description
ValueError

If neither url nor file is provided.

ValueError

If BCID cannot be found when uploading an image.

Note
  • Only one of url or file should be provided.
  • The search process involves multiple HTTP requests to Bing's API.
Source code in PicImageSearch/engines/bing.py
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
156
157
async def search(
    self,
    url: Optional[str] = None,
    file: Union[str, bytes, Path, None] = None,
    **kwargs: Any,
) -> BingResponse:
    """Performs a reverse image search on Bing.

    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.
        **kwargs (Any): Additional arguments passed to the parent class.

    Returns:
        BingResponse: An object containing the search results and metadata.

    Raises:
        ValueError: If neither `url` nor `file` is provided.
        ValueError: If BCID cannot be found when uploading an image.

    Note:
        - Only one of `url` or `file` should be provided.
        - The search process involves multiple HTTP requests to Bing's API.
    """
    self._validate_args(url, file)

    if url:
        resp_url = (
            f"{self.base_url}/images/search?"
            f"view=detailv2&iss=sbi&FORM=SBIHMP&sbisrc=UrlPaste"
            f"&q=imgurl:{url}&idpbck=1"
        )
        resp_json = await self._get_insights(image_url=url)

    elif file:
        bcid, resp_url = await self._upload_image(file)
        resp_json = await self._get_insights(bcid=bcid)

    return BingResponse(resp_json, resp_url)

Functions