Power BI REST API BadRequest for measures - powerbi

I have created a dataset without major incidence
{\"tableName\": \"Sales\"
,\"columns\": [
{\"name\":\"ProductID\", \"dataType\":\"int64\", \"summarizeBy\":\"none\", \"isHidden\":\"True\", \"formatString\":\"#,##0\"}
, {\"name\":\"Date\", \"dataType\":\"DateTime\", \"formatString\":\"dd/mm/yyyy\"}
, {\"name\":\"TipID\", \"dataType\":\"int64\", \"summarizeBy\":\"none\", \"isHidden\":\"True\", \"formatString\":\"#,##0\"}
, {\"name\":\"Sales\", \"dataType\":\"double\", \"formatString\":\"#,##0\"}
]
}
, but when I try to put some measure, always get a "BadRequest".
{\"tableName\": \"Sales\"
,\"columns\": [
{\"name\":\"ProductID\", \"dataType\":\"int64\", \"summarizeBy\":\"none\", \"isHidden\":\"True\", \"formatString\":\"#,##0\"}
, {\"name\":\"Date\", \"dataType\":\"DateTime\", \"formatString\":\"dd/mm/yyyy\"}
, {\"name\":\"TipID\", \"dataType\":\"int64\", \"summarizeBy\":\"none\", \"isHidden\":\"True\", \"formatString\":\"#,##0\"}
, {\"name\":\"Sales\", \"dataType\":\"double\", \"formatString\":\"#,##0\"}
]
, \"measures\": [
{\"name\": \"TrySales\", \"expression\": \"SUM(Sales[Sales])\"}
]
}
I have created a "Push Dataset" where only add measures, with the same error.
HttpContent body = new StringContent(postBody);
body.Headers.ContentType = new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
HttpResponseMessage response = client.PutAsync(restUri, body).Result;
JSON
{\"tableName\": \"Sales\"
, \"measures\": [
{\"name\": \"TrySales\", \"expression\": \"CALCULATE(SUM(Ventas[Venta]);SUM(Sales[Sales])\"}
]
}
I only found an example code in this link..
The result from the PUT
Headers
{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Pragma: no-cache
Transfer-Encoding: chunked
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: deny
X-Content-Type-Options: nosniff
RequestId: 6aa4198c-8315-4517-8f78-b5f90e6d1375
Access-Control-Expose-Headers: RequestId
request-redirected: true
home-cluster-uri: https://wabi-europe-north-b-redirect.analysis.windows.net/
Cache-Control: no-store, must-revalidate, no-cache
Date: Fri, 15 Nov 2019 13:08:36 GMT
Content-Type: application/json; charset=utf-8
}}
Request message
{Method: PUT, RequestUri: 'https://api.powerbi.com/v1.0/myorg/groups/1cd4f3cf-xxxx-41dd-83e4-c17708511d79/datasets/35b36723-ed24-xxxx-8e54-fc8e3a1503fe/tables/Sales'
, Version: 1.1, Content: System.Net.Http.StringContent, Headers:
{
Accept: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IkJCOE...
Content-Type: application/json
Content-Length: 147
}}
Any suggestions?
EDIT
Response
Id = 37, Status = RanToCompletion
, Method = "{null}"
, Result = "{\"error\":{
\"code\":\"BadRequest\"
,\"message\":\"Bad Request\"
,\"details\":[
{\"message\":\"The property 'tableName' does not exist on type 'Microsoft.PowerBI.ServiceContracts.Api.Table'
. Make sure to only use property names that are defined by the type.\"
,\"target\":\"tableSchema\"}
]
}
}
It seems a spelling error due to an error in the documentation. In this link it appears as "tableName" and I have not found any more examples.

It is an error in the documentation.
This example in the documentation has tableName in the json. However, when you click on Try it the body has name.
Using name instead of tableName worked for me.

Related

Accessing request data object

I am sending the following post Data to django Rest API
Request URL: http://localhost:8000/polls/
Request Method: POST
Status Code: 200 OK
Remote Address: 127.0.0.1:8000
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:8100
Content-Length: 90
Content-Type: text/html; charset=utf-8
Date: Mon, 18 Jun 2018 11:01:54 GMT
Server: WSGIServer/0.2 CPython/3.6.5
Vary: Origin
X-Frame-Options: SAMEORIGIN
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 83
content-type: text/plain
Host: localhost:8000
Origin: http://localhost:8100
Referer: http://localhost:8100/
User-Agent: Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Mobile Safari/537.36
0:
{id: "1", username: "admin", password: "admin", user_group_id: "1", status: "1"}
The sent here will first be authenticated against the one saved in the database. I am trying to access this data but failing to do so .
When I process the data using json parse
case 1.
def dunction(request)
data = json.loads(request.body.decode("utf-8"))
vak=data
return HttpResponse(vak)
Then the following response is received
{'id': '1', 'username': 'admin', 'password': 'admin', 'user_group_id': '1', 'status': '1'}
case 2.
When manipulating the same code
data = json.loads(request.body.decode("utf-8"))
vak=data[0]
return HttpResponse(vak)
received response
idusernamepassworduser_group_idstatus
Case 3.
def dunction(request):
data = json.loads(request.body.decode("utf-8"))
vak=data.username
return HttpResponse(vak)
throws error 'list' object has no attribute 'username'
FYI,
Here I am trying to create a custom authentication function which authenticates the userData and then sends data back to the server.
'DEFAULT_AUTHENTICATION_CLASSES':
'polls.authentication.UserAuthentication',
HttpResponse takes an iterable. You are passing it various things that are in fact iterable: in the first case, a list, so it prints the (only) entry in that list, which is a dictionary; in the second case, you pass it a dict, so it iterates through the dict which gives the keys only. In the third case, for some reason you try and use object notation to access a key of a dict which is inside a list, which won't work at all.
I'm not sure what your actual question is, but if you do want to access the username you would need data[0]['username'].
Note though that the point of DRF is to abstract away a lot of this stuff; you should use the built-in functionality rather than doing any of this.
Use request.data to get the data for processing. return message along with HTTP status code like below
def dunction(request):
username=request.data['username']
password=request.data['password']
group_id=request.data['user_group_id']
status=request.data['status']
return Response({"status":"success"}, status=status.HTTP_200_OK)

Browser doesn't store cookies

I'm sending Cookie from Laravel application (http://backend.local) to Vue SPA (http://frontend.local:8080):
Laravel side (dummy route)
//api routes
Route::post('login', function () {
setcookie("name", 'value', time()+3600, "/", ".local");
return response('ok');
});
Vue side
axios.post('//backend.local/api/login')
.then(response => {
console.log(response)
}).catch(error => {
})
Response Headers:
HTTP/1.1 200 OK
Date: Mon, 21 May 2018 09:42:35 GMT
Server: Apache
Set-Cookie: name=value; expires=Mon, 21-May-2018 10:42:36 GMT; Max-Age=3600; path=/; domain=.local
Cache-Control: no-cache, private
Access-Control-Allow-Origin: http://frontend.local:8080
Vary: Origin
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
Content-Length: 2
Keep-Alive: timeout=10, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
But there is no Cookies in broswer storage (Application tab in Developers Console).
What's wrong?
UPDATE: I think the problem is that there is port number in http://frontend.local:8080. Can I remove port number from url?
Original Answer
The browser will automatically reject any domain which doesn't have two parts to it. So using .local is not considered a domain at all. You need to two levels at least. Consider the below flask app I created for demoing the same
from flask import Flask, request, make_response
app = Flask(__name__)
#app.route("/")
def index():
resp = make_response()
resp.set_cookie('value1', ".frontend.local", domain=".frontend.local")
resp.set_cookie('value2', "frontend.local", domain="frontend.local")
resp.set_cookie('value3', ".local", domain=".local")
return resp
app.run(debug=True)
Now testing this through curl
$ curl -v frontend.local:5000
* Rebuilt URL to: frontend.local:5000/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to frontend.local (127.0.0.1) port 5000 (#0)
> GET / HTTP/1.1
> Host: frontend.local:5000
> User-Agent: curl/7.54.0
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Type: text/html; charset=utf-8
< Set-Cookie: value1=.frontend.local; Domain=.frontend.local; Path=/
< Set-Cookie: value2=frontend.local; Domain=frontend.local; Path=/
< Set-Cookie: value3=.local; Domain=.local; Path=/
< Content-Length: 0
< Server: Werkzeug/0.14.1 Python/3.6.5
< Date: Tue, 29 May 2018 12:58:20 GMT
<
* Closing connection 0
When you navigate this in browser, you can see that the cookie with Domain=.local gets discarded but rest 2 remains
And later you can see that both the cookies have been sent to the reload of the same page
Update 1: 30th May 2018
Since you are using 2 different domains, you should use frontend.local.com and backend.local.com and the cookies should be returned with domain as .local.com, so that backend and frontend works as a subdomain of local.com. Then frontend.local.com gets the cookies set by backend.local.com through domain sharing as the cookie domain is set to .local.com
Since this is a CORS call, you will need to set setCredentials to true. This is a standard behavior: Standard CORS requests do not send or set any cookies by default.
The withCredentials property will include any cookies from the other domain in the request and also set any cookies from other domain.
So your Vue.js code will be:
axios.defaults.withCredentials = true
axios({
method: 'POST',
url: '//backend.local/api/login',
// THIS IS IMPORTANT
withCredentials: true
})
.then(response => {
console.log(response)
}).catch(error => {})
[Edit]: Read more about CORS at HTML Rocks.
Please let me know if it doesn't help.

Empty Body in Vapor Client GET Response

I'm trying to connect to
Bamboo HR's API, and I've managed to make this work with curl and Swift Foundation's URLRequest/URLSession (as well as an older Express node.js app).
However, when trying to utilize Vapor's client with the .get() method, I'm getting a successful 200 response from BambooHR - but the response's .body is empty.
Here's the code snippet:
key and {myDomain} are placeholders in the example
let encodedKey = "\(key):x".utf8.base64String
let directoryRootUrl = "https://api.bamboohr.com/api/gateway.php/{myDomain}/v1/employees/directory"
let response = try drop.client.get(
directoryRootURL,
headers: [
"Accept": "application/json",
"Authorization": "Basic \(encodedKey)",
"Host": "api.bamboohr.com"
])
When I do print(response), this is what's displayed:
Response
- HTTP/1.0 200 OK
- Headers:
Connection: close
Vary: User-Agent
Server: Apache
Content-Security-Policy: {...}
Date: Mon, 16 Jan 2017 00:26:31 GMT
Content-Type: application/json
X-Content-Type-Options: nosniff
- Body:
I'm wondering if I'm doing anything wrong with Vapor, or if it's a bug.
Like tobygriffin suggested, setting:
drop.client = FoundationClient.self
after creating the Droplet worked.

Directory API: delete member API operation fails for non-Google accounts

We are noticing that group members cannot be removed using the new Directory API if they are not Google accounts. We've tested this with both Dito GAM (note I am the author of GAM) and the Google API Explorer.
The operation functions correctly if the member to be removed is a Google account:
C:\gam-64>gam update group group99#jay.powerposters.org remove google-user#jay.powerposters.org
removing google-user#jay.powerposters.org
connect: (www.googleapis.com, 443)
send: 'DELETE /admin/directory/v1/groups/group99#jay.powerposters.org/members/google-user#jay.powerposters.org?quotaUser=1ee51612c9a0220af0cf5516a990b206e2a619e8&prettyPrint=true
HTTP/1.1
Host: www.googleapis.com
content-length: 0
authorization: Bearer <valid access token>
accept-encoding: gzip, deflate
accept: */*
user-agent: Dito GAM 3.01 / jay#ditoweb.com (Jay Lee) / Python 2.7.5 final / Windows-7-6.1.7601-SP1 AMD64 / google-api-python-client/1.2 (gzip)
reply: 'HTTP/1.1 204 No Content
header: Cache-Control: no-cache, no-store, max-age=0, must-revalidate
header: Pragma: no-cache
header: Expires: Fri, 01 Jan 1990 00:00:00 GMT
header: Date: Wed, 28 Aug 2013 12:57:06 GMT
header: ETag: "cZnI-gy4eI-n1-_cqk7okAteLZk/vyGp6PvFo4RvsFtPoIWeCReyIC8"
header: Server: GSE
this is the expected behavior. However, if the account to be removed is not a Google Account (Google Apps or consumer), an error is returned:
C:\gam-64>gam update group group99#jay.powerposters.org remove not-a-google-account#not-a-google-domain.com
removing not-a-google-account#not-a-google-domain.com
connect: (www.googleapis.com, 443)
send: 'DELETE /admin/directory/v1/groups/group99#jay.powerposters.org/members/not-a-google-account#not-a-google-domain.com?quotaUser=1ee51612c9a0220af0cf5516a990b206e2a619e8&prettyPrint=true
HTTP/1.1
Host: www.googleapis.com\r\ncontent-length: 0
authorization: Bearer <valid oauth 2.0 token>
accept-encoding: gzip, deflate
accept: */*
user-agent: Dito GAM 3.01 / jay#ditoweb.com (Jay Lee) / Python 2.7.5 final / Windows-7-6.1.7601-SP1 AMD64 / google-api-python-client/1.2 (gzip)
reply: 'HTTP/1.1 400 Bad Request
header: Content-Type: application/json; charset=UTF-8
header: Content-Encoding: gzip
header: Date: Wed, 28 Aug 2013 13:00:02 GMT
header: Expires: Wed, 28 Aug 2013 13:00:02 GMT
header: Cache-Control: private, max-age=0
header: X-Content-Type-Options: nosniff
header: X-Frame-Options: SAMEORIGIN
header: X-XSS-Protection: 1; mode=block
header: Content-Length: 122
header: Server: GSE
body: {
"error": {
"errors": [
{
"domain": "global",
"reason": "badRequest",
"message": "Bad Request"
}
],
"code": 400,
"message": "Bad Request"
}
}
Error 400: Bad Request - badRequest
Note that this same behavior shows in the Google API Explorer also:
http://screencast.com/t/fQZCnMYYs
https://developers.google.com/apis-explorer/#s/admin/directory_v1/directory.members.delete?groupKey=group99%2540jay.powerposters.org&memberKey=not-a-google-account%2540not-a-google-domain.com&_h=1&
It should be possible to remove ANY address from a Google Group via the Directory API
I spoke with Google Enterprise support about this and they acknowledged this was a bug (as Silvano has here). After speaking with the dev team, they told me that a work around for this is to delete using the ID of the user instead of email address.
A quick example of how you can delete all members using member ids.
Directory directory =
new Directory.Builder(httpTransport, jsonFactory, credentials)
.setApplicationName(APPLICATION_NAME)
.build();
Members members = directory.members().list(groupKey).execute();
for(Member member : members.getMembers()) {
String memberId = member.getId();
Delete delete = directory.members().delete(groupKey, memberId);
delete.execute();
}
Hope this helps until they can release a fix.
Google has resolved this issue on their end. Removing non-Google email addresses from a Google Group now works without issue.
Here is a working example in PHP with Add and Delete.
function gmail_provision($email, $email_list, $requested_operation) {
// requested_operation should be either add or delete
require_once "google-api-php-client/src/Google_Client.php";
require_once "google-api-php-client/src/contrib/Google_DirectoryService.php";
require_once "google-api-php-client/src/contrib/Google_Oauth2Service.php";
session_start();
$group_scope = 'https://www.googleapis.com/auth/admin.directory.group';
$service_account_email = '.....#developer.gserviceaccount.com';
$service_account_pkcs12_file_path = '/path/to/...-privatekey.p12';
$client_id = '......apps.googleusercontent.com';
$adminEmail = 'admin-account#email.com;
$key = file_get_contents($service_account_pkcs12_file_path);
$auth = new Google_AssertionCredentials($service_account_email, array($group_scope), $key, 'notasecret', 'http://oauth.net/grant_type/jwt/1.0/bearer', $adminEmail);
$client = new Google_Client();
$client->setClientId($client_id); // from API console
$client->setApplicationName("API Project Name");
$client->setUseObjects(true);
$client->setAssertionCredentials($auth);
try {
// Adding or removing from specified list
$sync_status = '';
$service = new Google_DirectoryService($client);
switch ($requested_operation) {
case "add": // Add
$member = new Google_Member(array('email' => $email,
'kind' => 'admin#directory#member',
'role' => 'MEMBER',
'type' => 'USER'));
$service->members->insert($email_list, $member);
break;
case "remove": // Remove
// Users must be removed by ID not by email address
// This is slow and should be changed when
// Google fixes the bug and allows delete by email.
// Get a list of email addresses in the list
$results = $service->members->listMembers($email_list);
// Push results into an array
$arrResults = get_object_vars($results);
// Recursive iterator
$arrIt = new RecursiveIteratorIterator(new RecursiveArrayIterator($arrResults));
// Cycle through the array searching for the email address
foreach ($arrIt as $sub) {
$subArray = $arrIt->getSubIterator();
if ($subArray['email'] === $email) {
// Store an array of the details associated
// with the email address
$outputArray[] = iterator_to_array($subArray);
}
}
// Delete by id
$service->members->delete($email_list, $outputArray[0]['id']);
break;
}
}
catch (Google_ServiceException $e) {
// $e->getCode()
// $e->getMessage()
}
catch (Google_Exception $e) {
// $e->getCode()
// $e->getMessage()
}
catch (Zend_Gdata_Gapps_ServiceException $e) {
// $e->getCode()
// $e->getMessage()
}
}

Facebook Graph API post displaying some message characters incorrectly

I'm attempting to post a message to a users wall using the facebook graph api.
https://graph.facebook.com/me/feed
Charchters like å, ä or ö would display incorrectly with symbols like ���...
I used apacheCommons StringEscapeUtils.encodeHtml around all the relevent parameters sent in the request (message, name, description).
def params = [
accessToken: getFacebookAccessToken(),
message: StringEscapeUtils.escapeHtml(deal.title),
pictureUrl: imageUrl,
name: StringEscapeUtils.escapeHtml(deal.title),
description: StringEscapeUtils.escapeHtml(deal.shortDescription),
actionLabel: StringEscapeUtils.escapeHtml(actionLabel),
actionUrl: actionUrl
]
def graph(path, params, method = GET, contentType = JSON) {
def http = null
http = new TrustAllHttpBuilder(ConfigurationHolder.config.facebook.graph.uri)
http.request( method, contentType) { req ->
uri.path = path
req.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.IGNORE_COOKIES );
req.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, connectionTimeout );
req.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, socketTimeout );
requestContentType = URLENC
body = params
response.success = { resp, obj ->
return obj
}
}
}
The "Name" and "Description" display correctly in facebook after this change but the "Message" still does not render correctly.
Any ideas why the "Message" is not displaying correcltly?
Does FB handle it differently?
Thanks
Update
I adjusted the params to be URLEncoded to UTF-8 before sending in the body of JSON request.
def params = [
accessToken: getFacebookAccessToken(),
message: URLEncoder.encode(deal.title,"UTF-8"),
pictureUrl: imageUrl,
name: URLEncoder.encode(deal.title,"UTF-8"),
description: URLEncoder.encode(deal.shortDescription,"UTF-8"),
actionLabel: URLEncoder.encode(actionLabel,"UTF-8"),
actionUrl: actionUrl
]
The Request:
14:49:13 DEBUG [FacebookService] body: Message: Tommy+%C3%80%C3%84%C4%87%C3%95,Name: Tommy+%C3%80%C3%84%C4%87%C3%95,Description: %C3%80%C3%84%C4%87%C3%95%C3%80%C3%84%C4%87%C3%95,Caption: ,Action Label: TEST,ActionUrl: http://www.mytest.com
14:49:51 DEBUG [FacebookService] Calling facebook graph API https://graph.facebook.com/me/feed
14:49:51 DEBUG [TrustAllHttpBuilder] POST https://graph.facebook.com/me/feed
14:49:52 DEBUG [headers] >> POST /me/feed HTTP/1.1
14:49:52 DEBUG [headers] >> Accept: application/json, application/javascript, text/javascript
14:49:52 DEBUG [headers] >> Content-Length: 475
14:49:52 DEBUG [headers] >> Content-Type: application/x-www-form-urlencoded; charset=windows-1252
14:49:52 DEBUG [headers] >> Host: graph.facebook.com
14:49:52 DEBUG [headers] >> Connection: Keep-Alive
14:49:53 DEBUG [headers] << HTTP/1.1 200 OK
14:49:53 DEBUG [headers] << Access-Control-Allow-Origin: *
14:49:53 DEBUG [headers] << Cache-Control: private, no-cache, no-store, must-revalidate
14:49:53 DEBUG [headers] << Content-Type: application/json
14:49:53 DEBUG [headers] << Expires: Sat, 01 Jan 2000 00:00:00 GMT
14:49:53 DEBUG [headers] << Pragma: no-cache
14:49:53 DEBUG [headers] << X-FB-Rev:
14:49:53 DEBUG [headers] << X-FB-Debug:
14:49:53 DEBUG [headers] << Date: Fri, 05 Oct 2012 13:49:52 GMT
14:49:53 DEBUG [headers] << Connection: keep-alive
14:49:53 DEBUG [headers] << Content-Length: 40
The Result in FB (Not working):
escapeHtml is the wrong method for that – you see how your message is now showing HTML Entities. You do not want to post HTML code, you want to post plain text.
Charchters like å, ä or ö would display incorrectly with symbols like ���...
That’s most likely because your application is using the wrong character encoding.
Make sure to use UTF-8. (Or convert your parameter values to UTF-8 before passing them to the API, should the former not be possible.)
Edit:
I tried converting the params to UTF-8 before
14:49:13 DEBUG [FacebookService] body: Message: Tommy+%C3%80%C3%84%C4%87%C3%95,Name: …
These are URL-encoded UTF-8 characters. URL-encoding is contra-productive here.
14:49:52 DEBUG [headers] >> Content-Type: application/x-www-form-urlencoded; charset=windows-1252
Thou shalt not Lie into the API’s Face so blatantly :-)
Seriously, find out what brings your app to send that charset in the request header – and see how you get that changed to UTF-8 as well (or to leave the charset part out completely).
It turns out theEncoderRegistry class already
has a charset field that it uses for the request data. It defaults to
the platform encoding. You can set it to UTF-8 as follows:
def graph(path, params, method = GET, contentType = JSON) {
def http = null
http = new TrustAllHttpBuilder(ConfigurationHolder.config.facebook.graph.uri)
http.encoderRegistry = new EncoderRegistry( charset: 'utf-8' )
http.request( method, contentType) { req ->
uri.path = path
req.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.IGNORE_COOKIES );
req.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, connectionTimeout );
req.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, socketTimeout );
requestContentType = URLENC
body = params
response.success = { resp, obj ->
return obj
}
}
}
Answer reference