

{"id":3672,"date":"2015-09-10T09:05:06","date_gmt":"2015-09-10T14:05:06","guid":{"rendered":"http:\/\/rud.is\/b\/?p=3672"},"modified":"2018-03-07T16:43:28","modified_gmt":"2018-03-07T21:43:28","slug":"a-better-way-to-read-nest-data-into-r","status":"publish","type":"post","link":"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/","title":{"rendered":"A Better Way To Read Nest Data Into R"},"content":{"rendered":"<p>I glimpsed a [post](http:\/\/blagrants.blogspot.com\/2015\/09\/nest-thermostat-and-r-creating-shiny.html) in the RSS feeds today on how to connect Nest data with a Shiny dashboard and was compelled to post a less brute-force way to get data from the Nest API. The authors of the Shiny+Nest post used `system` calls to `curl` and regular expression character vector operations to slice, dice &#038; work with the Nest API\/data. However, we have packages like `RCurl`, `curl` and `httr` that all make `system` calls unnecessary. Here&#8217;s how to use the Nest API in a more R-like (or `httr`-like) fashion.<\/p>\n<p>### Nest &#038; OAuth 2.0<\/p>\n<p>Nest uses OAuth 2.0 for authentication. As the authors of the other post pointed out, you&#8217;ll need to go to `https:\/\/developer.nest.com\/clients` (create an account if you don&#8217;t already have one) to setup a new client, making sure to leave the `OAuth Redirect URL` field _blank_. Copy the _Client ID_ for use later and store the _Client secret_ in your `.Renviron` file as `NEST_CONSUMER_SECRET=&#8230;` (restart any open R sessions so R will re-read the `.Renviron` file). <\/p>\n<p>Once your API client information is setup, you&#8217;ll need a way of working with it. We first create a Nest OAuth endpoint that has the core URLs that `httr` will use to help authorize the client with. Unfortunately, not all OAuth 2.0 endpoints work the same way. For the Nest API an initial `state` parameter is required even if using PIN-based authentication (which we are in this example since Nest doesn&#8217;t honor a dynamic callback URL as far as I can tell). This is how top setup the `httr` endpoint.<\/p>\n<pre lang=\"rsplus\">library(httr)\r\nlibrary(jsonlite)\r\n\r\nnest <- oauth_endpoint(\r\n  request=NULL,\r\n  authorize=\"https:\/\/home.nest.com\/login\/oauth2?state=login\",\r\n  access=\"https:\/\/api.home.nest.com\/oauth2\/access_token\"\r\n)<\/pre>\n<p>Now, we need to setup the \"app\". This is more of an \"R\" need than an \"OAuth\" need. Use the _Client ID_ you copied earlier. `httr` will pull the secret from the environment variable you created.<\/p>\n<pre lang=\"rsplus\">nest_app <- oauth_app(\"nest\", key=\"a8bf6e0c-89a0-40ae-869a-943e928316f5\")<\/pre>\n<p>With that out of the way, now we authorize the client. Because we're using PIN-based authentication, the user will have to cut\/paste the URL displayed in the R Console into a browser then cut\/paste the PIN displayed in the browser back into the R Console. With `cache=TRUE` this will be a one-time event.<\/p>\n<pre lang=\"rsplus\">nest_token <- oauth2.0_token(nest, nest_app, use_oob=TRUE, cache=TRUE)<\/pre>\n<p>We can now use our shiny new token to make Nest API calls.<\/p>\n<p>### Using the Nest API<\/p>\n<p>Since this is not a detailed introduction to the Nest API in general, you may want to take the time to read [their documentation](https:\/\/developer.nest.com\/documentation\/topics\/api-guides-and-reference). Here's how to get a list of all the devices for the account and then read the data from the first thermostat. I'm gaming this a bit since I only have one Nest device and it is a thermostat, but you can use their simulator to play with more data.<\/p>\n<p>To get all the devices in use, it's just a call do the `devices` path. Again, not all OAuth 2.0 APIs work the same way, so instead of embedding the access token into the http request headers, you need to specify it in the query parameters:<\/p>\n<pre lang=\"rsplus\">req <- GET(\"https:\/\/developer-api.nest.com\",\r\n           path=\"devices\",\r\n           query=list(auth=nest_token$credentials$access_token))\r\nstop_for_status(req)\r\ndevices <- fromJSON(content(req, as=text))<\/pre>\n<p>Now, `devices` contains a very ugly list (most JSON APIs return really ugly responses) but we can easily get the ID of the first thermometer (which we'll need to use in the next API call) by doing:<\/p>\n<pre lang=\"rsplus\">first_thermostat <- names(devices$thermostats)[1]<\/pre>\n<p>Use `str(devices)` to see what else is there for use.<\/p>\n<p>Now, to get the data from thermostat, all you have to do is:<\/p>\n<pre lang=\"rsplus\">req <- GET(\"https:\/\/developer-api.nest.com\/\",\r\n           path=sprintf(\"devices\/thermostats\/%s\", first_thermostat),\r\n           query=list(auth=nest_token$credentials$access_token))\r\nstop_for_status(req)\r\nthermo <- data.frame(fromJSON(content(req, as=\"text\")),\r\n                     stringsAsFactors=FALSE)<\/pre>\n<p>And, you can display the current temperature\/humidity via:<\/p>\n<pre lang=\"rsplus\">cat(thermo$ambient_temperature_f, \"F \/ \", thermo$humidity, \"%\", sep=\"\")<\/pre>\n<p>### Fin<\/p>\n<p>Ideally, one would wrap this into a package (which I _may_ do but feel free to take this code and make one before I get the cycles to get to it) and add more error checking and convenience functions for working with the data. But, you can now adapt the [Nest+Shiny dashboard](http:\/\/blagrants.blogspot.com\/2015\/09\/nest-thermostat-and-r-creating-shiny.html) post code to use proper API calls and data structures vs `system(\"curl\u2026\")` and `gsub()`. <\/p>\n<p>A contiguous version of the above code is in [this gist](https:\/\/gist.github.com\/hrbrmstr\/2da2312170a84340c14f).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I glimpsed a [post](http:\/\/blagrants.blogspot.com\/2015\/09\/nest-thermostat-and-r-creating-shiny.html) in the RSS feeds today on how to connect Nest data with a Shiny dashboard and was compelled to post a less brute-force way to get data from the Nest API. The authors of the Shiny+Nest post used `system` calls to `curl` and regular expression character vector operations to slice, dice [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":3,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[760,49,759,91,758],"tags":[761,810],"class_list":["post-3672","post","type-post","status-publish","format-standard","hentry","category-apis","category-authentication","category-oauth","category-r","category-rest","tag-api","tag-post"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>A Better Way To Read Nest Data Into R - rud.is<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A Better Way To Read Nest Data Into R - rud.is\" \/>\n<meta property=\"og:description\" content=\"I glimpsed a [post](http:\/\/blagrants.blogspot.com\/2015\/09\/nest-thermostat-and-r-creating-shiny.html) in the RSS feeds today on how to connect Nest data with a Shiny dashboard and was compelled to post a less brute-force way to get data from the Nest API. The authors of the Shiny+Nest post used `system` calls to `curl` and regular expression character vector operations to slice, dice [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/\" \/>\n<meta property=\"og:site_name\" content=\"rud.is\" \/>\n<meta property=\"article:published_time\" content=\"2015-09-10T14:05:06+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-03-07T21:43:28+00:00\" \/>\n<meta name=\"author\" content=\"hrbrmstr\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"hrbrmstr\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/\"},\"author\":{\"name\":\"hrbrmstr\",\"@id\":\"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886\"},\"headline\":\"A Better Way To Read Nest Data Into R\",\"datePublished\":\"2015-09-10T14:05:06+00:00\",\"dateModified\":\"2018-03-07T21:43:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/\"},\"wordCount\":688,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886\"},\"keywords\":[\"API\",\"post\"],\"articleSection\":[\"APIs\",\"Authentication\",\"OAuth\",\"R\",\"REST\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/\",\"url\":\"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/\",\"name\":\"A Better Way To Read Nest Data Into R - rud.is\",\"isPartOf\":{\"@id\":\"https:\/\/rud.is\/b\/#website\"},\"datePublished\":\"2015-09-10T14:05:06+00:00\",\"dateModified\":\"2018-03-07T21:43:28+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/rud.is\/b\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A Better Way To Read Nest Data Into R\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/rud.is\/b\/#website\",\"url\":\"https:\/\/rud.is\/b\/\",\"name\":\"rud.is\",\"description\":\"&quot;In God we trust. All others must bring data&quot;\",\"publisher\":{\"@id\":\"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/rud.is\/b\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886\",\"name\":\"hrbrmstr\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1\",\"url\":\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1\",\"width\":460,\"height\":460,\"caption\":\"hrbrmstr\"},\"logo\":{\"@id\":\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1\"},\"description\":\"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7\",\"sameAs\":[\"http:\/\/rud.is\"],\"url\":\"https:\/\/rud.is\/b\/author\/hrbrmstr\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"A Better Way To Read Nest Data Into R - rud.is","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/","og_locale":"en_US","og_type":"article","og_title":"A Better Way To Read Nest Data Into R - rud.is","og_description":"I glimpsed a [post](http:\/\/blagrants.blogspot.com\/2015\/09\/nest-thermostat-and-r-creating-shiny.html) in the RSS feeds today on how to connect Nest data with a Shiny dashboard and was compelled to post a less brute-force way to get data from the Nest API. The authors of the Shiny+Nest post used `system` calls to `curl` and regular expression character vector operations to slice, dice [&hellip;]","og_url":"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/","og_site_name":"rud.is","article_published_time":"2015-09-10T14:05:06+00:00","article_modified_time":"2018-03-07T21:43:28+00:00","author":"hrbrmstr","twitter_card":"summary_large_image","twitter_misc":{"Written by":"hrbrmstr","Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/#article","isPartOf":{"@id":"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/"},"author":{"name":"hrbrmstr","@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"headline":"A Better Way To Read Nest Data Into R","datePublished":"2015-09-10T14:05:06+00:00","dateModified":"2018-03-07T21:43:28+00:00","mainEntityOfPage":{"@id":"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/"},"wordCount":688,"commentCount":1,"publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"keywords":["API","post"],"articleSection":["APIs","Authentication","OAuth","R","REST"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/","url":"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/","name":"A Better Way To Read Nest Data Into R - rud.is","isPartOf":{"@id":"https:\/\/rud.is\/b\/#website"},"datePublished":"2015-09-10T14:05:06+00:00","dateModified":"2018-03-07T21:43:28+00:00","breadcrumb":{"@id":"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/rud.is\/b\/2015\/09\/10\/a-better-way-to-read-nest-data-into-r\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/rud.is\/b\/"},{"@type":"ListItem","position":2,"name":"A Better Way To Read Nest Data Into R"}]},{"@type":"WebSite","@id":"https:\/\/rud.is\/b\/#website","url":"https:\/\/rud.is\/b\/","name":"rud.is","description":"&quot;In God we trust. All others must bring data&quot;","publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/rud.is\/b\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886","name":"hrbrmstr","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","contentUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","width":460,"height":460,"caption":"hrbrmstr"},"logo":{"@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1"},"description":"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7","sameAs":["http:\/\/rud.is"],"url":"https:\/\/rud.is\/b\/author\/hrbrmstr\/"}]}},"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p23idr-Xe","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":2618,"url":"https:\/\/rud.is\/b\/2013\/09\/04\/nizdos\/","url_meta":{"origin":3672,"position":0},"title":"nizdos &#8211; Nest Thermometer Notifications And Data Logging In Python","author":"hrbrmstr","date":"2013-09-04","format":false,"excerpt":"I've had a Nest thermometer for a while now and it's been an overall positive experience. It's given me more visibility into our heating\/cooling system usage, patterns and preferences; plus, it actually saved us money last winter. We try to avoid running the A\/C during the summer, and it would\u2026","rel":"","context":"In &quot;Development&quot;","block_context":{"text":"Development","link":"https:\/\/rud.is\/b\/category\/development\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":9442,"url":"https:\/\/rud.is\/b\/2018\/04\/04\/exploring-r-bloggers-posts-with-the-feedly-api\/","url_meta":{"origin":3672,"position":1},"title":"Exploring R-Bloggers Posts with the Feedly API","author":"hrbrmstr","date":"2018-04-04","format":false,"excerpt":"There's a yuge chance you're reading this post (at least initially) on R-Bloggers right now (though you should also check out R Weekly and add their live feed to your RSS reader pronto!). It's a central \"watering hole\" for R folks and is read by many (IIRC over 20,000 Feedly\u2026","rel":"","context":"In &quot;R&quot;","block_context":{"text":"R","link":"https:\/\/rud.is\/b\/category\/r\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2018\/04\/rb-post-count.png?fit=1200%2C568&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2018\/04\/rb-post-count.png?fit=1200%2C568&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2018\/04\/rb-post-count.png?fit=1200%2C568&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2018\/04\/rb-post-count.png?fit=1200%2C568&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2018\/04\/rb-post-count.png?fit=1200%2C568&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":5146,"url":"https:\/\/rud.is\/b\/2017\/03\/12\/think-twice-before-using-ohmconnect\/","url_meta":{"origin":3672,"position":2},"title":"Think Twice Before Using Ohmconnect","author":"hrbrmstr","date":"2017-03-12","format":false,"excerpt":"I listen to @NPR throughout the day (on most days) and a story on Ohmconnect piqued my interest (it aired 5 days prior to this post). The TLDR on Ohmconnect is that it ostensibly helps you save energy by making you more aware of consumption and can be enabled to\u2026","rel":"","context":"In &quot;Cybersecurity&quot;","block_context":{"text":"Cybersecurity","link":"https:\/\/rud.is\/b\/category\/cybersecurity\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/03\/OhmConnect-9.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/03\/OhmConnect-9.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/03\/OhmConnect-9.png?resize=525%2C300 1.5x"},"classes":[]},{"id":6164,"url":"https:\/\/rud.is\/b\/2017\/08\/22\/caching-httr-requests-this-means-warc\/","url_meta":{"origin":3672,"position":3},"title":"Caching httr Requests? This means WAR[C]!","author":"hrbrmstr","date":"2017-08-22","format":false,"excerpt":"I've blathered about my crawl_delay project before and am just waiting for a rainy weekend to be able to crank out a follow-up post on it. Working on that project involved sifting through thousands of Web Archive (WARC) files. While I have a nascent package on github to work with\u2026","rel":"","context":"In &quot;R&quot;","block_context":{"text":"R","link":"https:\/\/rud.is\/b\/category\/r\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4728,"url":"https:\/\/rud.is\/b\/2016\/12\/18\/package-update-longurl-0-3-0-is-hitting-cran-mirrors\/","url_meta":{"origin":3672,"position":4},"title":"Package update: longurl 0.3.0 is hitting CRAN mirrors","author":"hrbrmstr","date":"2016-12-18","format":false,"excerpt":"The longurl package has been updated to version 0.3.0 as a result of a bug report noting that the URL expansion API it was using went pay-for-use. Since this was the second time a short URL expansion service either went belly-up or had breaking changes the package is now completely\u2026","rel":"","context":"In &quot;R&quot;","block_context":{"text":"R","link":"https:\/\/rud.is\/b\/category\/r\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":10243,"url":"https:\/\/rud.is\/b\/2018\/05\/03\/seventeen-minutes-from-tweet-to-package\/","url_meta":{"origin":3672,"position":5},"title":"Seventeen Minutes From Tweet To Package","author":"hrbrmstr","date":"2018-05-03","format":false,"excerpt":"Earlier today, @noamross posted to Twitter: #rstats #lazyweb What's the R\/httr\/curl equivalent of curl -F \"file=@somefile.html\" https:\/\/t.co\/abbugLz9ZW\u2014 Noam Ross (@noamross) May 3, 2018 The answer was a 1:1 \"file upload\" curl to httr translation: but I wanted to do more than that since Noam took 20 minutes out his day\u2026","rel":"","context":"In &quot;R&quot;","block_context":{"text":"R","link":"https:\/\/rud.is\/b\/category\/r\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/3672","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/comments?post=3672"}],"version-history":[{"count":0,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/3672\/revisions"}],"wp:attachment":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/media?parent=3672"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/categories?post=3672"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/tags?post=3672"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}