You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
All ORM model queries like User.query().get() should be able to query the local database OR switch to remote API mode and the query will be converted to a aiohttp request.
The goal is to pull this off without a syntax change. If you had to change syntax, this wouldn't work. All you should have to do is change your database config from local MySQL to remote uvicore_api. No code change.
How can we possibly do this? The complication is that when using remote mode, the aiohttp request needs an authentication token. This token can come from a controller route or from some backend ~/.config/myapp.json file during CLI "login" command. Either way, the ORM query must know about this token somehow.
Examples:
From a controller. The route already has the request, and the authorization or www basic auth header is already there. So we need to get it into the ORM query
The query() method will see a request and only if config remote=true will it grab the authorization or www headers and pass them into the API QueryBuilder for aiohttp usage. If config remote=false, this variable is ignored. This means the code is consistent, and doesn't change. It feels odd if you never need to use remote=true, but if you ever do, code does not need to change.
From some command line where the token is in a ~/.config/myapp.json file
user=IamUser.query().include('tenant').get()
Notice nothing in query()? You can override query() with your own and if remote=true then look up token in ~/.config and inject it. If remote=false, just ORM local as usual.
All of this means that your remote API must be able to use the same TOKEN as the one you are currently using. Lets say we have a tools CLI app. You run ./uvicore tools login and enter user/pass, it calls remote IDP gets token, stores token in ~/.config. Your tools app wants to query a remote IAM uvicore app. That IAM API must also understand the current Tools token. This works fine if you own both APIs and both authenticate with the same token. You are just passing whatever auth method in Tools on to IAM. If they don't use the same token, Tools would have to "login" to IAM's IDP as well and store an IAM compatible token to pass through, which wouldn't be in the request header. So your query() override needs to be able to handle all this work.
Also, if a middleware could pull out your authorization token, store in a common location (some constant variable), then you wouldn't need to pass request into query(request) at all! Just plain old User.query().get() would still work. Override the query() method and search for an auth header in your special place, or if from CLI, use ~/.config... NO probably not, its not per user, your token storage would get clobbered.
Here are some notes I had in a py file
# Cross api usage# Lets say this is TOOLS app and I want to query IAM from IAM APItoken=request.headers.get('Authorization') # MINUS bearer# So this is an API SDK helper. It GET on a URL# and passes in existing TOOLS token, which should work in IAM too# Token must be passed around, which means I cannot query IAM from a non logged in# CLI app. I always need a FA token. So even CLI apps and cron tasks need a login# to get an access token.user=iam.get('/sun/users/1', token)
# Could work, but model would need to know its in local DB mode# or remote API mode.user=IAMUser.query(token).include('tenant').get()
# Or add a api() method on the model that has its own query builder COPY for APIs# This is a uvicore specific API query builderuser=IAMUser.api(token).include('tenant').get()
# If using basic authuser=IAMUser.api(username=username, password=password).include('tenant').get()
# Or to keep query identical, do a login first and get new logged in instance# presenes of a login would swap from local ORM mode to remote API mode?User=IAMUser.login(token) # Login function could look at a CONFIG for remote=true, if false ignore login use ORMuser=User.query().include('tenant').get()
# Or all in one I suppose same thinguser=IAMUser.login(token).query().include('tanant').get()
# Guess the query() itself could detect the login, only if config remote=trueuser=IAMUser.query(token).include('tenant').get()
# Maybe you can set a token for ALL models in this requestIam.login(token) # though if not instance, will collide with multiple user requestsuser=IAMUser.query().include('tanent').get()
app=IAMApp.query().get()
The text was updated successfully, but these errors were encountered:
All ORM model queries like
User.query().get()
should be able to query the local database OR switch to remote API mode and the query will be converted to a aiohttp request.The goal is to pull this off without a syntax change. If you had to change syntax, this wouldn't work. All you should have to do is change your database config from local MySQL to remote uvicore_api. No code change.
How can we possibly do this? The complication is that when using remote mode, the aiohttp request needs an authentication token. This token can come from a controller route or from some backend
~/.config/myapp.json
file during CLI "login" command. Either way, the ORM query must know about this token somehow.Examples:
From a controller. The route already has the request, and the authorization or www basic auth header is already there. So we need to get it into the ORM query
The query() method will see a request and only if config remote=true will it grab the authorization or www headers and pass them into the API QueryBuilder for aiohttp usage. If config remote=false, this variable is ignored. This means the code is consistent, and doesn't change. It feels odd if you never need to use remote=true, but if you ever do, code does not need to change.
From some command line where the token is in a
~/.config/myapp.json
fileNotice nothing in query()? You can override query() with your own and if remote=true then look up token in
~/.config
and inject it. If remote=false, just ORM local as usual.All of this means that your remote API must be able to use the same TOKEN as the one you are currently using. Lets say we have a
tools
CLI app. You run./uvicore tools login
and enter user/pass, it calls remote IDP gets token, stores token in~/.config
. Your tools app wants to query a remote IAM uvicore app. That IAM API must also understand the current Tools token. This works fine if you own both APIs and both authenticate with the same token. You are just passing whatever auth method in Tools on to IAM. If they don't use the same token, Tools would have to "login" to IAM's IDP as well and store an IAM compatible token to pass through, which wouldn't be in the request header. So your query() override needs to be able to handle all this work.Also, if a middleware could pull out your authorization token, store in a common location (some constant variable), then you wouldn't need to pass request into query(request) at all! Just plain old
User.query().get()
would still work. Override the query() method and search for an auth header in your special place, or if from CLI, use ~/.config... NO probably not, its not per user, your token storage would get clobbered.Here are some notes I had in a py file
The text was updated successfully, but these errors were encountered: