Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using Kerko in multi-user settings #47

Open
pmkrawczyk opened this issue Apr 5, 2024 · 9 comments
Open

Using Kerko in multi-user settings #47

pmkrawczyk opened this issue Apr 5, 2024 · 9 comments
Labels
question Further information is requested

Comments

@pmkrawczyk
Copy link

Hi!
I was wondering whether it would be possible to use Kerko in multi-user settings, i.e. make it serve content obtained from Zotero using different API keys, depending on user? The context for this question is embedding Kerko in another web app (online text editor)

Thank you in advance!

@davidlesieur
Copy link
Member

Are you looking at serving the same Zotero library to all users? If so, then only a single API key is needed for that library. Kerko will cache the library using that API key. User interactions happening in Kerko only deal with Kerko's cache and do not trigger any Zotero API calls.

I hope this helps!

@davidlesieur davidlesieur added the question Further information is requested label Apr 5, 2024
@pmkrawczyk
Copy link
Author

Thank you for your quick reply! :-)
I'm looking at serving different Zotero libraries using different API keys by different users (one user >> one API key + potentially multiple libraries). So I guess I would need a separate cache for each API key+library combo. Maybe with a bit of tinkering these could be set dynamically on init? Would you have any recommendations?

@davidlesieur
Copy link
Member

I suspect the task might end up being more than "a bit" of tinkering, unfortunately, as Kerko was not designed with such use case in mind. The configuration structure, CLI commands and views are designed for a single cache and a single search index, and all would have to be modified. URL routing would also have to be modified to identify which library to serve.

At the moment, having a separate KerkoApp instance for each user is the easiest way. All instances can still share the same code, but each would run in a separate process, and have its own configuration files, cache and search index, whose paths would derive from the KERKOAPP_INSTANCE_PATH environment variable, which would specify a different path for each instance). The HTTP server would have to be configured with a different base URL for each instance. However, that strategy may not scale well if you have a large number of instances.

@pmkrawczyk
Copy link
Author

Thank you for the explanation! I did look at the code earlier (albeit briefly) and thought that at the root is the storage.py where the local storage directory is defined, which is then used for the index. So if one could maybe make this base directory defined dynamically based on the API key / library id / user data inherited from request, then the rest of the app would be potentially not even aware that it is dealing with different users / libraries at all. Your code is beautifully modular and well-organized and neat, which makes me suspect this might work. What do you think?

@davidlesieur
Copy link
Member

Yes, some sort of library id could come from the request and be used to select the right storage directory. However, the configuration system would still have to be adapted for multiple libraries. Some configuration parameters impact the structure of the search schema. Also, configuration is accessed from various places (usually though the config() and composer() shortcuts in Python code, or though config.kerko or config.kerko_composer in templates), and all those access points assume they're dealing with a single library and a single set of parameters.

Perhaps not a huge amount of code would have to be changed to support the "multiple libraries" use case, but I suspect there could be small changes in many places. Still, that might be worth trying! But then if you have those changes in a fork, they might become hard to maintain in sync with Kerko on the long run. I wouldn't necessarily be against merging such changes into Kerko, but that would require extra care so that the single-library use case does not become more complicated.

@pmkrawczyk
Copy link
Author

Allright!:-)

Some configuration parameters impact the structure of the search schema.

But this just means that all users/libraries would need to have identical configuration parameters, right? Not a deal breaker for our use case.

@davidlesieur
Copy link
Member

Some features need configuration parameters that can't be identical for everyone, e.g., facets based on collections (need collection ids), content pages based on notes (need item ids). But perhaps you don't intend to use any feature of that kind.

@pmkrawczyk
Copy link
Author

Indeed, to start with it's probably a good idea to keep it simple and exclude such features (could be added later).

Now, what is remaining is to figure out how to hook up the storage settings to requests. In our use case, Kerko would run inside of an iframe (at least initially - again, to keep it simple) served from the same domain as our main application. This means that all our session cookies would be automatically added by the browser to all requests originating from the iframe. So user authentication would be taken care of. But would you have suggestions on where in the Kerko code to intercept the incoming request, ask our main application for user storage settings, and pass this information to Kerko init?

@davidlesieur
Copy link
Member

Cookies can be read from the Flask request object, which you can import from pretty much anywhere. You'll find more details in the Flask documentation. In theory, you could access the request object directly from within functions such as kerko.storage.get_storage(). In practice, there may be cases where such functions are called by Kerko outside of a request context (e.g., from the CLI commands), so you'll have to determine how to deal with those cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants