Google Visualization API .net? [closed] - serialization

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
How can i use data in my .NET app that is coming in google's visualisation api json format? Can't imagine at the moment how to use this data.
Do i have to parse the json to an object by myself? Can i use Json.NET to deserialize it? For now i have no idea how start with this. Any help is appreciated.
Data looks like this:
{
cols: [
{id: '1', label: 'Name', type: 'string'},
{id: '2', label: 'Age', type: 'number'},
{id: '3', label: 'Birthdate', type: 'date'}
],
rows: [
{c:[{v: 'Dan'}, {v: 18.0, f: 'eighteen'}, {v: new Date(2008, 1, 28, 0, 31, 26), f: '2/28/08 12:31 AM'}]},
{c:[{v: 'Frank'}, {v: 19.0, f: 'nineteen'}, {v: new Date(2008, 2, 30, 0, 31, 26), f: '3/30/08 12:31 AM'}]},
{c:[{v: 'Esther'}, {v: 20.0, f: 'twenty'}, {v: new Date(2008, 3, 30, 0, 31, 26), f: '4/30/08 12:31 AM'}]}
]
}

Can i use Json.NET to deserialize it?
Yes. That's what it's for.
For now i have no idea how start with this. Any help is appreciated.
The manual

You can use Json deserialisation via the DataContractJsonSerializer class in the System.Runtime.Serialization.Json namespace. It's pretty similar to XML Serialisation in that you create a bunch of data classes, dress them with attributes and chuck the Json into a deserializer.
The article below explains how work with Json with a Google web search example:
http://www.ben-morris.com/google-search-api-deserialize-json-output-net

I know I'm late, but for future seekers take a look here:
https://code.google.com/p/bortosky-google-visualization/
I'm using it without any problem.
Sample code:
DataTable tbl = DatabaseEnquiry(sqlcommand, DATE_IN, DATE_OUT, "dd/MM/yyyy HH:mm:ss", true);
return new Bortosky.Google.Visualization.GoogleDataTable(tbl).GetJson().ToString();
Alternatively you can use JavaScriptSerializer:
DataTable tbl = DatabaseEnquiry(sqlcommand, DATE_IN, DATE_OUT, "dd/MM/yyyy HH:mm:ss", true);
JavaScriptSerializer js = new JavaScriptSerializer();
StringBuilder sb = new StringBuilder();
try
{
var linqResults = from DataRow row in tbl.AsEnumerable()
select new
{
avgft = row.Field<object>("AVG FT"),
minft = row.Field<object>("MIN FT"),
maxft = row.Field<object>("MAX FT"),
avgffc = row.Field<object>("AVG FFC"),
minffc = row.Field<object>("MIN FFC"),
maxffc = row.Field<object>("MAX FFC"),
avgtt = row.Field<object>("AVG TT"),
mintt = row.Field<object>("MIN TT"),
maxtt = row.Field<object>("MAX TT"),
avgtfc = row.Field<object>("AVG TFC"),
mintfc = row.Field<object>("MIN TFC"),
maxtfc = row.Field<object>("MAX TFC")
};
js.Serialize(linqResults, sb);
}
catch (InvalidCastException e)
{
logger.Debug(e.StackTrace);
return null;
}
return sb.ToString();
}

Related

API call from google sheets is too long

I am trying to write a script in google sheets to update my 3commas bots. The API requires a number of mandatory fields are passed even when there's only 1 item that needs to be updated.
The code I have is below and it uses the values already read from the platform updating only the base_order_volume value. This works perfectly except for when the pairs value is long (more the 2k chars) and then I get an error from the UrlFetchApp call because the URL is too long.
var sheet = SpreadsheetApp.getActiveSheet();
var key = sheet.getRange('F4').getValue();
var secret = sheet.getRange('F5').getValue();
var baseUrl = "https://3commas.io";
var editBots = "/ver1/bots/"+bots[botCounter].id+"/update";
var patchEndPoint = "/public/api"+editBots+"?";
.
.
[loop around values in sheet]
.
.
var BaseOrder=Number(sheet.getRange(rowCounter,12).getValue().toFixed(2));
var botParams = {
"name": bots[botCounter].name,
"pairs": bots[botCounter].pairs,
"max_active_deals": bots[botCounter].max_active_deals,
"base_order_volume": BaseOrder,
"take_profit": Number(bots[botCounter].take_profit),
"safety_order_volume": bots[botCounter].safety_order_volume,
"martingale_volume_coefficient": bots[botCounter].martingale_volume_coefficient,
"martingale_step_coefficient": Number(bots[botCounter].martingale_step_coefficient),
"max_safety_orders": bots[botCounter].max_safety_orders,
"active_safety_orders_count": Number(bots[botCounter].active_safety_orders_count),
"safety_order_step_percentage": Number(bots[botCounter].safety_order_step_percentage),
"take_profit_type": bots[botCounter].take_profit_type,
"strategy_list": bots[botCounter].strategy_list,
"bot_id": bots[botCounter].id
};
var keys = Object.keys(botParams);
var totalParams = keys.reduce(function(q, e, i) {
q += e + "=" + encodeURIComponent(JSON.stringify(botParams[e])) + (i != keys.length - 1 ? "&" : "");
return q;
},endPoint);
var signature = Utilities.computeHmacSha256Signature(totalParams, secret);
signature = signature.map(function(e) {return ("0" + (e < 0 ? e + 256 : e).toString(16)).slice(-2)}).join("");
var headers = {
'APIKEY': key,
'Signature': signature,
};
try {
var params = {
'method': 'PATCH',
'headers': headers,
'muteHttpExceptions': true
};
var response = JSON.parse(UrlFetchApp.fetch(baseUrl + totalParams, params).getContentText());
I have tried to set the botParams as a payload in the params but when I do the signature is incorrect.
I anyone knows how to use sheets to make a call using extensive length of parameters I'd appreciate any help at all
Some sample data for the bots array would be
{
"name": "TestBot",
"base_order_volume": 0.001,
"take_profit": 1.5,
"safety_order_volume": 0.001,
"martingale_volume_coefficient": 2,
"martingale_step_coefficient": 1,
"max_safety_orders": 1,
"active_safety_orders_count": 1,
"safety_order_step_percentage": 2.5,
"take_profit_type": "total",
"stop_loss_percentage": 0,
"cooldown": 0,
"pairs": ["BTC_ADA","BTC_TRX"],
"trailing_enabled":"true",
"trailing_deviation":0.5,
"strategy_list": [{"strategy":"cqs_telegram"}]
}
Thanks in advance
I'd consider using a Cloud Function to either do the heavy lifting, or, if you're worried about costs, use it as a proxy. You can then call the cloud function from Google Sheets. Cloud Functions can be written in whatever language you're most comfortable with, including Node.
Check the GCP pricing calculator to see what the cost would be. For many cases it would be completely free.
This should give you a sense of how to use cloud functions for CSV creation:
https://codelabs.developers.google.com/codelabs/cloud-function2sheet#0
Here is a SO question with an answer that explains how to query cloud functions with authentication.

How to merge cells with Google Sheets API?

I am using the Python client for the Google Sheets API to build a spreadsheet. I am able to create a new sheet and update values in it, but I have been unable to merge cells for the header row that I want.
top_header_format = [
{'mergeCells': {
'mergeType': 'MERGE_COLUMNS',
'range': {
'endColumnIndex': 3,
'endRowIndex': 1,
'sheetId': '112501875',
'startColumnIndex': 0,
'startRowIndex': 0
}
}},
{'mergeCells': {
'mergeType': 'MERGE_COLUMNS',
'range': {
'endColumnIndex': 5,
'endRowIndex': 1,
'sheetId': '112501875',
'startColumnIndex': 3,
'startRowIndex': 0
}
}}
]
service.spreadsheets().batchUpdate(
spreadsheetId=spreadsheet_id,
body={'requests': top_header_format}
).execute()
This is the code I am running. There are no errors. The response's replies are empty and the spreadsheet doesn't have merged cells. The documentation is here.
Start indexes are inclusive and end indexes are exclusive, so by asking to merge row [0,1) you're saying "i want to merge row 0 into row 0", which is a no-op. You probably want [0,2), e.g:
top_header_format = [
{'mergeCells': {
'mergeType': 'MERGE_COLUMNS',
'range': {
'endColumnIndex': 4,
'endRowIndex': 2,
'sheetId': '112501875',
'startColumnIndex': 0,
'startRowIndex': 0
}
}},
{'mergeCells': {
'mergeType': 'MERGE_COLUMNS',
'range': {
'endColumnIndex': 6,
'endRowIndex': 2,
'sheetId': '112501875',
'startColumnIndex': 3,
'startRowIndex': 0
}
}}
]
If someone looking for doing merging with PHP, you can use this code below:
For merging cells first you will have to download the PHP library from composer as in their documentation ( https://developers.google.com/sheets/api/quickstart/php )
once installed follow their guide to set up your client to get authenticated.
//$client will be your Google_Client authentication, for more info check the documentation link above.
Use below code for doing merging of rows and columns
$service = new Google_Service_Sheets($client);
$spreadsheetId = '1jfUz2VMUUEt2s4BP2Ye'; //this is test spreadsheet it, use your spreadsheet id here
$rangeinst = new Google_Service_Sheets_GridRange();
$rangeinst->setSheetId(0); //your sheet id
$rangeinst->setStartRowIndex(1); // row index from where to start
$rangeinst->setEndRowIndex(11); //ending row upto which you want merging
$rangeinst->setStartColumnIndex(0); //start of column index, first column has 0 index like row
$rangeinst->setEndColumnIndex(4); //end of column upto which you want merging
$merge = new Google_Service_Sheets_MergeCellsRequest();
$merge->setMergeType('MERGE_COLUMNS'); //merge type request
$merge->setRange($rangeinst);
$requestBody = new Google_Service_Sheets_Request();
$requestBody->setMergeCells($merge);
$requestBatchBody = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest();
$requestBatchBody->setRequests($requestBody);
$response = $service->spreadsheets->batchUpdate($spreadsheetId, $requestBatchBody);
echo "<pre>";
print_r($response);

Linqpad extension to plot graphs

I tried to plot some graphs in Linqpad with with "Util.RawHtml()" and "Dump()" but it is not working with this example from amcharts.com. I created a string variable including all the HTML source code but the result is not working.
string html = "";
using (System.Net.WebClient client = new System.Net.WebClient ())
{
html = client.DownloadString(#"http://pastebin.com/raw/pmMMwXhm");
}
Util.RawHtml(html).Dump();
Later versions of LinqPad 5 now support charting out of the box with Util.Chart. You can see the samples in the Samples Tab (next to My Queries) under
LINQPad Tutorial&Reference
Scratchpad Features
Charting with Chart
The following script is the Chart() - dual scale sample:
// Each y-series can have a different series type, and can be assigned to the secondary y-axis scale on the right.
var customers = new[]
{
new { Name = "John", TotalOrders = 1000, PendingOrders = 50, CanceledOrders = 20 },
new { Name = "Mary", TotalOrders = 1300, PendingOrders = 70, CanceledOrders = 25 },
new { Name = "Sara", TotalOrders = 1400, PendingOrders = 60, CanceledOrders = 17 },
};
customers.Chart (c => c.Name)
.AddYSeries (c => c.TotalOrders, Util.SeriesType.Spline, "Total")
.AddYSeries (c => c.PendingOrders, Util.SeriesType.Column, "Pending", useSecondaryYAxis:true)
.AddYSeries (c => c.CanceledOrders, Util.SeriesType.Column, "Cancelled", useSecondaryYAxis:true)
.Dump();
As I understand it, this will not work because the html contains scripts that will not be executed.
As an alternative, you can still use the old (and deprecated) google charts api, eg
var link = #"http://chart.apis.google.com/chart?chxt=y&chbh=a&chs=300x225&cht=bvg&chco=A2C180,3D7930&chd=t:10,20,30,40,50,60|30,35,40,45,55,60&chtt=Sample";
Util.Image (link).Dump();
or see
http://blog.divebomb.org/2012/11/dumping-charts-in-linqpad/
Not sure if it's the answer you're after but there may be value in looking at the DisplayWebPage method on the Util class in Linqpad. This correctly rendered your chart in the result window, (although there was a script error). Obviously, this may not solve your underlying issue.
I used version 5.10.00 to test this.

nytime API returns no data

I am using NYTimes API to scrap news articles for my text analysis. Here is the code.
from nytimesarticle import articleAPI
api = articleAPI('<API key>')
articles = api.search(q = 'President',
fq = {'source':['Reuters','AP', 'The New York Times']},
begin_date = 20110829,
end_date = 20161203)
print ("the response is ", articles)
However, it does not return any results. This is the sample response with null dataset:
{'response': {'meta': {'offset': 0, 'time': 227, 'hits': 0}, 'docs':
[]}, 'status': 'OK', 'copyright': 'Copyright (c) 2013 The New York
Times Company. All Rights Reserved.'}
Should there be any additional paremeters when sending the request
I actually was using a completely different API in my initial code. Using "requests" API solved the problem here
uri = "http://api.nytimes.com/svc/archive/v1/"+str(year)+"/"+str(month)+".json?api-key=<>"
resp = requests.get(uri)

How to stream SQL results to JSON using Groovy StreamingJsonBuilder?

I am trying to execute a SQL query and convert the results to JSON as follows. Though I got it working without streaming, I'm having some issues using StreamingJsonBuilder to stream the results.
non-streaming code
def writer = new StringWriter()
def jsonBuilder = new StreamingJsonBuilder(writer)
sql.eachRow("select * from client"){ row ->
jsonBuilder( id: row.id, name: row.name )
}
println writer.toString()
Result from the code above
{"id":123,"name":"ABCD"}{"id":124,"name":"NYU"}
The problem with this result is that, all documents are printed on same line without delimitation. How do I get the results as an array and each document pretty-printed as below
Expected result
[
{
id: 123,
name: "ABCD",
...
},
{
id: 124,
name: "NYU",
...
},
]
I put this here more as an fallback. If your problem is just to have your data properly formatted as json, but the sheer amount of data make you use the streaming API, then you are better off with using the streaming for your data and handle the "array" for yourself.
All the calls in the StreamingJsonBuilder take an object and directly write it to the writer. So there is no safe way (I can see) to have the writer open the array, then send the data in chunks you provide and then close the array. So while we already hold the writer, why not just deal with the array your self (this part of json is rather easy to get right):
new File('/tmp/out.json').withWriter{ writer ->
writer << '['
def jsonBuilder = new groovy.json.StreamingJsonBuilder(writer)
def first = true
10000000.times{
if (!first) writer << "\n,"
first = false
jsonBuilder(id: it, name: it.toString())
}
writer << ']'
}
I've no access to any SQL to try but the following piece of code should do the job (You need to replace the data variable):
import groovy.json.*
def writer = new StringWriter()
def jsonBuilder = new StreamingJsonBuilder(writer)
def data = [
[id:1, name: 'n1', other: 'o1'],
[id:2, name: 'n2', other: 'o2']
]
def dataJson = jsonBuilder(data.collect { [id:it.id, name:it.name] })
println(JsonOutput.prettyPrint(JsonOutput.toJson(dataJson)))
UPDATE (after #cfrick's comment)
Here, every row is processed one ofter another but, a key (data in this case) is needed.
import groovy.json.*
def writer = new StringWriter()
def jsonBuilder = new StreamingJsonBuilder(writer)
def data = [
[id:1, name: 'n1', other: 'o1'],
[id:2, name: 'n2', other: 'o2']
]
def root = jsonBuilder(data: [])
data.each { d ->
root.data << [id:d.id, name: d.name]
}
println(JsonOutput.prettyPrint(JsonOutput.toJson(root)))