More conduit/cmdline fixes. Added filter to client query

parent 8d3a0ab8
......@@ -9,6 +9,7 @@ import qualified OpenAlex.Types as OA
main :: IO ()
main = do
let filterHelp = help "Filter, for example: display_name.search:einstein , see https://docs.openalex.org/how-to-use-the-api/get-lists-of-entities/filter-entity-lists"
(opts, runCmd) <-
simpleOptions "0.1.0.0"
"OpenAlex"
......@@ -16,46 +17,46 @@ main = do
(pure ()) $ do
addCommand "concepts"
"Fetch OpenAlex concepts (https://docs.openalex.org/api-entities/concepts/concept-object)"
(const fetchConcepts)
(pure ())
fetchConcepts
(strOption (long "filter"))
addCommand "works"
"Fetch OpenAlex works (https://docs.openalex.org/api-entities/works/work-object)"
(const fetchWorks)
(pure ())
fetchWorks
(strOption (long "filter"))
addCommand "works-c"
"Fetch OpenAlex works (https://docs.openalex.org/api-entities/works/work-object) with conduit"
(const fetchWorksC)
(pure ())
fetchWorksC
(strOption (long "filter"))
runCmd ()
fetchConcepts :: () -> IO ()
fetchConcepts _ = do
ec <- OA.fetchConcepts (Just 1) (Just 1) (Just "*")
fetchConcepts :: OA.Filter -> () -> IO ()
fetchConcepts fltr _ = do
ec <- OA.fetchConcepts (Just 1) (Just 1) (Just "*") (Just fltr)
case ec of
Left err -> putText $ "error: " <> show err
Right c -> do
putText $ show c
fetchWorks :: () -> IO ()
fetchWorks _ = do
ew <- OA.fetchWorks (Just 1) (Just 1) (Just "*")
fetchWorks :: OA.Filter -> () -> IO ()
fetchWorks fltr _ = do
ew <- OA.fetchWorks (Just 1) (Just 1) (Just "*") (Just fltr)
case ew of
Left err -> putText $ "error: " <> show err
Right w -> do
putText $ show w
fetchWorksC :: () -> IO ()
fetchWorksC _ = do
eWorksC <- OA.fetchWorksC Nothing
fetchWorksC :: OA.Filter -> () -> IO ()
fetchWorksC fltr _ = do
eWorksC <- OA.fetchWorksC Nothing (Just fltr)
case eWorksC of
Left err -> putText $ "error: " <> show err
Right (Just count, c) -> do
putText $ "Count: " <> show count
Right (mCount, c) -> do
putText $ "Count: " <> show mCount
_ <- runConduit $ c
.| takeC 1000
.| mapM_C (\(OA.Work { .. }) -> do
liftIO $ putText $ show id
liftIO $ putText $ show id <> " :: " <> show display_name
)
pure ()
......@@ -27,7 +27,7 @@ import Network.HTTP.Client.TLS (tlsManagerSettings)
import Protolude hiding (yield)
import OpenAlex.Client
import OpenAlex.ServantClientLogging
import OpenAlex.Types (ListOf(..), Meta(..), Page, PerPage, Cursor, Concept, Work)
import OpenAlex.Types (ListOf(..), Meta(..), Page, PerPage, Cursor, Filter, Concept, Work)
import Servant.Client (BaseUrl(..), ClientEnv(..), ClientError, Scheme(Https), defaultMakeClientRequest, mkClientEnv, runClientM)
defaultClientEnv :: IO ClientEnv
......@@ -41,23 +41,33 @@ defaultClientEnv = do
pure $ addLoggingToClientEnv env
fetchConcepts :: Maybe Page -> Maybe PerPage -> Maybe Cursor -> IO (Either ClientError (ListOf Concept))
fetchConcepts mPage mPerPage mCursor = do
fetchConcepts :: Maybe Page
-> Maybe PerPage
-> Maybe Cursor
-> Maybe Filter
-> IO (Either ClientError (ListOf Concept))
fetchConcepts mPage mPerPage mCursor mFilter = do
env <- defaultClientEnv
runClientM (concepts mPage mPerPage mCursor) env
runClientM (concepts mPage mPerPage mCursor mFilter) env
fetchWorks :: Maybe Page -> Maybe PerPage -> Maybe Cursor -> IO (Either ClientError (ListOf Work))
fetchWorks mPage mPerPage mCursor = do
fetchWorks :: Maybe Page
-> Maybe PerPage
-> Maybe Cursor
-> Maybe Filter
-> IO (Either ClientError (ListOf Work))
fetchWorks mPage mPerPage mCursor mFilter = do
env <- defaultClientEnv
runClientM (works mPage mPerPage mCursor) env
runClientM (works mPage mPerPage mCursor mFilter) env
fetchWorksC :: Maybe Cursor -> IO (Either ClientError (Maybe Integer, ConduitT () Work IO ()))
fetchWorksC Nothing = do
fetchWorksC (Just "*")
fetchWorksC mCursor = do
fetchWorksC :: Maybe Cursor
-> Maybe Filter
-> IO (Either ClientError (Maybe Integer, ConduitT () Work IO ()))
fetchWorksC Nothing mFilter = do
fetchWorksC (Just "*") mFilter
fetchWorksC mCursor mFilter = do
env <- defaultClientEnv
-- NOTE: per-page max is 200
eRes <- runClientM (works (Just 1) (Just 1) Nothing) env
eRes <- runClientM (works (Just 1) (Just 1) Nothing mFilter) env
case eRes of
Left err -> pure $ Left err
Right ListOf { meta = Meta { count }} -> do
......@@ -66,11 +76,11 @@ fetchWorksC mCursor = do
where
producer :: ClientEnv -> Maybe Cursor -> ConduitT () Work IO ()
producer env mCursor' = do
eRes <- liftIO $ runClientM (works Nothing (Just 20) mCursor') env
liftIO $ putText $ "Conduit fetching page with cursor " <> show mCursor'
eRes <- liftIO $ runClientM (works Nothing (Just 200) mCursor' mFilter) env
-- liftIO $ putText $ "Conduit fetching page with cursor " <> show mCursor'
case eRes of
Left err -> panic $ "error: " <> show err
Right (ListOf { results, meta = meta@(Meta { next_cursor }) }) -> do
liftIO $ putText $ "Meta: " <> show meta
Right (ListOf { results, meta = _meta@(Meta { next_cursor }) }) -> do
-- liftIO $ putText $ "Meta: " <> show meta
yieldMany results
producer env next_cursor
......@@ -16,7 +16,7 @@ import Protolude
import Servant.API
import Servant.Client
import OpenAlex.Types (Page, PerPage, Cursor, ListOf(..), Concept, Work)
import OpenAlex.Types (Page, PerPage, Cursor, Filter, ListOf(..), Concept, Work)
type API_URL = Text
apiUrl :: API_URL
......@@ -34,6 +34,7 @@ type OpenAlexAPI =
:> QueryParam "page" Page
:> QueryParam "per-page" PerPage
:> QueryParam "cursor" Cursor
:> QueryParam "filter" Filter
-- TODO: filter, search, sort
:> Get '[JSON] (ListOf Concept)
......@@ -42,14 +43,15 @@ type OpenAlexAPI =
:> QueryParam "page" Page
:> QueryParam "per-page" PerPage
:> QueryParam "cursor" Cursor
:> QueryParam "filter" Filter
-- TODO: filter, search, sort
:> Get '[JSON] (ListOf Work)
openAlexApi :: Proxy OpenAlexAPI
openAlexApi = Proxy
concepts :: Maybe Page -> Maybe PerPage -> Maybe Cursor -> ClientM (ListOf Concept)
concepts :: Maybe Page -> Maybe PerPage -> Maybe Cursor -> Maybe Filter -> ClientM (ListOf Concept)
works :: Maybe Page -> Maybe PerPage -> Maybe Cursor -> ClientM (ListOf Work)
works :: Maybe Page -> Maybe PerPage -> Maybe Cursor -> Maybe Filter -> ClientM (ListOf Work)
concepts :<|> works = client openAlexApi
......@@ -23,9 +23,17 @@ import Data.Time.Calendar (Day)
import qualified Data.Time.Format as DTF
import Protolude hiding (Location, Meta)
-- API request types
type Cursor = Text
type Page = Int
type PerPage = Int
type Filter = Text
-- API response types
type Count = Int
type Cursor = Text
type DOI = Text
data ExternalID = ExtIDUrl URL | ExtIDUrls [URL] | ExtIDInt Int
deriving (Generic, Show)
......@@ -54,8 +62,6 @@ instance FromJSON OAStatus where
parseJSON (String "closed") = pure OAClosed
parseJSON _ = fail "Don't know how to parse this oa status"
type OpenAlexID = Text
type Page = Int
type PerPage = Int
type URL = Text
type Year = Int
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment