Skip to content

Commit b6276dc

Browse files
committed
added a Brave search API example
1 parent c379057 commit b6276dc

File tree

3 files changed

+133
-0
lines changed

3 files changed

+133
-0
lines changed

BraveSearch/BraveSearch.hs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
{-# LANGUAGE OverloadedStrings #-}
2+
{-# LANGUAGE RecordWildCards #-}
3+
4+
module BraveSearch
5+
( getSearchSuggestions
6+
) where
7+
8+
import Network.HTTP.Simple
9+
import Data.Aeson
10+
import qualified Data.Text as T
11+
import Control.Exception (try)
12+
import Network.HTTP.Client (HttpException)
13+
import qualified Data.ByteString.Char8 as BS
14+
import qualified Data.ByteString.Lazy.Char8 as LBS
15+
16+
data SearchResponse = SearchResponse
17+
{ query :: QueryInfo
18+
, web :: WebResults
19+
} deriving (Show)
20+
21+
data QueryInfo = QueryInfo
22+
{ original :: T.Text
23+
} deriving (Show)
24+
25+
data WebResults = WebResults
26+
{ results :: [WebResult]
27+
} deriving (Show)
28+
29+
data WebResult = WebResult
30+
{ type_ :: T.Text
31+
, index :: Maybe Int
32+
, all :: Maybe Bool
33+
, title :: Maybe T.Text
34+
, url :: Maybe T.Text
35+
, description :: Maybe T.Text
36+
} deriving (Show)
37+
38+
instance FromJSON SearchResponse where
39+
parseJSON = withObject "SearchResponse" $ \v -> SearchResponse
40+
<$> v .: "query"
41+
<*> v .: "web"
42+
43+
instance FromJSON QueryInfo where
44+
parseJSON = withObject "QueryInfo" $ \v -> QueryInfo
45+
<$> v .: "original"
46+
47+
instance FromJSON WebResults where
48+
parseJSON = withObject "WebResults" $ \v -> WebResults
49+
<$> v .: "results"
50+
51+
instance FromJSON WebResult where
52+
parseJSON = withObject "WebResult" $ \v -> WebResult
53+
<$> v .: "type"
54+
<*> v .:? "index"
55+
<*> v .:? "all"
56+
<*> v .:? "title"
57+
<*> v .:? "url"
58+
<*> v .:? "description"
59+
60+
getSearchSuggestions :: String -> String -> IO (Either String [T.Text])
61+
getSearchSuggestions apiKey query = do
62+
let url = "https://api.search.brave.com/res/v1/web/search?q=" ++ query ++ "&country=US&count=5"
63+
64+
request <- parseRequest url
65+
let requestWithHeaders = setRequestHeader "Accept" ["application/json"]
66+
$ setRequestHeader "X-Subscription-Token" [BS.pack apiKey]
67+
$ request
68+
69+
result <- try $ httpLBS requestWithHeaders
70+
71+
case result of
72+
Left e -> return $ Left $ "Network error: " ++ show (e :: HttpException)
73+
Right response -> do
74+
let statusCode = getResponseStatusCode response
75+
if statusCode /= 200
76+
then return $ Left $ "HTTP error: " ++ show statusCode
77+
else do
78+
let body = getResponseBody response
79+
case eitherDecode body of
80+
Left err -> return $ Left $ "JSON parsing error: " ++ err
81+
Right searchResponse@SearchResponse{..} -> do
82+
let originalQuery = original query
83+
webResults = results web
84+
let suggestions = "Original Query: " <> originalQuery : map formatResult webResults
85+
return $ Right suggestions
86+
87+
formatResult :: WebResult -> T.Text
88+
formatResult WebResult{..} =
89+
let titleText = maybe "N/A" ("Title: " <>) title
90+
urlText = maybe "N/A" ("URL: " <>) url
91+
descText = maybe "N/A" ("Description: " <>) (fmap (T.take 100) description)
92+
in T.intercalate " | " [titleText, urlText, descText]

BraveSearch/Main.hs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{-# LANGUAGE OverloadedStrings #-}
2+
3+
module Main where
4+
5+
import BraveSearch (getSearchSuggestions)
6+
import System.Environment (getEnv)
7+
import qualified Data.Text as T
8+
import qualified Data.Text.IO as TIO
9+
10+
main :: IO ()
11+
main = do
12+
-- Get the API key from the environment variable
13+
apiKey <- getEnv "BRAVE_SEARCH_API_KEY"
14+
15+
-- Prompt the user for a search query
16+
TIO.putStrLn "Enter a search query:"
17+
query <- TIO.getLine
18+
19+
-- Call the function to get search suggestions
20+
result <- getSearchSuggestions apiKey (T.unpack query)
21+
22+
case result of
23+
Left err -> TIO.putStrLn $ "Error: " <> T.pack err
24+
Right suggestions -> do
25+
TIO.putStrLn "Search suggestions:"
26+
mapM_ (TIO.putStrLn . ("- " <>)) suggestions

BraveSearch/brave-search-client.cabal

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: brave-search-client
2+
version: 0.1.0.0
3+
build-type: Simple
4+
cabal-version: >=1.10
5+
6+
executable brave-search-client
7+
main-is: Main.hs
8+
other-modules: BraveSearch
9+
build-depends: base >=4.7 && <5
10+
, http-conduit
11+
, aeson
12+
, text
13+
, bytestring
14+
, http-client
15+
default-language: Haskell2010

0 commit comments

Comments
 (0)