osfr
First, it is necessary to get an API key from OSF. Do this by heading
to your OSF project, your user settings, and selecting “create new
key”.

Keep that key safe, this is very important, ie don’t share it with
anyone.
That being said, we do need to store it somewhere so that
osfr
can access it. The most sensible place, and where
osfr
will look for it, is in a file called
.Renviron
in your home folder. We will first check if a
.Renviron
file exists already – if it does, we’ll add our
key to it – if it doesn’t, we’ll create it, and then add our key to
it.
To do this, we’ll use the ‘Terminal’ adjacent to the R Console.
# list all files in the home directory (~ is short for home, you can also try $HOME if ~ doesn't work)
# including hidden files (the -a does this)
# and then with grep, filter that list for the file name of interest
ls -a ~/ | grep ".Renviron"
If you’re presented with a blank line, .Renviron
doesn’t
exist. So let’s create it.
touch ~/.Renviron
And we’ll write our API token or key to the file, copying and pasting
your key after the =
sign below.
echo "OSF_PAT=" >> ~./Renviron
To validate this worked, you can run
cat ~./Renviron
You will need to restart R before this file and / or it’s new
information is accessible. To do this, go to
Session > Restart R
from the RStudio menu.
Next, we install, if not already installed, and load,
osfr
install.packages("osfr")
library(osfr)
## Automatically registered OSF personal access token
You should get the above output, indicating that osfr
has successfully found your API token so that you can authenticate.
Accessing your project
Next, we download the metadata associated with our OSF project.
You’ll need the url from the landing page of your OSF project.
jumpstart_project <- osf_retrieve_node("https://osf.io/uha5g/")
Then, we look at the list of files in our project:
js_files <- osf_ls_files(jumpstart_project)
js_files
## # A tibble: 9 × 3
## name id meta
## <chr> <chr> <list>
## 1 scripts 68220a2fc6762f78ebc0d856 <named list [3]>
## 2 data 68220a2fc6762f78ebc0d857 <named list [3]>
## 3 docs 68220a2fc6762f78ebc0d859 <named list [3]>
## 4 resources 68220a30c6762f78ebc0d860 <named list [3]>
## 5 tmp 68220a30c6762f78ebc0d86b <named list [3]>
## 6 README.md 68220a30c6762f78ebc0d86c <named list [3]>
## 7 outputs 68220a30c6762f78ebc0d86d <named list [3]>
## 8 license.txt 68220a30c6762f78ebc0d86e <named list [3]>
## 9 readme.md 68260dc6bbec12fd859c4265 <named list [3]>
A small caveat here, this works more easily with files than
directories, so we’ll simply explore this with a single file, like the
README.md file.
The meta
column is a list of metadata associate with
each file – we need to access the unique id of the file we want to
download before we can download it. This is the same 5 digit
alphanumeric code that we would see if we loaded the file for viewing
within OSF. So, you could access it that way too.
readmeFile <- js_files$meta[[6]]$attributes$guid
readmeFile
## [1] "ystfh"
We then download it. We need to resolve how to handle conflicts, and
here, I’m simply going to elect to overwrite any existing file with the
same name, as this is my first ‘pull’.
osf_retrieve_file(readmeFile) |>
osf_download(conflicts = "overwrite")
Since this is a markdown file, it can be opened and edited directly
in RStudio. Once you’re done for the day, we can send it back to OSF and
overwrite the one sitting on OSF servers.
osf_upload(jumpstart_project,
"README.md",
conflicts = "overwrite")
As long as you don’t change your file names, the unique ID of the
files never changes. So, once you know what you need to routinely back
up, you can get creative in automating this process using only
osf_upload()
to overwrite what’s on OSF servers.
While OSF with provide access to the historical versions of these
overwrites that you are performing, osfr
is not a version
control system, that is to say, it does not look for changes in files,
it does not compare dates on files, etc, it simply completely
overwrites.
LS0tCnRpdGxlOiAib3NmciIKcGFnZXRpdGxlOiAib3NmciIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2ZvbGRpbmc6IHNob3cgIyBhbGxvd3MgdG9nZ2xpbmcgb2Ygc2hvd2luZyBhbmQgaGlkaW5nIGNvZGUuIFJlbW92ZSBpZiBub3QgdXNpbmcgY29kZS4KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUgIyBhbGxvd3MgdGhlIHVzZXIgdG8gZG93bmxvYWQgdGhlIHNvdXJjZSAuUm1kIGZpbGUuIFJlbW92ZSBpZiBub3QgdXNpbmcgY29kZS4KICAgIGluY2x1ZGVzOgogICAgICBhZnRlcl9ib2R5OiBmb290ZXIuaHRtbCAjIGluY2x1ZGUgYSBjdXN0b20gZm9vdGVyLgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCiMjIG9zZnIKCkZpcnN0LCBpdCBpcyBuZWNlc3NhcnkgdG8gZ2V0IGFuIEFQSSBrZXkgZnJvbSBPU0YuIERvIHRoaXMgYnkgaGVhZGluZyB0byB5b3VyIE9TRiBwcm9qZWN0LCB5b3VyIHVzZXIgc2V0dGluZ3MsIGFuZCBzZWxlY3RpbmcgImNyZWF0ZSBuZXcga2V5Ii4KCiFbXShpbWFnZXMvb3NmL29zZkFQSXRva2VuLmdpZikKCktlZXAgdGhhdCBrZXkgc2FmZSwgdGhpcyBpcyB2ZXJ5IGltcG9ydGFudCwgaWUgZG9uJ3Qgc2hhcmUgaXQgd2l0aCBhbnlvbmUuCgpUaGF0IGJlaW5nIHNhaWQsIHdlIGRvIG5lZWQgdG8gc3RvcmUgaXQgc29tZXdoZXJlIHNvIHRoYXQgYG9zZnJgIGNhbiBhY2Nlc3MgaXQuIFRoZSBtb3N0IHNlbnNpYmxlIHBsYWNlLCBhbmQgd2hlcmUgYG9zZnJgIHdpbGwgbG9vayBmb3IgaXQsIGlzIGluIGEgZmlsZSBjYWxsZWQgYC5SZW52aXJvbmAgaW4geW91ciBob21lIGZvbGRlci4gV2Ugd2lsbCBmaXJzdCBjaGVjayBpZiBhIGAuUmVudmlyb25gIGZpbGUgZXhpc3RzIGFscmVhZHkgLS0gaWYgaXQgZG9lcywgd2UnbGwgYWRkIG91ciBrZXkgdG8gaXQgLS0gaWYgaXQgZG9lc24ndCwgd2UnbGwgY3JlYXRlIGl0LCBhbmQgdGhlbiBhZGQgb3VyIGtleSB0byBpdC4KClRvIGRvIHRoaXMsIHdlJ2xsIHVzZSB0aGUgJ1Rlcm1pbmFsJyBhZGphY2VudCB0byB0aGUgUiBDb25zb2xlLgoKYGBge2Jhc2gsIGV2YWwgPSBGQUxTRX0KIyBsaXN0IGFsbCBmaWxlcyBpbiB0aGUgaG9tZSBkaXJlY3RvcnkgKH4gaXMgc2hvcnQgZm9yIGhvbWUsIHlvdSBjYW4gYWxzbyB0cnkgJEhPTUUgaWYgfiBkb2Vzbid0IHdvcmspCiMgaW5jbHVkaW5nIGhpZGRlbiBmaWxlcyAodGhlIC1hIGRvZXMgdGhpcykKIyBhbmQgdGhlbiB3aXRoIGdyZXAsIGZpbHRlciB0aGF0IGxpc3QgZm9yIHRoZSBmaWxlIG5hbWUgb2YgaW50ZXJlc3QKbHMgLWEgfi8gfCBncmVwICIuUmVudmlyb24iCmBgYAoKSWYgeW91J3JlIHByZXNlbnRlZCB3aXRoIGEgYmxhbmsgbGluZSwgYC5SZW52aXJvbmAgZG9lc24ndCBleGlzdC4gU28gbGV0J3MgY3JlYXRlIGl0LgoKYGBge2Jhc2gsIGV2YWwgPSBGQUxTRX0KdG91Y2ggfi8uUmVudmlyb24KYGBgCgpBbmQgd2UnbGwgd3JpdGUgb3VyIEFQSSB0b2tlbiBvciBrZXkgdG8gdGhlIGZpbGUsIGNvcHlpbmcgYW5kIHBhc3RpbmcgeW91ciBrZXkgYWZ0ZXIgdGhlIGA9YCBzaWduIGJlbG93LgoKYGBge2Jhc2gsIGV2YWwgPSBGQUxTRX0KZWNobyAiT1NGX1BBVD0iID4+IH4uL1JlbnZpcm9uCmBgYAoKVG8gdmFsaWRhdGUgdGhpcyB3b3JrZWQsIHlvdSBjYW4gcnVuCgpgYGB7YmFzaCwgZXZhbCA9IEZBTFNFfQpjYXQgfi4vUmVudmlyb24KYGBgCgpZb3Ugd2lsbCBuZWVkIHRvIHJlc3RhcnQgUiBiZWZvcmUgdGhpcyBmaWxlIGFuZCAvIG9yIGl0J3MgbmV3IGluZm9ybWF0aW9uIGlzIGFjY2Vzc2libGUuIFRvIGRvIHRoaXMsIGdvIHRvIGBTZXNzaW9uID4gUmVzdGFydCBSYCBmcm9tIHRoZSBSU3R1ZGlvIG1lbnUuCgpOZXh0LCB3ZSBpbnN0YWxsLCBpZiBub3QgYWxyZWFkeSBpbnN0YWxsZWQsIGFuZCBsb2FkLCBgb3NmcmAKCmBgYHtyLCBldmFsID0gRkFMU0V9Cmluc3RhbGwucGFja2FnZXMoIm9zZnIiKQpsaWJyYXJ5KG9zZnIpCmBgYAoKYGBge3IsIGVjaG8gPSBGQUxTRX0KbGlicmFyeShvc2ZyKQpgYGAKCllvdSBzaG91bGQgZ2V0IHRoZSBhYm92ZSBvdXRwdXQsIGluZGljYXRpbmcgdGhhdCBgb3NmcmAgaGFzIHN1Y2Nlc3NmdWxseSBmb3VuZCB5b3VyIEFQSSB0b2tlbiBzbyB0aGF0IHlvdSBjYW4gYXV0aGVudGljYXRlLgoKIyMgQWNjZXNzaW5nIHlvdXIgcHJvamVjdAoKTmV4dCwgd2UgZG93bmxvYWQgdGhlIG1ldGFkYXRhIGFzc29jaWF0ZWQgd2l0aCBvdXIgT1NGIHByb2plY3QuIFlvdSdsbCBuZWVkIHRoZSB1cmwgZnJvbSB0aGUgbGFuZGluZyBwYWdlIG9mIHlvdXIgT1NGIHByb2plY3QuCgpgYGB7cn0KanVtcHN0YXJ0X3Byb2plY3QgPC0gb3NmX3JldHJpZXZlX25vZGUoImh0dHBzOi8vb3NmLmlvL3VoYTVnLyIpCmBgYAoKVGhlbiwgd2UgbG9vayBhdCB0aGUgbGlzdCBvZiBmaWxlcyBpbiBvdXIgcHJvamVjdDoKCmBgYHtyfQpqc19maWxlcyA8LSBvc2ZfbHNfZmlsZXMoanVtcHN0YXJ0X3Byb2plY3QpCmpzX2ZpbGVzCmBgYAoKQSBzbWFsbCBjYXZlYXQgaGVyZSwgdGhpcyB3b3JrcyBtb3JlIGVhc2lseSB3aXRoIGZpbGVzIHRoYW4gZGlyZWN0b3JpZXMsIHNvIHdlJ2xsIHNpbXBseSBleHBsb3JlIHRoaXMgd2l0aCBhIHNpbmdsZSBmaWxlLCBsaWtlIHRoZSBSRUFETUUubWQgZmlsZS4KClRoZSBgbWV0YWAgY29sdW1uIGlzIGEgbGlzdCBvZiBtZXRhZGF0YSBhc3NvY2lhdGUgd2l0aCBlYWNoIGZpbGUgLS0gd2UgbmVlZCB0byBhY2Nlc3MgdGhlIHVuaXF1ZSBpZCBvZiB0aGUgZmlsZSB3ZSB3YW50IHRvIGRvd25sb2FkIGJlZm9yZSB3ZSBjYW4gZG93bmxvYWQgaXQuIFRoaXMgaXMgdGhlIHNhbWUgNSBkaWdpdCBhbHBoYW51bWVyaWMgY29kZSB0aGF0IHdlIHdvdWxkIHNlZSBpZiB3ZSBsb2FkZWQgdGhlIGZpbGUgZm9yIHZpZXdpbmcgd2l0aGluIE9TRi4gU28sIHlvdSBjb3VsZCBhY2Nlc3MgaXQgdGhhdCB3YXkgdG9vLgoKYGBge3J9CnJlYWRtZUZpbGUgPC0ganNfZmlsZXMkbWV0YVtbNl1dJGF0dHJpYnV0ZXMkZ3VpZApyZWFkbWVGaWxlCmBgYAoKV2UgdGhlbiBkb3dubG9hZCBpdC4gV2UgbmVlZCB0byByZXNvbHZlIGhvdyB0byBoYW5kbGUgY29uZmxpY3RzLCBhbmQgaGVyZSwgSSdtIHNpbXBseSBnb2luZyB0byBlbGVjdCB0byBvdmVyd3JpdGUgYW55IGV4aXN0aW5nIGZpbGUgd2l0aCB0aGUgc2FtZSBuYW1lLCBhcyB0aGlzIGlzIG15IGZpcnN0ICdwdWxsJy4KCmBgYHtyLCBldmFsID0gRkFMU0V9Cm9zZl9yZXRyaWV2ZV9maWxlKHJlYWRtZUZpbGUpIHw+CiAgb3NmX2Rvd25sb2FkKGNvbmZsaWN0cyA9ICJvdmVyd3JpdGUiKQpgYGAKClNpbmNlIHRoaXMgaXMgYSBtYXJrZG93biBmaWxlLCBpdCBjYW4gYmUgb3BlbmVkIGFuZCBlZGl0ZWQgZGlyZWN0bHkgaW4gUlN0dWRpby4gT25jZSB5b3UncmUgZG9uZSBmb3IgdGhlIGRheSwgd2UgY2FuIHNlbmQgaXQgYmFjayB0byBPU0YgYW5kIG92ZXJ3cml0ZSB0aGUgb25lIHNpdHRpbmcgb24gT1NGIHNlcnZlcnMuCgpgYGB7ciwgZXZhbCA9IEZBTFNFfQpvc2ZfdXBsb2FkKGp1bXBzdGFydF9wcm9qZWN0LAogICAgICAgICAgICJSRUFETUUubWQiLAogICAgICAgICAgIGNvbmZsaWN0cyA9ICJvdmVyd3JpdGUiKQpgYGAKCkFzIGxvbmcgYXMgeW91IGRvbid0IGNoYW5nZSB5b3VyIGZpbGUgbmFtZXMsIHRoZSB1bmlxdWUgSUQgb2YgdGhlIGZpbGVzIG5ldmVyIGNoYW5nZXMuIFNvLCBvbmNlIHlvdSBrbm93IHdoYXQgeW91IG5lZWQgdG8gcm91dGluZWx5IGJhY2sgdXAsIHlvdSBjYW4gZ2V0IGNyZWF0aXZlIGluIGF1dG9tYXRpbmcgdGhpcyBwcm9jZXNzIHVzaW5nIG9ubHkgYG9zZl91cGxvYWQoKWAgdG8gb3ZlcndyaXRlIHdoYXQncyBvbiBPU0Ygc2VydmVycy4KCjo6Om5vdGUKV2hpbGUgT1NGIHdpdGggcHJvdmlkZSBhY2Nlc3MgdG8gdGhlIGhpc3RvcmljYWwgdmVyc2lvbnMgb2YgdGhlc2Ugb3ZlcndyaXRlcyB0aGF0IHlvdSBhcmUgcGVyZm9ybWluZywgYG9zZnJgIGlzIG5vdCBhIHZlcnNpb24gY29udHJvbCBzeXN0ZW0sIHRoYXQgaXMgdG8gc2F5LCBpdCBkb2VzIG5vdCBsb29rIGZvciBjaGFuZ2VzIGluIGZpbGVzLCBpdCBkb2VzIG5vdCBjb21wYXJlIGRhdGVzIG9uIGZpbGVzLCBldGMsIGl0IHNpbXBseSBjb21wbGV0ZWx5IG92ZXJ3cml0ZXMuCjo6OgoKCgoKCgoK