bookwyrm icon indicating copy to clipboard operation
bookwyrm copied to clipboard

Client API

Open tastytea opened this issue 3 years ago • 19 comments

Is your feature request related to a problem? Please describe. It would be wonderful if I could share quotes, comments and reviews and re-shelve books directly from my e-book reader. I'd like to try writing a plugin for KOReader.

Describe the solution you'd like I'd like an API that allows me to:

  • Log-in
  • Match book title & author(s) / ISBN with a book on one of my shelves
  • Post quotes, comments, reviews and ratings
  • Re-shelve books
  • Set started reading / finished reading dates

Additional context I realize it may be a bit early to introduce a stable API, but I wanted an issue I could subscribe to so I wouldn't miss it when it gets implemented. 🙂

tastytea avatar Mar 23 '21 22:03 tastytea

I uh, have some thoughts about this, as I have been looking at all sorts of ebook-enviroment protocols with regards to KDE's Peruse Comic Book Reader (and that'd also be why I'd be interested in a client API :D )

So, the typical protocol used on fedi right now is mastodon's c2s protocol, but that's not a good fit for Bookwyrm because there's just too little functionality, especially for the types of things reading applications like to share. The second option is the activitypub c2s protocol, but that has the problem that there's too many gaps: it's not clear how to log in, how to upload media, how to configure your account, and furthermore, it's really designed for a generalized activitypub server, so there's no functionality for the server to tell the client 'yeah, I don't support what you're sending me'.

So, then there's the following options:

Micropub

Micropub is mostly designed to post things to your own blog. It uses microformats syntax, which supports reviews as well as a variety of other markups (and, interesting factoid: Mastodon leaves MicroFormats alone). Unlike activitypub it does have a configuration logic, and furthermore, there are stable extensions for limiting the supported vocabulary. It also has visibility and post status amongst the supported vocab. It does require indieAuth though (more on that later). There's a django implementation and flask implementation for it, both under-documented.

WebAnnotations

Webannotations Protocol is probably much more interesting if the client is an ereader, because there are ways to represent bookmarks, reviews, citations, and a lot of other annotations. Furthermore, it uses activitystream collection pages :D It's proly more that bookwyrm really supports right now, but I do think that a lot of what it supports, if we could insert that in a social context, would be really useful for social reading. (Yes, it does support authorship)

So, this one is already in use by the New York Public Library's ebook server project, though they mention they extended the vocabulary to represent the reading position.

What will be hardest, I think, is how servers should federate the annotations with one another. The annotations vocab is json-LD, but I am not sure other activitypub projects will really enjoy having the annotations vocab in federation? It also doesn't have things like 'reblog/like/block/add to collection', so that might need separate API, or webannotations for bookwyrm are extended to allow adding likes or flagging an annotation.

Authentication

Basically all of the fediverse uses a variation of OAuth, and it's also in ebook projects. OAuth has a small problem in that it requires client-registration, which doesn't work well with a distributed system. The following solutions exist:

OPDS auth document approach

The OPDS authentication document suggests all OAuth clients should use the same identifier and callback uri. This is really awkward compared to the other options, and makes it hard to identify bad-actor client programs.

Mastodon approach

Mastodon implements a client registration API call. It's a bit better than OPDS' approach, because at the very least every single client is separated, and thus bad-actor clients can be blocked from an account.

IndieAuth

IndieAuth is an extension of OAuth which is designed for small communities, and it's been recommended by the IndieWeb folks that fediverse applications adopt it, because it's far more secure than the other options. It's not getting a super-lot of traction though, but I suspect this is largely because people find it scary to modify their OAuth implementations.

And, as before, there's a django implementation and flask implementation for it, both under-documented.

Potential way to use it?

  • Client does authentication flow with server.
  • Client GETs the profile page, and can auto-discover the link for the micropub endpoint or the webannotation endpoint.
  • Client, authenticated, POSTs reviews to these endpoints.
  • If a webannotation endpoint, client could, authenticated, GET the annotations collection and the server could serve them reviews, citations and other things that would normally show up in their activitypub inbox as relevant webannotations.
    • If a client knows which book belongs with which annotation, they could present the annotations while reading.
    • A client that is really interested in supporting the full social part of bookwyrm could display all annotations in a stream regardless if it know which book it belongs with, so that the user can see what kind of books their friends are reading.

What this misses, obviously, is a way to identify books. What is necessary for this is a search query, where the client sends a query for, say, "Sherlock Holmes Study Scarlet", and bookwyrm gives them a list of possible books, with some minor amount of metadata for further identification, and a URI which reviews or annotations should target for the server to know which book they're talking about. The benefit of just using an URI here means that the URI could be an isbn, an openlibrary link, inventaire link, etc, so that the server doesn't necessarily need to create a local book object to be targeted until the review has been accepted.

Overall, I think WebAnnotations might be best for an ereader client to communicate with a social reader server, because it does seem to have everything relevant to social reading. It is a very detailed spec though. For a full social reader client, it misses stuff like like/reblog/flag, but that might be solved by extending webannotations or adding separate api.

Anyway, I hope all the links are useful if nothing else. Sorry if this was a little intense :D

therahedwig avatar Jun 18 '21 13:06 therahedwig

mentioned in #75

seniorm0ment avatar Jul 21 '21 01:07 seniorm0ment

I do not understand. ActivityPub has a Client2Server part …

This is Micropub but ActivityPub. See section 6 https://www.w3.org/TR/activitypub/#client-to-server-interactions

PS: The author of IndieAuth had a nice talk at the conf: https://conf.tube/search?search=oauth&searchTarget=local

sebilasse avatar Dec 04 '21 09:12 sebilasse

Are there any updates on this ?

I am the developer of a foss self hosted goodreads alternative and I would like to let users post book reading progress/reading status to their bookwyrm account.

So is there an API that could be used to add/update books ?

bayang avatar May 02 '22 14:05 bayang

When there's progress on developing a client API, there will be updates to this issue -- you can follow the issue if you want to be in the know.

Books and reading progress are federated, so they can be updated using ActivityPub Create and Update activities. That's out of scope for this issue, but I'd be more than happy to talk to you further elsewhere about how the data federation works :)

mouse-reeve avatar May 03 '22 01:05 mouse-reeve

Well, yes, this is why we do the frequent ActivityPub meetings, so that implementors can tell each other how the data federation works :) At least each 2nd Tuesday a month. They are announced in the official forum and calendar:
https://socialhub.activitypub.rocks or webcal https://cloud.w3c.social/remote.php/dav/public-calendars/GzxsDfE6CKtp9MHX/?export There will be an extra meeting on 24th. I would love if the book people would attend and demo, so also pinging @maxlath

sebilasse avatar May 13 '22 11:05 sebilasse

I just found this Android reading tracker APP and thought how awesome a bookwyrm Integration would be. This could become a bookwyrm android app.

When there is an API https://github.com/mateusz-bak/openreads-android/issues/96

thrillfall avatar May 30 '22 20:05 thrillfall

So, I used bookwyrm for a few months and now came across https://github.com/mateusz-bak/openreads-android.

I would like an api so this app can sync to (and from) my bookwyrm account ;)

I would be willing to donate a few bucks to make this happen.

pabloscloud avatar Jan 28 '23 20:01 pabloscloud

Books and reading progress are federated, so they can be updated using ActivityPub Create and Update activities. That's out of scope for this issue, but I'd be more than happy to talk to you further elsewhere about how the data federation works

I don't have experience with ActivityPub, only rest/graphql apis,but... would there be a way to load 'read', 'to-read' shelves? If I understand correctly, I would only be able to get each activity, but not the whole 'completed books' shelf, right?

thiagomgd avatar Feb 03 '23 23:02 thiagomgd

You can see a shelf; for example, this is my to-read shelf: https://bookwyrm.social/user/mouse/shelf/to-read.json?page=1

mouse-reeve avatar Feb 03 '23 23:02 mouse-reeve

Hello! Admin/mod of boundcovers.com (a bookwyrm instance) here.

The way a number of activitypub status posters (ie, Mastodon, Takahe) work is by having a client API deliberately from the activitypub APIs. My read is the core development teams behind most activitypub server software see AP as closer to a server-to-server protocol than a client<>server<>server<>client protocol (whether this is against the spirit of AP is a discussion for the spec working groups, not this thread, I feel)

Given that, my question for folks like @mouse-reeve is: If work were to start via PR on adding a fuller client API to bookwyrm, is that work welcome? or not in the spirit of what y'all are trying to do?

phildini avatar Mar 29 '23 03:03 phildini

Wdym, we want an api. That's the point of this gh issue.

I don't have experience with ActivityPub, only rest/graphql apis

pabloscloud avatar Mar 29 '23 07:03 pabloscloud

Given that, my question for folks like @mouse-reeve is: If work were to start via PR on adding a fuller client API to bookwyrm, is that work welcome? or not in the spirit of what y'all are trying to do?

A client API would be extremely welcome!

mouse-reeve avatar Mar 29 '23 15:03 mouse-reeve

Wdym, we want an api. That's the point of this gh issue.

I don't have experience with ActivityPub, only rest/graphql apis

But since they mentioned something was doable, I asked them how to do it so I don't have to wait forever for the API

thiagomgd avatar Mar 29 '23 19:03 thiagomgd

You can see a shelf; for example, this is my to-read shelf: https://bookwyrm.social/user/mouse/shelf/to-read.json?page=1

Neat, this is nearly exactly what I needed (working on a lil Hugo shortcode for displaying a user's recently read or to-read books) with the exception that author details are provided as an URL rather than a readable name and there's not an API endpoint for an author yet.

Alternatively a user's RSS feed (#2610) is close to what I need but without a date #2699, it's tricky to limit to recent activity.

(Sorry if this is just adding noise to this issue, just thought I'd share a use case if this becomes a design discussion.)

dijitali avatar May 14 '23 05:05 dijitali

To add another use-case: I would like to write a plugin for my reference manager, which synchronises my (academic) books, lists and reading dates with bookwyrm. Obviously a good api would help with that.

Hugo-Heagren avatar Dec 18 '23 10:12 Hugo-Heagren

And another use-case: an API would (could? might?) allow us to write external programs for adding books, which could streamline the process of adding cool things I find (e.g. if the external program was a firefox extension).

This came to me just now: I saw a recommendation for a cool book on reddit, in a an academic subject. I googled to see if it was legti/well-reviewed. It is, so I wanted to add it to my bookwyrm. At this point, I had the amazon page, the wikipedia page and an academic review open in different tabs. A least the amazon and wiki pages present enough strucured information that a plugin could be developed to grab the ISBN. An API would let me just click once and add the book to my to read shelf. Zotero works this way and people love it.

Hugo-Heagren avatar Jan 04 '24 10:01 Hugo-Heagren

for what it is worth, I stumbled across BookWyrm because GoodReads no longer has a client API, and I would happily move to something else that did have one and has a chance of surviving (BookWyrm being federated helps checks this box for me). maybe I'm not alone?

JaredCorduan avatar Jan 08 '24 14:01 JaredCorduan

I've been doing some poking around and thought I'd share what I found for any potential implementers who are less familiar with the code base in case it makes it a little easier to jump into (I'm not very familiar either, to be fair, so take this with a grain of salt).

Based on this very helpful comment, it seems there are a few more json "apis" that I can't find documentation for, but do seem to exist:

  • Shelf: https://bookwyrm.social/user/mouse/shelf/to-read.json?page=1
  • Search: https://bookwyrm.social/search.json?q=all+the+light+we+cannot+see&type=book
  • User: https://bookwyrm.social/user/CombatWombatEsq.json
  • Review: https://bookwyrm.social/user/Tania/review/2253463.json
  • Followers: https://bookwyrm.social/user/CombatWombatEsq/followers.json

I'm still digging through the code, but it looks like the json serializing is happening for objects that inherit from ActivityObject because Django auto-attempts to parse results to json when the .json extension is passed in the url, but I'm not entirely certain.

doug-wade avatar Jan 24 '24 01:01 doug-wade