-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from ScotGovAnalysis/vignettes
Add vignettes for authentication and example workflow
- Loading branch information
Showing
7 changed files
with
293 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#' Generate random UUID | ||
#' | ||
#' @param seed Integer to set seed for random sampling. Default value is NULL. | ||
#' | ||
#' @return A single character value in the format of eight blocks of four | ||
#' letters/integers separated by dashes. | ||
#' | ||
#' @noRd | ||
|
||
random_uuid <- function(seed = NULL) { | ||
|
||
options <- c(letters, 0:9) | ||
|
||
# There should be equal probability of a letter or integer being sampled | ||
prob_weights <- c(rep(1/26, 26), rep(1/10, 10)) | ||
|
||
set.seed(seed) | ||
|
||
replicate(8, paste0(sample(options, 4, replace = TRUE, prob = prob_weights), | ||
collapse = "")) |> | ||
paste0(collapse = "-") | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
|
||
test_that("Single character value returned", { | ||
|
||
expect_type(random_uuid(), "character") | ||
|
||
expect_length(random_uuid(), 1) | ||
|
||
}) | ||
|
||
test_that("Returned value format correct", { | ||
|
||
pattern_exp <- paste(rep("[a-z0-9]{4}", 8), collapse = "-") | ||
|
||
expect_true(grepl(pattern = pattern_exp, x = random_uuid())) | ||
|
||
}) | ||
|
||
test_that("Not setting seed returns random value", { | ||
|
||
sample_5 <- replicate(5, random_uuid()) | ||
|
||
expect_true(length(unique(sample_5)) == 5) | ||
|
||
}) | ||
|
||
test_that("Setting seed returns consistent value", { | ||
|
||
expect_identical( | ||
random_uuid(1234), | ||
random_uuid(1234) | ||
) | ||
|
||
}) | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
--- | ||
title: "Authentication" | ||
output: rmarkdown::html_vignette | ||
vignette: > | ||
%\VignetteIndexEntry{Authentication} | ||
%\VignetteEngine{knitr::rmarkdown} | ||
%\VignetteEncoding{UTF-8} | ||
--- | ||
|
||
```{r, include = FALSE} | ||
knitr::opts_chunk$set( | ||
eval = FALSE | ||
) | ||
``` | ||
|
||
## How authentication works | ||
|
||
The first time you send a request, the API requires your Objective Connect user email address and password to authenticate. | ||
|
||
Each successful response from the API includes a token. This token can then be used to authenticate subsequent requests in your session, negating the need to repeatedly supply your email address and password. | ||
|
||
The rest of this article details how to manage authentication when using the `objectiveR` package. | ||
|
||
|
||
## First request | ||
|
||
You will need your Objective Connect user email address and password to make a first request to the API. These can be provided in two ways. | ||
|
||
### R Environment variables | ||
|
||
Add two variables to your `.Renviron` file to define your email address and password. | ||
|
||
* Open your `.Renviron` file to edit: | ||
|
||
```{r open_renviron} | ||
usethis::edit_r_environ() | ||
``` | ||
|
||
* Add two variables as follows: | ||
|
||
```{r add_vars} | ||
OBJECTIVER_USR = "XXX" | ||
OBJECTIVER_PWD = "XXX" | ||
``` | ||
|
||
* Save and close the `.Renviron` file. | ||
|
||
* To check this has worked as expected, first restart your R session then: | ||
|
||
```{r check_vars} | ||
Sys.getenv("OBJECTIVER_USR") | ||
Sys.getenv("OBJECTIVER_PWD") | ||
``` | ||
|
||
Your credentials should be printed in the console. | ||
|
||
Note: For this reason, it is important not to save your R session workspace on close as your console may contain your Objective Connect credentials. | ||
|
||
The benefit of this method is that you can leave this information in your `.Renviron` file and `objectiveR` will automatically find them here each time you use the package. | ||
|
||
|
||
### Supply credentials when prompted | ||
|
||
If you don't have these variables defined in your `.Renviron` file, `objectiveR` will prompt you to supply them if you're working in an interactive session. | ||
|
||
<br> | ||
|
||
```{r} | ||
#| eval: true | ||
#| echo: false | ||
#| fig-align: "center" | ||
#| fig-alt: > | ||
#| A small pop-up window with prompt 'Enter email registered with Objective | ||
#| Connect' followed by a text input box and buttons to select 'OK' or | ||
#| 'Cancel'. | ||
knitr::include_graphics("auth_prompt.png", dpi = "retina") | ||
``` | ||
|
||
|
||
## Subsequent requests | ||
|
||
Each successful API response includes a token that can be used for subsequent requests. `objectiveR` functions automatically parse this token from the API response and store it in your R session's global environment. | ||
|
||
Where this object exists, `objectiveR` will automatically use it to authenticate subsequent requests. | ||
|
||
If this object doesn't exist, `objectiveR` will resort to using your username and password, as it did for your [first request](#first-request). | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
--- | ||
title: "Introduction to objectiveR" | ||
output: rmarkdown::html_vignette | ||
vignette: > | ||
%\VignetteIndexEntry{Introduction to objectiveR} | ||
%\VignetteEngine{knitr::rmarkdown} | ||
%\VignetteEncoding{UTF-8} | ||
--- | ||
|
||
```{r, include = FALSE} | ||
knitr::opts_chunk$set( | ||
eval = FALSE | ||
) | ||
``` | ||
|
||
objectiveR aims to provide a convenient method of interacting with [Objective Connect](https://secure.objectiveconnect.co.uk) using R, making use of the [Objective Connect API](https://secure.objectiveconnect.co.uk/publicapi/1/swagger-ui/index.html). | ||
|
||
This article demonstrates a simple workflow for using the package, with the ultimate aim of downloading or uploading a file to an Objective Connect workspace. | ||
|
||
Start by loading the package in your R session: | ||
|
||
```{r setup} | ||
library(objectiveR) | ||
``` | ||
|
||
|
||
## Universally Unique Identifiers | ||
|
||
It is useful to be aware that everything on Objective Connect is associated with a Universally Unique Identifier (UUID). This includes users, workgroups, workspaces, participants in a workspace and assets in a workspace. | ||
|
||
Objective Connect UUIDs take the form of a string of eight chunks of four lower case letters and numbers, separated by dashes. For example: | ||
|
||
``` | ||
84op-9qdu-c692-t4z1-wa4z-h9k3-8454-i71f | ||
``` | ||
|
||
Use of the API and the objectiveR package depends on these UUIDs. UUIDs are mostly findable using the functions in objectiveR (as demonstrated in this article), however you can often also find relevant UUIDs in the webpage URLs. For example, this is an example URL when viewing a workspace: | ||
|
||
``` | ||
https://secure.objectiveconnect.co.uk/share/2vo2-dd3s-1nn9-y20r-b906-u4s2- | ||
7134-b352?workgroupUuid=2j47-ff38-lcgg-mnis-3vq8-9536-9jfp-oy44 | ||
``` | ||
|
||
The UUID for the workspace is `2vo2-dd3s-1nn9-y20r-b906-u4s2-7134-b352` and the UUID for the workgroup is `2j47-ff38-lcgg-mnis-3vq8-9536-9jfp-oy44`. | ||
|
||
|
||
## Test your authentication | ||
|
||
To interact with the Objective Connect API, you must provide valid authentication. This is explained in more detail in `vignette("authentication")`. | ||
|
||
It might be a good idea to test your authentication, especially if it's your first time using the package. There is no specific function for this, but the following simple function to get your own user ID requires no input and is an easy way to test that you can get a successful response from the API. | ||
|
||
```{r user} | ||
me <- my_user_id() | ||
``` | ||
|
||
|
||
## Workspaces | ||
|
||
To see workspaces you are a member of: | ||
|
||
```{r workspaces} | ||
workspaces <- my_workspaces() | ||
``` | ||
|
||
This returns a data frame with a row for each workspace you are a member of. Among other things, there will be a column containing the workspace name and another containing the workspace UUID. For example: | ||
|
||
```{r workspaces-output, eval = TRUE, echo = FALSE} | ||
data.frame( | ||
workspace_name = c("Project 1", "Project 2"), | ||
workspace_uuid = sapply(1:2, objectiveR:::random_uuid) | ||
) | ||
``` | ||
|
||
|
||
## Assets | ||
|
||
Maybe you would like to download a file from one of your workspaces. In Objective Connect, files are also known as 'assets'. To download an asset, you'll need its UUID. | ||
|
||
Use the workspace UUID from `workspaces` to get a data frame of assets in the workspace: | ||
|
||
```{r assets} | ||
assets <- workspace_assets("84op-9qdu-c692-t4z1-wa4z-h9k3-8454-i71f") | ||
``` | ||
|
||
This returns a data frame with a row for each asset in the workspace. Among other things, there will be a column containing the asset name and another containing the asset UUID. | ||
|
||
```{r assets-output, eval = TRUE, echo = FALSE} | ||
data.frame( | ||
uuid = sapply(3:4, objectiveR:::random_uuid), | ||
name = c("asset1", "asset2") | ||
) | ||
``` | ||
|
||
|
||
## Download file | ||
|
||
To download a document, use its UUID and the file path of the folder you'd like the downloaded file to be saved to: | ||
|
||
```{r download} | ||
download_file(document_uuid = "2j47-ff38-lcgg-mnis-3vq8-9536-9jfp-oy44", | ||
folder = here::here("data")) | ||
``` | ||
|
||
This function doesn't return anything but will display a message in the R console to indicate the download has been a success and to confirm the location of the file: | ||
|
||
```{r download-output, eval = TRUE, echo = FALSE, message = TRUE} | ||
cli::cli_alert_success( | ||
"File downloaded: project-1/data/file1.csv." | ||
) | ||
``` | ||
|
||
|
||
## Upload file | ||
|
||
To upload a file to a workspace, use the UUID of the workspace and the file path of the file to upload: | ||
|
||
```{r upload} | ||
new_document(here::here("data", "file2.csv"), | ||
workspace_uuid = "84op-9qdu-c692-t4z1-wa4z-h9k3-8454-i71f") | ||
``` | ||
|
||
This function doesn't return anything but will display a message in the R console to indicate the upload has been a success and to confirm the name of the file. | ||
|
||
```{r upload-output, eval = TRUE, echo = FALSE, message = TRUE} | ||
cli::cli_alert_success( | ||
"New document created: file2.csv." | ||
) | ||
``` | ||
|
||
Now, if you rerun the previous step to get a data frame of workspace assets, you should see an additional row for the file you've just uploaded. | ||
|
||
```{r assets2} | ||
assets <- workspace_assets("84op-9qdu-c692-t4z1-wa4z-h9k3-8454-i71f") | ||
``` | ||
|
||
```{r assets2-output, eval = TRUE, echo = FALSE} | ||
data.frame( | ||
uuid = sapply(3:5, objectiveR:::random_uuid), | ||
name = c("Asset 1", "Asset 2", "file2") | ||
) | ||
``` | ||
|