obsidian-api-request icon indicating copy to clipboard operation
obsidian-api-request copied to clipboard

FR: Preventing repeated requests to the API

Open elvarb opened this issue 1 year ago • 13 comments

Is your feature request related to a problem? Please describe. Many API's are rate limited by tier or cost each time it is used. The plugin sends a request out to the API each time the page is loaded regardless if there is need to update the data itself.

Describe the solution you'd like Few options that would work to limit repeat calls.

  1. Offer a setting that will automatically call the API if N amount of time has passed since the last call. This would require storing the last request time in some way, could be done with a custom defined property within the code block. If there is nothing in the file property for that custom name then call the api. If a datetime is stored there compare the time difference between than and now, evaluate as stated in the codeblock. The Period could be defined in the codeblock as is in ISO8601 (https://en.wikipedia.org/wiki/ISO_8601#Durations)

  2. Offer a setting to be used in the code block that will present a button in Obsidian labeled "Refresh", or "Recall", or better yet have the text customizable. Offering the same custom defined property in the code block as above to store when the API was last called could be helpful as it can be used to present to the user how old the data is.

I think the second option would probably be simpler to implement and be good enough for most use cases.

Describe alternatives you've considered Only alternative solution I can think of is running a reverse proxy locally with lots of caching to prevent repeated api requests (I have done this in the past for a different use case)

elvarb avatar Jun 27 '24 12:06 elvarb

There are ways to prevent multiple calls to an API, you could use the disabled flag and assign a req-id to save the response and not call the API again, unless you remove the disabled flag. It is not the most practical or intuitive, but it is an option.

Some time ago I was thinking about adding the Recall button, but I didn't do it because the current code is a complete mess. Everything is mixed up and there are no defined functions. I need to organize everything to be able to add something like this

Maybe for the moment, the first option is more feasible, to add a flag like rep-req-after: X or something like that.

Rooyca avatar Jun 27 '24 17:06 Rooyca

Totally understand, this can be a backlog enhancement for later.

Regarding the option of using racall. Would that work if I had many files which include the api request codeblock from a templater template, meaning they all use the same codeblock. If one sends out a requests and sets a req-id, wouldn't the same req-id be used when viewing the next file?

elvarb avatar Jun 28 '24 10:06 elvarb

Regarding the option of using racall.

Do you mean using the actual mode (disabled with req-id) or the "new mode" (that is not yet implemented) rep-req-after: X?

Ether way, the actual mode use localStorage so responses can be access from every file that has the same req-id (the disabled is just to prevent new calls to the endpoint). I would imagine the new mode would reuse the same idea. The response would be stored in localStorage and would be reusable from any code-block (from any document) with the same req-id.

Rooyca avatar Jun 28 '24 17:06 Rooyca

Totally understand, this can be a backlog enhancement for later.

I had try to clean up the code so many times but I always end up overwhelm haha. One day tho; for sure.

Rooyca avatar Jun 28 '24 17:06 Rooyca

Do you mean using the actual mode (disabled with req-id) or the "new mode" (that is not yet implemented) rep-req-after: X?

I mean using the "new mode" and the way you describe it I think that way could potentially solve some use cases but not all.

  1. You could have either an API that you want to use very sparingly. The new mode would work here.
  2. Or you could have an API that you use in many places but there is no need to always refresh the information for each codeblock every time you render the file

elvarb avatar Jun 30 '24 23:06 elvarb

If you have the same code block in different documents but you don't want the response of one document to be the same for all of them you can use different ids.

Something that could be implemented would be an option to add or remove the "Run" button in the code-blocks. If the button is enabled run the request only the first time it is defined and every time the user presses the button. If it is disabled, run the requests every time the document is reloaded (the way they run right now).

Rooyca avatar Jul 01 '24 02:07 Rooyca

Good points, is it possible to use the file name or some other file property to define the id ?

elvarb avatar Jul 02 '24 09:07 elvarb

Perhaps we can use the name as id, filename+path to prevent repeated names.

Rooyca avatar Jul 03 '24 02:07 Rooyca

Having that option would be great, that would open the option of limiting the queries by file and by the api 👍

elvarb avatar Jul 04 '24 09:07 elvarb

I don't know if that would make a good ID, because we can have multiple code-blocks within a single file.

Rooyca avatar Jul 04 '24 20:07 Rooyca

That's a good point, but I think that could be mitigated.

Just an hypothetical use case. Lets say you have a template for Movies which you want to use to log all movies you watch with some insights from yourself.

The template has an api request which will pull from IMDB some information, you have a block that calls the API to get basic information, it will use the filename to query the movie from the API. Filename is "The Matrix (1999)". This request will return the IMDB score, length, etc.

There is also a second block that queries the top actors.

Within each block will have the ID defined as filename+path as a variable but also include custom text used for that block. So it could end up as IMDB-API Movie The Matrix (1999) /movies and then IMDB-API Actors The Matrix (1999) /movies

elvarb avatar Jul 08 '24 12:07 elvarb

Yeah, and the Movie and Actors part from: IMDB-API Movie The Matrix (1999) /movies and IMDB-API Actors The Matrix (1999) /movies would be defined by the user? So, if I understand correctly the requests will be something like these:

```req
req-id: IMDB-API Movie 
url: https://example.com
```
```req
req-id: IMDB-API Actors 
url: https://example.com
```

And under the hood the complete ID will be filepath+req-id right?

Rooyca avatar Jul 08 '24 21:07 Rooyca

I think it would be best to present the user with a few functions directly

  • filepath
  • filename
  • maybe a file property? can't see a use case for this as is

If we focus on the first one we could have it configured like

req-id: IMDB-API Movie {{filepath}}
url: https://example.com
req-id: IMDB-API Actors {{filepath}} {{filename}}
url: https://example.com

That would allow lots of flexibility

elvarb avatar Jul 10 '24 17:07 elvarb