Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 9 additions & 1 deletion R/api_check.R
Original file line number Diff line number Diff line change
Expand Up @@ -903,14 +903,17 @@
#' \itemize{
#' \item{
#' \code{.check_file()} throws an error if provided value is not a valid and
#' existing file path.
#' existing file path. With \code{allow_remote = TRUE}, remote files
#' (\code{http}, \code{https}, \code{s3}) are accepted after the extension
#' check, since they have no local path to be found or created.
#' }
#' }
#' @keywords internal
#' @noRd
.check_file <- function(x, ...,
extensions = NULL,
file_exists = TRUE,
allow_remote = FALSE,
local_msg = NULL,
msg = NULL) {
# check parameter name
Expand Down Expand Up @@ -945,6 +948,11 @@
local_msg = local_msg
)
}
# remote files are read by their consumer, so there is no local
# file to find or create
if (allow_remote && !.file_is_local(x)) {
return(invisible(x))
}
if (file_exists) {
existing_files <- file.exists(x)
existing_dirs <- dir.exists(x)
Expand Down
21 changes: 15 additions & 6 deletions R/sits_parquet.R
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,17 @@ sits_to_parquet.default <- function(data, file) {
#' Files from another layout version are read, not refused. A warning is
#' raised.
#'
#' @param file Full path of the file to read
#' Remote files (\code{http} or \code{https} URLs) are downloaded by
#' \code{arrow} to a temporary file before being read.
#'
#' @param file Full path or URL of the file to read
#' (valid file name with extension ".parquet").
#' @return Time series (tibble of class "sits").
#'
#' @note Requires the \code{arrow} and \code{jsonlite} packages.
#' @note Requires the \code{arrow} and \code{jsonlite} packages. Remote
#' files are downloaded with \code{utils::download.file}, which is limited
#' by \code{getOption("timeout")}. Large files may need a higher value,
#' e.g. \code{options(timeout = 600)}.
#'
#' @examples
#' if (sits_run_examples()) {
Expand All @@ -121,10 +127,13 @@ sits_to_parquet.default <- function(data, file) {
sits_from_parquet <- function(file) {
.check_set_caller("sits_from_parquet")
.check_require_packages(c("arrow", "jsonlite"))
.check_file(x = file, extensions = "parquet")
reader <- arrow::ParquetFileReader$create(file)
block <- reader$GetSchema()$metadata[["sits"]]
tbl <- arrow::read_parquet(file)
.check_file(x = file, extensions = "parquet", allow_remote = TRUE)
# read as arrow::Table
tbl <- arrow::read_parquet(file, as_data_frame = FALSE)
# extract metadata
block <- tbl$metadata[["sits"]]
# convert arow::Table to tibble
tbl <- tibble::as_tibble(tbl)
# no block: infer the class, then rebuild through the same path
if (!.has(block)) {
warning(.conf("messages", "sits_from_parquet_no_metadata"),
Expand Down
10 changes: 8 additions & 2 deletions man/sits_from_parquet.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions tests/testthat/test-parquet.R
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,30 @@ test_that("Parquet errors are informative", {
expect_error(suppressWarnings(sits_from_parquet(plain_file)))
})

test_that("Samples can be read from a remote parquet file", {
skip_if_not_installed("arrow")
skip_if_not_installed("jsonlite")

# a remote file must still have the parquet extension
expect_error(sits_from_parquet("https://example.com/samples.csv"))

skip_on_cran()
skip_if_offline()

# define remote file (parquet from sits book)
url <- paste0(
"https://huggingface.co/datasets/gilbertocamara/samples_book/",
"resolve/main/samples_deforestation_rondonia.parquet"
)

# read the file
samples <- sits_from_parquet(url)

expect_s3_class(samples, "sits")
expect_gt(nrow(samples), 0L)
expect_true("time_series" %in% colnames(samples))
})

test_that("Class is inferred when the file has no sits metadata", {
skip_if_not_installed("arrow")
skip_if_not_installed("jsonlite")
Expand Down
Loading