Is it possible to get raw data from a Metabase MBQL / SQL query via the REST API? - sql

Is there a Metabase REST API that takes a MBQL/SQL query and returns the raw data?
I can perform a MBQL query via the API in a 2-step process by doing the intermediate step of creating a Question via the Metabase web app UI and then querying the Question, but I haven't figured how how to combine MBQL with the REST API in a single step.
Some items I'd like to accomplish by having the MBQL in the API request instead of a UI-generated Question:
better version management as the MBQL query can be checked into source control with the code
better isolation as the API call won't be dependent on the question which can change
Here's some info on how to perform the 2-step process.
2-Step Process
The two step process is:
Use web app to create a MBQL/SQL Metabase Question
Use REST API to query existing Question created in web app using the Card API
Step 1) Creating Question via Web UI
Log into the web app and click the "New Question" button in the top menu.
Once your question has been created you will be directed to a URL like the following where :question-id is an integer.
Web UI endpoint: GET /question/:question-id
Note this value and use it in the API in the next step.
Note: an alternative for creating the card is to use the POST /api/card API endpoint per YakovL. This can be useful in some scenarios were UI questions/cards are desirable, but I'm also trying to avoid creating creating cards / questions in the first place, since I'm not planning on using the Metabase UI to consume them. Reasons to avoid cards for me include needing to perform extra work to verify the card query definitions haven't changed but still having the SQL in the code to create the cards, and generate a lot of unneeded question cards in the UI.
Step 2) REST API for Question Data
The API uses the term "card" for the Web UI "question" object, so make an API call to the following Card API:
API endpoint: POST /api/card/:card-id/query/:export-format
In this URL:
:card-id is the :question-id from the Web UI URL
:export-format can be json or another format
More information on the API is available in the API Documentation:
https://github.com/metabase/metabase/blob/master/docs/api-documentation.md
Question
Is there a way to do this directly by sending the MBQL/SQL query in the API request in a single step without a pre-existing Question/Card?

Querying via raw SQL and MBQL are both available via the POST /api/dataset/ API. The documentation for the endpoint mentions the query request definition but does not define it.
I ended up doing some more research and asking on the Metabase Discourse forum. The following examples were posted by sbelak.
Raw SQL Query
I was able to successfully make a native SQL query using the go-metabase SDK to make the following request:
POST /api/dataset
Content-Type: application/json
X-Metabase-Session: <sessionId>
{
"database": 1,
"native": {
"query": "SELECT COUNT(*) FROM orders"
},
type: "native"
}
Notes:
The POST /api/dataset does not set the response Content-Type header.
There is a POST /api/dataset/json endpoint, but that does not seem to accept the native property.
To set X-Metabase-Session see github.com/goauth/metabase.
MBQL
POST /api/dataset
Content-Type: application/json
X-Metabase-Session: <sessionId>
{
"database": 1,
"type": "query",
"query": {
"source-table": 2,
"breakout": [
[
"binning-strategy", ["field-id", 14], "default"
]
],
"aggregation": [["avg", ["field-id", 17]]]
}
}
Notes:
To set X-Metabase-Session see github.com/goauth/metabase.

Related

Whatsapp Cloud API Update Profile Picture

I'm trying to upload an image as profile picture using WhatsApp Cloud API *.
After creating an application using WhatsApp Cloud API I'm not allowed to access neither using the regular application nor using Business Application. It says something like "try again in one hour". So I have to implement everything using the API.
After reading the docs and importing Postman Endpoints I found the one called Business Profiles > Update Business Profile
https://graph.facebook.com/{{Version}}/{{Phone-Number-ID}}/whatsapp_business_profile
It has a field "profile_picture_url"and I have tried POSTing media https://graph.facebook.com/{{Version}}/{{Phone-Number-ID}}/media and then with the given ID y used https://graph.facebook.com/{{Version}}/{{Media-ID}} to get the URL but it didn't work. The rest of the information is updated successfully
{
"messaging_product": "whatsapp",
"address": "",
"description": "Simple Bot",
"email": "...#gmail.com",
"websites": [
"https://..."
],
"profile_picture_url": "https://lookaside.fbsbx.com/..."
}
However if I try to send someone using the ID and the endpoint https://graph.facebook.com/{{Version}}/{{Phone-Number-ID}}/messages it works fine.
And if I use Download Media Content with the URL in Postman it works fine too.
I don't know if I have misunderstood something or if it can't be done using the API.
It is mentioned in the Cloud API Documentation:
profile_picture_url (Optional): URL of the profile picture generated from a call to the Resumable Upload API.
But, i got it working using profile_picture_handle instead of profile_picture_url. So how do we get the profile_picture_handle?
Prerequisite:
Graph API token here. Or use your WhatsApp Cloud API token.
App ID, go Apps > Your App > Settings (sidebar menu) > Basic
Update Photo Profile:
Call POST https://graph.facebook.com/v14.0/{{appId}}/uploads?access_token={{token}}&file_length={{fileSizeInByte}}&file_type=image/jpeg
Save the session id you got, upload:XXXXXX?sig=XXXXXX.
Call POST https://graph.facebook.com/v14.0/{{sessionId}}, with the headers: Authorization=OAuth {{token}}, file_offset=0, Host=graph.facebook.com, Connection=close, Content-Type=multipart/form-data, and include your image file in the request body with type binary. If you using Postman, see image below (This is what I missed for hours).
Save the handle result you got, 4::XXX==:XXXXXX.
Finally, call POST https://graph.facebook.com/{{Version}}/{{Phone-Number-ID}}/whatsapp_business_profile, with json request body: {"messaging_product": "whatsapp", "profile_picture_handle": "4::XXX==:XXXXXX"}
That's it, You can check the profile picture.
The last step you have to add your taken by selecting "Bearer" or else it will give you error. I had hard time on the last ones, do all the steps and then go to the following link and it should help.
https://web.postman.co/workspace/My-Workspace~a4ddb3b8-02a3-4132-8384-66e63e149b7b/request/22958165-506a0542-c845-41ac-b3fb-b8209fd6f53b

Jira - XRay- How to get the total of defects created during a test execution

I'm creating a script that goes into all tests into a test execution. I'd like to get the amount of defects for that particular test execution. Is that a way to get it using rest api?
Xray enables exporting Cucumber tests to be exported as .feature file that further can be used in your automated tests. To do so use this export endpoint
To import the automated test results back to Jira used this import endpoint
Usually APIs will be executed in conjunction with CI/CD tools, like Jenkins.
In this article you can see that the total number of defects can be view via the Jira UI.
And finally, this video shows how tests are imported and exported via the UI.
Tests can be created via API as well, see here.
I think it all depends on your testplans. When those contain all tests you should be able to execute the test via the endpoint rest/raven/1.0/api/testexec/<testExecution>.
Maybe it will be good to ask the very same question in the atlassian community.
Sorry for not being able to fully answer your question, but I think you now should have some things to read :)
There is one way that is more straightforward.
You can make use of the "Test Execution Defects" custom field, which is a calculated field.
Then you just need to use Jira's REST API and obtain information for the related Test Execution issue, for that specific custom field that returns an array. The number of elements corresponds to the number of defects.
Example of HTTP GET request:
https://sandbox.xpand-it.com/rest/api/2/issue/BOOK-31?fields=customfield_11802
Example of response:
{
"expand": "renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations",
"id": "20130",
"self": "https://sandbox.xpand-it.com/rest/api/2/issue/20130",
"key": "BOOK-31",
"fields": {
"customfield_11802": [
"20131"
]
}
}
Another way would be to use the JQL function "defectsCreatedDuringTestExecution ()", as mentioned here: https://docs.getxray.app/display/XRAY/Enhanced+querying+with+JQL
Then you could do a Jira REST API search call.
Example of HTTP GET search request using the JQL function:
https://sandbox.xpand-it.com/rest/api/2/search?jql=issue%20in%20defectsCreatedDuringTestExecution(BOOK-31)

Authentication issue using Rally WebServices

I am trying to call some Rally WebServices from an App inside Rally to update Portfolio Item details (SubFeatures) and I hit a problem that a search on Stack OVerflow indicated I needed to use:
https://rally1.rallydev.com:443/slm/webservice/v2.0/security/authorize
When I GET this it requires me to log in with my Rally userID/Password.
How should I use this properley from within a Rally App so as to not need this authentication since i am already logged in.
As a secondary factor, ulrimately I am to call 'https://rally1.rallydev.com/slm/webservice/v2.0/portfolioitem/' + id
and I assume I would need to pass something like: { "PortfolioItem": { "Description": "hello" } }
Am I barking up wrong trees there?
Thanks
Martin
Are you manually wrangling the ajax calls yourself? App SDK 2.0 does a lot of this for you (including the security token piece mentioned above). Check out this example, which demonstrates performing a full CRUD lifecycle within an app:
https://help.rallydev.com/apps/2.0rc2/doc/#!/guide/data_models

Some general restful api design questions

A few general design questions:
Give the example here:
https://developers.google.com/+/api/latest/activities/list#nextPageToken
Why would the server return a token to retreive the next paginated result? Doesn't this break the idea of being stateless?
Why not just pass a MySQL like LIMIT name=value as the parameters? The server now has to return the number of pages I suppose...what am I missing?
I read many but this one was of interest:
REST Web Services API Design
The second reply, offers the following examples.
GET http://api.domain.com/user/<id>
GET http://api.domain.com/users
PUT http://api.domain.com/user/<id>
POST http://api.domain.com/users
DELETE http://api.domain.com/user/<id>
Makes sense but why are there two plural resources? Could one not assume that if "user" is queried and was NULL or not provided that "all" was intended? Likewise for POST? If plural is for improved readability - why is there not a "users" resource for DELETE?
Ultimately, I understand REST to mean...representation of a single resource - using HTTP verbs (GET, PUT, POST, DELETE) to essentially manage that resource - similar to CRUD.
EDIT | Lastly I also wanted to ask why Google API sends the API version in the URI instead of using HTTP headers? Is there a reason? For backwards compat with older clients?
Comments?
Why would the server return a token to retrieve the next paginated result? Doesn't this break the idea of being stateless?
Using this kind of mechanism for paginated result sets is completely standard and does not break the idea of being stateless. Consider the following example.
Suppose GET /users?after=<after> (where after is optional) is supposed to return the list of all users in a paginated fashion, say <= 4 per page.
The first request a client makes is GET /users with a response that might look like the following (formatted as JSON).
{
"users": [ "alex", "bob", "carter", "dan" ]
"more_after": "dan"
}
In this example, the more_after property designates there may be more users left in the user list. So the client then requests GET /users?after=dan and gets a second response that looks like the following.
{
"users": [ "edward", "frank" ]
}
The absence of the more_after property designates that this is the last page of users.
Now the question is: was the "dan" token used as the page separator something that breaks the "statelessness" property we want? Clearly the answer is no. The server doesn't have to remember anything between the two GET requests. There's no concept of a session. Any state that needs to persist between the two GET requests exists only client-side - that's the important distinction. It's completely acceptable - and often required - to have the client persist state between calls to the service.

Retrieve the list of friends that did a custom action on a custom object in open graph 2

I would like to do something like facepile using the graph api with open graph 2 actions : from a custom object and a custom object, give me the friends (using my facebook application) that did this action on this object.
The problem is that using FQL, I cannot query custom objects and actions. Using the graph API, I cannot find a way to intersect the list of my friends with the object I'm interested in.
The best I could do was the following using the batch mode of the graph API :
batch=[
// First we get the list of friends that are using my facebook application
{ "method": "GET", "relative_url": "fql?q=SELECT+uid+FROM+user+WHERE+uid+IN+(SELECT+uid1+FROM+friend+WHERE+uid2=me())+AND+is_app_user=1+LIMIT+0,49", "name": "friends"},
// Then query each friend to get the list of objects that went through my namespace:testaction
{ "method": "GET", "relative_url": "{result=friends:$.data.0.uid}/namespace:testaction" },
{ "method": "GET", "relative_url": "{result=friends:$.data.1.uid}/namespace:testaction" },
...
{ "method": "GET", "relative_url": "{result=friends:$.data.49.uid}/namespace:testaction" }
]
It's quite inefficient and does not fully resolve my issue since :
I still have to filter the results to get only the one that matches
the object I want
If there is a large number of objects in namespace:testaction, I have to go through paging, doing more queries (I try to minimize the number of queries)
Do you see a better way to do this ?
This probably isn't exactly what you're looking for, but given the fact that facebook (AFAIK) doesn't provide (and will probably never provide) the ability to do this. I think you should simply store the information yourself and then query the data from your own database. It would be like what you're doing in your question, but you can optimize it since it's your database.
I'm sure you thought about this already, but someone had to say it.
It's now possible to do this with one Graph API request:
GET https://graph.facebook.com/me/friends?limit=50&fields=name,namespace:testaction.limit(100)
see field expansion and updates to the graph API.
If the answer derickito gave is not enough, you should explore getting your app on the Facebook white-list (aka become a partner) to get at some the private Graph API where this functionality might exist, but is not available for "normal" application that are stuck using the public Graph API.