After some tinkering with the current Google API integration code, I can conclude the following: a. The currently implemented interface in Pike is skimpy at best (it covers less than 1% of the total available interfaces). b. The current implementation uses outdated interface versions (oauth v1 instead of v2, and token interface v1 instead of v4). c. The current implementation still defaults to Google Plus (which has been closed down).
So, I was trying my hand at some Google API integration code that makes use of the JSON-discovery documents Google makes available. This way the interface will cover 100% of all available Google API calls, and will always be current (it will then even support alpha and beta interfaces).
In doing so, I tried to get rid of one level of indirection, by overloading the `-> and `[] operators. But this still seems to result in something that does not play well with classes we inherit from. Any suggestions here? Or should I simply stick in a member called "resrc" to make the jump to the dynamically loaded resources and methods?
P.S. The reason I'm implementing this is because I'm in the process of creating a webcrawler that crawls like Googlebot (which includes Javascript parsing, but with Googlebot rules). And to run this in a way that scales, I need to autoscale a farm of Google Compute Engines up and down, which requires fast Google API access.
I now have an API that works roughly like this:
#define TOKENTIME 3600 #define PROJECT "mylittleproject" #define ZONE "eu-west1-c"
string jwt_secret = Stdio.File("googleserviceaccount.json", "r").read(); // // This hot-fetches the Google Compute API from the discovery file // provided by Google: // Web.Api.Google.Base api = Web.Api.Google.discover("compute", "v1");
void authenticated() { if (!api->auth->is_authenticated() || api->auth->expires->unix_time() - time(1) < TOKENTIME / 2) api->auth->get_token_from_jwt(jwt_secret); }
int main(int argc, array(string) argv) { api->auth->set_scope(api->valid_scopes[1]); authenticated(); // Lists all compute engine instances in this project/zone write("%O\n", api->resrc->instances->list( ([ "project":PROJECT, "zone":ZONE ]) )); return 0; }
Suggestions? Complaints? Wishes?
Stephen R. van den Berg wrote:
I now have an API that works roughly like this:
The API has since reached beta-stage and is now included in Pike 8.1 (it has a synchronous, a callback *and* a promise interface). Documentation is a little bit skimpy at the moment. But a working minimal example is included in the docs.
Suggestions are still appreciated.
Stephen R. van den Berg wrote:
Stephen R. van den Berg wrote:
I now have an API that works roughly like this:
The API has since reached beta-stage and is now included in Pike 8.1 (it has a synchronous, a callback *and* a promise interface). Documentation is a little bit skimpy at the moment. But a working minimal example is included in the docs.
My Google Compute Engine herd-orchestrator/autoscaler (for cheap preemptive instances) works like a charm now.
The promise interface I added to the Google API interface works thus that if you replace the callback argument with the string "promise", that it will return a Promise.
Given the constraints of the dynamic API definitions, this was the best I could come up with. If anybody has any better ideas, please let me know.
pike-devel@lists.lysator.liu.se