The current implementation expects the user to instantiate a handle to an IRODSHTTPClient. On construction, instantiations of many classes such as Collections, DataObjects, Rules, etc. happen. These are stored inside of the IRODSHTTPClient.
To use the newly created instance, the user must set the user token. Now the client is ready for use. If the user wants to do work for a different user, they have two options:
- (A) Instantiate another handle resulting in several hidden instantiations of classes
- (B) Or, save the token of the existing user and call
setToken at the appropriate time
All of this is fine for an application which is designed to manage one, maybe two users. However, if someone wants to write a server which is responsible for managing many hundreds to thousands of users, the API doesn't hold up as well.
To fix this, we should remove the need for handles. This should be possible due to the fact that there's no true state in the client implementation. The entire implementation can be a set of free functions. The most difficult part of this exercise is designing an auth mechanism which supports Basic (Native) and OIDC.
Here's an example of what the API could look like.
# IRODSBasicAuth stores the token on a successful auth. If any function
# receives an authorization error and refresh_token is true, the IRODSBasicAuth
# instance is automatically used to get a new token.
username = 'alice'
password = 'apass'
alice_session = IRODSBasicAuth(username, password, refresh_token=True)
# Use the session object to interact with the HTTP API.
result = IRODSCollections.create_collection(alice_session, lpath)