Program Listing for File online.h¶
↰ Return to documentation for file (source/online.h
)
/*
* online.h TODO - this is a collection of snippets from first working with online plotly API.
* They could be used to form the basis of a plotly client in C++
*
* References:
*
* [1]
*
* Future Improvements:
*
* [1]
*
*
* Author: Tom Clark (thclark@github)
*
* Copyright (c) 2017-8 T Clark. All Rights Reserved.
*
*/
#ifndef CPPLOT_ONLINE_H
#define CPPLOT_ONLINE_H
// Encapsulate plotly config variables. Obtain credentials from the environment upon instantiation.
/* Leaving as a comment - focussing on offline first.
struct Config {
std::string url = "https://api.plot.ly/v2/";
std::string user = "";
std::string password = "";
Config() {
// Get configuration from environment variables. PLOTLY_URL is optional, allowing you to run your own server
char *c_url = getenv("PLOTLY_URL");
char *c_user = getenv("PLOTLY_USERNAME");
char *c_password = getenv("PLOTLY_API_KEY");
if ((c_user == NULL) || (c_password == NULL)) {
InvalidOrMissingPlotlyCredentialsException e;
throw (e);
}
if (c_url != NULL) {
url = std::string(c_url);
}
user = std::string(c_user);
password = std::string(c_password);
if (url.back() == '/') {
url.pop_back();
}
}
};
// Base class for managing the figure creation process
template <class ContentsType>
class Figure {
private:
ContentsType contents;
Config configuration;
void setPlotlyIdFromUrl(std::string url);
protected:
// Plotly figure id
std::string plotly_id;
// Plotly username
std::string plotly_usr;
// Refers to the python plotly library used to generate the figure
// TODO figure out how to get the version of plotly used to render the figure through their API; set it here
std::string plotly_version = "unknown";
public:
Figure(ContentsType contents);
// Gets the plotly URL string
std::string plotlyUrl();
// Gets the plotly embed URL string
std::string embedUrl();
// Not implemented, as we don't use C++ to serve web content directly
// html(self, **kwargs):
// Gets the plotly PDF URL string (an expiring link to the pdf file containing the figure)
std::string pdfUrl();
// Update the figure json from the plotly server
// Not implemented - one-way so far
// void pull();
// Plot the figure by POSTing its data to the plotly server
void plot();
};
template <class ContentsType>
Figure<ContentsType>::Figure(ContentsType contents) {
contents = contents;
// Get plotly server access configuration and credentials from the environment
configuration = Config();
}
template <class ContentsType>
std::string Figure<ContentsType>::plotlyUrl() {
// Returns the URL to this figure on plotly, if the figure is rendered
if (plotly_usr == "") {
return "";
}
return configuration.url + "/~" + plotly_usr + "/" + plotly_id;
}
template <class ContentsType>
void Figure<ContentsType>::setPlotlyIdFromUrl(std::string url) {
// Remove any trailing / in case the url is given as, e.g. https://plot.ly/~usr_name/123/
if (url.back() == '/') {
url.pop_back();
}
// Split the URL into its components. Use ~ as a splitter as well as / to avoid extra op of removing it from user
std::vector<std::string> url_parts;
boost::split(url_parts, url, boost::is_any_of("/~"));
// If the url is given as, e.g. plot.ly/~usr_name/123.embed, remove the .* from the trailing figure id
std::vector<std::string> trailing_id_parts;
boost::split(trailing_id_parts, url_parts.back(), boost::is_any_of("."));
// Assign the Figure properties from the url
plotly_id = trailing_id_parts[0];
plotly_usr = url_parts[url_parts.size() - 2];
}
template <class ContentsType>
std::string Figure<ContentsType>::embedUrl() {
return plotlyUrl() + ".embed";
}
template <class ContentsType>
std::string Figure<ContentsType>::pdfUrl() {
return plotlyUrl() + ".pdf";
}
template <class ContentsType>
void Figure<ContentsType>::plot() {
// Plot the figure by POSTing its data to the plotly server
// Get the json data for the figure contents
std::string body_str = contents.toJson();
// POST to configuration.url, with configured credentials
auto r = cpr::Post( cpr::Url{configuration.url},
cpr::Body{body_str},
cpr::Authentication{configuration.user, configuration.password},
cpr::Header{{"Accept", "application/json"}, {"Plotly-Client-Platform", "cpp 0.0.1"}});
// Remove any trailing / in case the url is given as, e.g. https://plot.ly/~usr_name/123/
if (r.status_code != 200) {
std::stringstream msg;
msg << "Error received from plotly..." <<std::endl;
msg << "url: " << configuration.url << std::endl;
msg << "status_code: " << r.status_code << std::endl;
msg << "content-type: " << r.header["content-type"] << std::endl; // application/json; charset=utf-8
msg << "text: " << r.text << std::endl;
ErrorInPlotlyOnlineException e(msg.str());
throw (e);
}
// Expected response...
auto json = nlohmann::json::parse(r.text);
std::cout << "Successful response from plotly API... " << std::endl << json.dump(4) << std::endl;
NotImplementedException e;
throw (e);
}
*/
#endif //CPPLOT_ONLINE_H