Variable scoping in KDB - kdb

getQuotes: {[sym;start;end]
url: f[sym;start;end]
{some_test} {request.quotes[url;x`next_page_token]} \ request.quotes[url;0b]
}
I have a while loop. The issue I'm having is that url is out of scope for the while lambda:
'url
[2] alpaca.q:47: .alpaca.getQuotes#:{request.quotes[url;x`next_page_token]}
^
I have read on this post that this is by design:
Variable scope propagation in k, but it doesn't really give me a solution.
I've tried to wrap it in a unary, which didn't work.
I made url global with url::, this did work, but it's not very clean.
Is there a preferred pattern for passing url into the lambda?

You can pass variables into the inner lambdas as parameters:
getQuotes: {[sym;start;end]
url: f[sym;start;end]
{some_test} {[x;url]request.quotes[url;x`next_page_token]}[;url] \ request.quotes[url;0b]
}

Related

authlib: some client_kwargs in config are not used

Love authlib overall. Question about client_kwargs described in
https://docs.authlib.org/en/latest/client/frameworks.html
and https://docs.authlib.org/en/latest/client/django.html
Problem statement: I tried to pass "scope" and "audience" key/value pairs in the client_kwargs dict, but only "scope" key/value is used for generating URI for authorization.
I need to pass "audience" for Atlassian OAuth2.0 https://developer.atlassian.com/cloud/jira/platform/oauth-2-authorization-code-grants-3lo-for-apps/
Workaround found after some tinkering by passing "audience"="api.atlassian.com" to oauth.atlassian.authorize_redirect.
Question: Is client_kwargs in oauth.register/AUTHLIB_OAUTH_CLIENTS intended only for certain keyword arguments? If so, would be great to share it in the documentation; otherwise it would be convenient to set it in config together with everything else.
This behavior was found in 0.12.1 and 0.13.dev0.
Thanks!
Because OAuth 1.0 and OAuth 2.0 are different, this client_kwargs are designed to pass extra parameters to either OAuth1Client/OAuth1Session or OAuth2Client/OAuth2Session.
For your case, there is a authorize_params. You can put audience in your authorize_params:
oauth.register(
....
authorize_params={'audience': '...'},
....
)

How to use : colon char in Bottle route

I have simple Bottle route, and URL should contain : (colon) sign. URL should be like /REST/item:128 or /REST/item:89753
My route is
#route('/REST/item:<id:int>')
def icc(id):
return { 'id': id }
Route is not working properly. id contain only last char from url id, not full id.
How to use : (colon) in route?
Wow, this was confusing.
I haven't had time to fully understand what's happening, but I suspect that one of Bottle's route regexes is eating too many characters when there's a colon in the route.
In any case, escaping the colon with a backslash appears to solve the problem:
#route(r'/REST/item\:<id_:int>') # note the "r" prefix there
def icc(id_):
return {'id': id_}
Here's a test request and its response:
=> curl -v 'http://127.0.0.1:8080/REST/item:123'
{"id": 123}
EDIT: Mystery solved.
Bottle currently supports two syntaxes for url wildcards: The
one (since 0.10) and the :old syntax. Both are described here:
http://bottlepy.org/docs/dev/routing.html
In your example, the : triggered the old syntax. The solution is to
escape the colon with a backslash (as described in the SO answer).
Escaping is fully implemented and works as intended, but is
undocumented. This is why I leave this issue open. Pull requests for
better documentation would be welcomed.

How to access invoke response object variable in following steps of assembly

the assembly of my API Connect API contains two invokes. The first is calling an internal routing API to get some routing information. The response of this routing API should not be passed to the second invoke.
If I do not configure a 'response object variable' in the invoke of the routing API, the original request body is overwritten and the second API gets the result from the routing API as request body. And if I specify a 'response object variable' in the routing invoke, I can not access the content (json) of this variable in the following steps.
How can I solve this issue?
Thx 4 help.
Rather than relying on reading the request object, you can read from your configured 'response object variable' later on in the flow. For instance, if your first invoke has a response object variable set to 'resp1', you can access the JSON payload using '$(resp1.body)' later on in the flow. Using this technique will allow you to store the response of each invoke in a separate object, avoiding the overwriting issue. These response object variables can be read just like any other context variable in the flow.
For more info, check out these links in the Knowledge Center:
Invoke Policy: https://www.ibm.com/support/knowledgecenter/en/SSMNED_5.0.0/com.ibm.apic.toolkit.doc/rapim_ref_ootb_policyinvoke.html
Context Variables:
https://www.ibm.com/support/knowledgecenter/SSMNED_5.0.0/com.ibm.apic.toolkit.doc/capim_context_references.html
I don't understand this part:
[...] "And if I specify a 'response object variable' in the routing
invoke, I can not access the content (json) of this variable in the
following steps." [...]
Why can't you access the content of this variable in the following steps?
Save copy of the request...
... that you received. What I'd do is always save a copy of the data received in the invoke to a processed variable instead of the (raw) original request.
In your GatewayScript try something like this:
let objRequest = apim.getvariable("request");
let body = null;
Here I recommend you to change the body (if json) to a standard js object
if(objRequest && objRequest.hasOwnProperty("body")){
try{
body = JSON.parse(objRequest.body);
}catch(e){
body = objRequest.body;
}
}
Remember to stringify the complete object before saving it as global variable. Is the only way to store it (because you can only store a string value in this kind of variables)
apim.setvariable("objRequest", JSON.stringify(objRequest));
Retrieve copy of the request...
...that you have saved in global variables you can get it from any other GatewayScript that you want this way:
let objRequest = JSON.parse(apim.getvariable("objRequest"));
Be careful not to assign an existent name to the apim.setvariable(name, value) because if you use "request" as name instead of "objRequest" (or other), you'll be replacing the original request element, and we don't want that to happen.
If you need to set or retrieve the status.code...
...you can do it with:
let statusCode = objRequest.body.status.code;

Can't pass parameter to reverse router in playframework

I have defined a route like this:
GET /login controllers.Login.showForm(continue: Option[String] = None)
Login.showForm is this:
def showForm(continue: Option[String] = None) = Action { implicit request =>
val nextPage = continue match {
case None => routes.CtrlIndex.index().absoluteURL().toString()
case Some(page) => page
}
Ok(views.html.login(nextPage))
}
Now, using action composition I made an authenticated action that performs this when the user is not authenticated:
val continue =
if (request.method == "GET") request.uri
else routes.CtrlIndex.index().absoluteURL().toString() // This is not code duplication for reasons that are out of the scope of this question.
Redirect(routes.Login.showForm(Some(continue)))
This fails to compile with this message:
too many arguments for method showForm: ()play.api.mvc.Call
[error] Redirect(routes.Login.showForm(Some(continue)))
Changing the route definition makes it work:
GET /login controllers.Login.showForm(continue: Option[String])
But then when I use the javascript reverse router, it generates the following error in the generated javascript:
SyntaxError: missing formal parameter
function(continue) {
---------^
I have tried all combination of the definition of the function signatures but when the javascript works, the other stops working or the other way around. How can I use
Optional parameter on /login
Use the reverse javascript router
Redirect to /login with the "continue" parameter
I would also like to change request.uri for something that returns an absolute path.
Thanks in advance
PS. If you see something in Spanish, let me know and I'll fix it, the code is originally in Spanish; I may have missed something even after I read it.
The likely cause is that "continue" is a reserved word in javascript
Play's javascript reverse router constructs a given route using the controller path and method argument(s) specified in the routes file; in your case, "continue" may be tripping up the js parser, much like a method named "delete", which works fine server-side but will blow up in the client-side reverse router.
This may be a non-issue for newer browsers, but have been bitten by "delete" method name on older versions of Internet Explorer (that we are required to support).

how to pass parameter in facebook redirect_uri

I'm using https://graph.facebook.com/oauth/authorizeclient_id=APP_ID&redirect_uri=MY_URL&scope=user_likes,friends_likes
to get permissions from user to access his information. after that i'm being redirected to MY_URL, the problem is that i need to pass a parameter to MY_URL.
i would like to do something like:
MY_SITE?parameter=test.
how do i do it without mixing with outer parameters?
thanks!
Use urlencode(MY_URL) instead of MY_URL
Replace MY_URL with encodeURIComponent(MY_URL) using javascript. For example:
window.location = 'https://graph.facebook.com/oauth/authorizeclient_id=APP_ID&redirect_uri='+encodeURIComponent(MY_URL)+'&scope=user_likes,friends_likes';