Skip to content
Open

Dev #19

Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7356e99
add return to dlw_country_catalog()
Tefera19 Feb 18, 2026
447b7c3
add qs2 format
Tefera19 Feb 18, 2026
fba2a31
implement {stamp} to load and save dlw data and update documentation
Tefera19 Feb 18, 2026
16b2879
rename helper functions with dot prefix
Tefera19 Feb 18, 2026
7bb8af0
{stamp} add to the description file
Tefera19 Feb 18, 2026
7bff556
update dlw.Rmd
Tefera19 Feb 18, 2026
58d03e3
country and server catalogs vignettes added
Tefera19 Feb 18, 2026
7d1979f
unit tests added for country and server catalogs
Tefera19 Feb 18, 2026
b154698
add categories to _pkgdown.yml
Tefera19 Feb 18, 2026
a577790
updated _pkgdown.yml
Tefera19 Feb 19, 2026
abd1b2b
fix the issue in yaml file
Tefera19 Feb 19, 2026
c79bbd6
update pkgdown yaml file
Tefera19 Feb 26, 2026
c9d5140
Update the vignettes - wrap API-dependent chunks with a condition tha…
Tefera19 Mar 5, 2026
ddaad84
remove eval from the knitr setup
Tefera19 Mar 5, 2026
8088a70
rename dlw, dlw_country_catalog, and dlw_serve_catalog Rmds to .Rmd.orig
Tefera19 Mar 5, 2026
689a621
generate Rmd with executed codes
Tefera19 Mar 5, 2026
91cd891
update pkgdown.yaml
Tefera19 Mar 5, 2026
4ce9cb9
update pkgdown yaml
Tefera19 Mar 5, 2026
208276e
fix yaml
Tefera19 Mar 5, 2026
ae77278
yaml file uupdated
Tefera19 Mar 13, 2026
ae331d8
fix issues in yaml file
Tefera19 Mar 13, 2026
835c787
README.md generated
Tefera19 Mar 13, 2026
933b497
Merge branch 'master' into dev
Tefera19 Mar 13, 2026
f7c4f1b
unit test for dlw_get_gmd with stamp
Tefera19 Mar 16, 2026
1b0abc6
README.html deleted; unit test for dlw_get_gmd with stamp has created
Tefera19 Mar 16, 2026
82b6b52
Merge branch 'dev' of https://github.com/worldbank/dlw into dev
Tefera19 Mar 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Imports:
haven,
httr2,
keyring,
pins,
stamp,
rlang,
stats
Suggests:
Expand All @@ -32,3 +32,5 @@ Suggests:
rmarkdown
Config/testthat/edition: 3
VignetteBuilder: knitr
Remotes:
github::randrescastaneda/stamp
1 change: 1 addition & 0 deletions R/dlw_country_catalog.R
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ dlw_country_catalog <- function(country_code,
ctl <- handle_resp(req)

set_in_dlwenv(key, ctl, verbose)
return(ctl)
}
148 changes: 94 additions & 54 deletions R/dlw_get_data.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
#' Get data from datalibweb (refactored)
#'
#' @description
#' `dlw_get_data()` function is the main user-facing function for
#' retrieving datasets from the Datalibweb (DLW) API. It handles
#' downloading, caching, and reading datasets, supporting both local
#' and temporary storage.
#'
#' **How it works:**
#' 1. Checks if the requested file exists locally (unless `local_overwrite = TRUE`).
#' 2. If it exists, reads it using `.dlw_read()`.
#' 3. If not, downloads the data from the DLW API using `.dlw_download()`, saves
#' it in the specified format, and returns it as a `data.table`.
#' 4. Handles directory management and caching via `.get_wrk_board()`.
#'
#' This function streamlines access to DLW datasets, automatically
#' managing download, storage, and retrieval.
#'
#' @param filename character: Name of the file to save/read (required)
#' @inheritParams dlw_country_catalog
#' @inheritParams dlw_server_catalog
Expand All @@ -10,7 +26,7 @@
#' @param local logical: whether or not to save and read data locally. default
#' is TRUE if `local_dir` exists.
#' @param format character: File format to use for pinning data ('parquet'
#' [default] or 'qs')
#' [default] or 'qs2')
#' @param local_overwrite logical. Whether to overwrite any saved data. Default
#' is FALSE
#' @param version numeric: Version of the pin to read (for pinning data
Expand All @@ -33,50 +49,53 @@ dlw_get_data <- function(country_code,
cli::cli_abort("{.arg filename} is a required argument.")
}

# Construct board and pin_name for reading
board <- get_wrk_board(local = local,
local_dir = local_dir)
# Construct directory and id_name for reading
dlw_dir <- .get_wrk_board(local = local, local_dir = local_dir)

pin_name <- filename |>
id_name <- filename |>
fs::path_ext_remove() |>
fs::path(ext = format)

# set in dlwenv
set_in_dlwenv("current_board", board)
set_in_dlwenv("current_pin", pin_name)
set_in_dlwenv("current_board", dlw_dir)
set_in_dlwenv("current_pin", id_name)

files_in_dir <- basename(list.files(dlw_dir))

if (!local_overwrite && pin_name %in% pins::pin_list(board)) {
if (!local_overwrite && id_name %in% files_in_dir) {
# Only read the requested version, do not download
out <- dlw_read(board = board,
pin_name = pin_name,
version = version)
out <- .dlw_read(dlw_dir = dlw_dir,
id_name = id_name,
version = version)
return(out)
}

dlw_download(country_code = country_code,
server = server,
filename = filename,
format = format,
board = board,
pin_name = pin_name,
...,
verbose = verbose)
.dlw_download(
country_code = country_code,
server = server,
filename = filename,
format = format,
dlw_dir = dlw_dir,
id_name = id_name,
...,
verbose = verbose
)
}


#' Download data from datalibweb and save as a pin
#' Download data from datalibweb and save using stamp framework
#'
#' @inheritParams dlw_get_data
#' @inheritParams dlw_read
#' @inheritParams .dlw_read
#' @param filename character: Name of the file to save/read (required)
#' @param format character: File format to use for pinning data ('qs'
#' @param format character: File format to use for saving data ('qs2'
#' [default] or 'parquet')
#' @returns A list with the board and pin_name used
#' @keywords internal
dlw_download <- function(country_code,
.dlw_download <- function(country_code,
filename,
board,
pin_name,
dlw_dir,
id_name,
format,
server = NULL,
...,
Expand All @@ -98,39 +117,47 @@ dlw_download <- function(country_code,
dots)

raw_data <- do.call("build_request", args) |>
get_raw_data()
.get_raw_data()

# Save raw data to a temp file for reading
tmpfile <- fs::file_temp(ext = "dta")
writeBin(raw_data, tmpfile)

# Read .dta and pin as parquet or qs
# Read .dta and save it as qs2 using {stamp}
dt <- haven::read_dta(tmpfile, encoding = "latin1") |>
setDT()
unlink(tmpfile)
pins::pin_write(board = board,
x = dt,
name = pin_name,
type = format,
versioned = TRUE)

stamp::st_save(dt, fs::path(dlw_dir, id_name), alias = "dlw")
Comment thread
Tefera19 marked this conversation as resolved.
dt
}

#' Read data from a pin (local or temp)
#'
#' @param board A pins board object (as returned by dlw_download)
#' @param pin_name The name of the pin (as returned by dlw_download)
#' @param version numeric: Version of the pin to read (for pinning data
#' Reads a dataset from a specified directory and file name, returning it as a `data.table`.
#'
#' - Lists files in `dlw_dir` and checks if `id_name` exists.
#' - If not found, aborts with an error.
#' - Removes any extension from `id_name`.
#' - Loads the data using `stamp::st_load()` from a `.qs2` file in the directory.
#'
#' This function is used internally to retrieve previously saved or downloaded datasets in a fast, versioned format.
#'
#' @param dlw_dir A folder object (as returned by .dlw_download)
#' @param id_name The name of the a dataset (as returned by .dlw_download)
#' @param version numeric: Version of the data to read (for versioning data
#' retrieval only)
#' @returns data.table
#' @keywords internal
dlw_read <- function(board, pin_name, version = NULL) {
.dlw_read <- function(dlw_dir, id_name, version = NULL) {

if (!(pin_name %in% pins::pin_list(board))) {
cli::cli_abort("File {.file {pin_name}} not found in the provided board.")
files_in_dir <- basename(list.files(dlw_dir))

if (!(id_name %in% files_in_dir)) {
cli::cli_abort("File {.file {id_name}} not found in the provided directory.")
}
pins::pin_read(board, pin_name, version = version) |>
setDT()

stamp::st_load(fs::path(dlw_dir, id_name), alias = "dlw")

}

Expand All @@ -142,36 +169,49 @@ dlw_read <- function(board, pin_name, version = NULL) {
#'
#' @returns raw data from [resp_body_raw]
#' @keywords internal
get_raw_data <- \(req) {
.get_raw_data <- \(req) {

raw_data <- handle_resp(req)

set_in_dlwenv(key = "last_raw_data", value = raw_data)

}

# return raw data so callers receive the bytes
raw_data

}



#' Get workign pips board
#' Get working folder for saving or reading data
#'
#' Determines the directory to use for saving or reading data, depending on whether you want to use a local directory or a temporary one.
#'
#' - If `local` is `TRUE`, it checks if `local_dir` exists. If not, it creates it (using `fs::dir_create()`). It then returns this directory path.
#' - If `local` is `FALSE`, it tries to get a temporary directory path from the package environment (`get_from_dlwenv("temp_dir")`). If this does not exist, it creates a new temporary directory, stores its path in the environment, and returns it.
#'
#' This function ensures that data is always saved to a valid directory, either user-specified or temporary.
#'
#' @inheritParams dlw_get_data
#' @returns board from (pins) package
#' @returns Folder path
#' @keywords internal
get_wrk_board <- function(local, local_dir) {
.get_wrk_board <- function(local, local_dir) {
if (local) {
if (fs::is_dir(local_dir)) {
pins::board_folder(local_dir)
if (!fs::is_dir(local_dir)) {
wrk_dir <- fs::dir_create(local_dir)
} else {
pins::board_local(local_dir)
wrk_dir <- fs::dir_create(local_dir)
}
} else {
brd <- get_from_dlwenv("temp_board")
if (is.null(brd)) {
brd <- pins::board_temp()
set_in_dlwenv(key = "temp_board", value = brd)
wrk_dir <- get_from_dlwenv("temp_dir")

if (is.null(wrk_dir)) {
#wrk_dir <- fs::path_temp("wrk_dir")
#fs::dir_create(wrk_dir)
wrk_dir <- fs::path(tempdir())
stamp::st_init(wrk_dir, alias = "dlw")

set_in_dlwenv(key = "temp_dir", value = wrk_dir)
}
brd
wrk_dir
}
}
8 changes: 4 additions & 4 deletions R/zzz.R
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
op.dlw <- list(
dlw.verbose = TRUE,
dlw.verbose = TRUE,
dlw.default_api_version = "v1",
dlw.output_method = cli::ansi_has_hyperlink_support(),
dlw.output_method = cli::ansi_has_hyperlink_support(),
cli.ignore_unknown_rstudio_theme = TRUE,
dlw.local_dir = Sys.getenv("DLW_local_dir"),
dlw.board_type = c("folder", "local"),
dlw.format = c("qs", "parquet"),
#dlw.board_type = c("folder", "local"),
dlw.format = c("qs2", "qs", "parquet"),
dlw.download_formats = c("dta") # we could add more later.
)

Expand Down
2 changes: 1 addition & 1 deletion README.Rmd
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
output: github_document
---

[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/worldbank/dlw)
<!-- README.md is generated from README.Rmd. Please edit that file -->

```{r, include = FALSE}
Expand Down
Loading
Loading