Skip to content
Merged

Dev #305

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
ba16081
Updates to taxonomic and metadata help files
mjwestgate Feb 18, 2026
1791bae
First pass supporting event queries (#226)
mjwestgate Feb 20, 2026
93301ae
First pass at including `describe()` (#291)
mjwestgate Feb 23, 2026
59a9375
Further progress on events
mjwestgate Mar 17, 2026
94abfbf
Ensure functions work with `galah::` syntax without first calling `li…
mjwestgate Mar 17, 2026
72310ae
Iterate version number, add skip-tests when offline
mjwestgate Mar 17, 2026
821308a
Re-add list metadata columns #293
daxkellie Mar 20, 2026
711685d
First pass at supporting `from` argument in `request_data()` (#297)
mjwestgate Mar 27, 2026
8d7f2ed
First pass at enabling authentication across atlases (#296)
mjwestgate Mar 31, 2026
865bd80
Improved behaviour in `read_zip()` when source atlas is unknown (#297)
mjwestgate Apr 1, 2026
c57adb2
Support `select()` for GBIF occurrence queries
mjwestgate Apr 1, 2026
ca18f32
move older `galah_` functions to `superseded`
mjwestgate Apr 1, 2026
652dce5
Minor update to docs
mjwestgate Apr 9, 2026
f4c6931
Re-arrange `authenticate()` to handle all JWT- and email-based authen…
mjwestgate Apr 22, 2026
46b9fae
Fix bug in `read_zip()` preventing storage of citation info (#297)
mjwestgate Apr 23, 2026
ffbaf26
Misc bug fixes from `test()`
mjwestgate Apr 23, 2026
c341c1b
Temporarily deactivate events for next release (#226)
mjwestgate Apr 23, 2026
d77235c
fix `glimpse` pipeline
mjwestgate Apr 24, 2026
13a6e9e
Fix `url_lookup()`
mjwestgate Apr 24, 2026
2867a30
More bug fixes
mjwestgate Apr 29, 2026
994f5d6
supersede last `galah_` piped queries
mjwestgate Apr 29, 2026
5d07168
update tests for `geolocate_` functions
mjwestgate Apr 30, 2026
f9be3fc
Fix tests/bugs for Kew, Spain, Sweden
mjwestgate May 1, 2026
cf60682
Fix bugs in GBIF code & tests
mjwestgate May 2, 2026
a9f6330
Update DESCRIPTION, NEWS, and QSG
mjwestgate May 3, 2026
36cf5f7
minor test updates
mjwestgate May 3, 2026
f4af338
Update gitignore and Rbuildignore
daxkellie May 13, 2026
541eca1
minor addition to `describe()` docs
daxkellie May 13, 2026
433507d
Add deprecation warnings
daxkellie May 13, 2026
25aa173
Ensure GBIF count requests get user/password from query, not potions
mjwestgate May 16, 2026
2b1f622
Supersede rather than deprecate `galah_` functions
mjwestgate May 16, 2026
9a8f5d9
Add further test for authentication with count data in GBIF
mjwestgate May 16, 2026
8fa2480
Fix for miscellaneous GBIF bugs (#299)
mjwestgate May 27, 2026
6e5e3e6
First pass at supporting ALA specieslist API v2 (#300)
mjwestgate May 27, 2026
0c68e5c
First pass at response to Security, Vulnerability & Performance Review
mjwestgate May 28, 2026
55b34a6
Update specieslists urls to `api.ala.org.au/specieslist/v2` (#300)
mjwestgate May 28, 2026
64e2ef7
Bug fixes to GBIF count queries introduced by changes to `query_API()`
mjwestgate Jun 1, 2026
ddba12c
Support auto-population of `q` parameter where possible (#301)
mjwestgate Jun 2, 2026
3195114
Fix minor bug affecting media downloads
mjwestgate Jun 2, 2026
ba3bc4e
Update behaviour for lists v2 on ALA
mjwestgate Jun 2, 2026
60d7616
Update tests to work adequately with new specieslist API (#300)
mjwestgate Jun 4, 2026
4988575
Minor changes to tests, news
mjwestgate Jun 29, 2026
3406aec
Fix v2 list output and pagination, fix `show_values()` #300
daxkellie Jul 23, 2026
cb9c536
Re-add `species_list_uid` to `show_values()` result #300
daxkellie Jul 24, 2026
d97400b
Fix queries that use `geolocate()` #301
daxkellie Jul 24, 2026
6e8e48e
Add CRS warning to `galah_polygon()` #302
daxkellie Jul 24, 2026
3501399
Add CRS test to `geolocate_bbox()` #302
daxkellie Jul 24, 2026
430add8
Fix query parsing #303
daxkellie Aug 25, 2026
acc395e
First pass at resolving #298
mjwestgate Aug 31, 2026
cb78bd4
Allow `NA` crs vaues in `check_crs()` (#302)
mjwestgate Aug 31, 2026
c9d49fd
revise `check_crs()` to inform when NA is given (#302)
mjwestgate Sep 1, 2026
4158776
Integrate list-unnest lookup with `compound()` workflow (#300)
mjwestgate Sep 1, 2026
ddd630d
Ensure `collect()` works for type `lists-unnest` (#300)
mjwestgate Sep 2, 2026
5a76734
Misc improvements such that R CMD Check passes while offline
mjwestgate Sep 4, 2026
58db168
Misc bug fixes to code and tests
mjwestgate Sep 4, 2026
b0b3e88
Use brighter color for `galah_green()` (#304)
mjwestgate Sep 4, 2026
70a4bdd
Minor test improvements
mjwestgate Sep 4, 2026
bb4666b
Use cli in startup message
daxkellie Sep 7, 2026
1a4a65e
Add `from` example to `galah_call()`
daxkellie Sep 7, 2026
28deb6d
add example to `authenticate()` docs
daxkellie Sep 7, 2026
a855883
Update docs on `all_fields`, remove from code
daxkellie Sep 8, 2026
8f8b462
Show values for lists with empty `properties` #300
daxkellie Sep 8, 2026
ea74811
Add complex string test #303
daxkellie Sep 8, 2026
3b05899
Remove `all_fields` from `show_values()` tests
daxkellie Sep 8, 2026
74b4436
Update NEWS with fixes
daxkellie Sep 8, 2026
41c8b79
reinstate `galah_call()` in place of `request_data()` in QSG
mjwestgate Sep 16, 2026
ebe4f26
render recent changes to help files
mjwestgate Sep 16, 2026
a091f0f
Fix bug preventing `.onLoad()` from working
mjwestgate Sep 16, 2026
814989a
Fix minor bugs in list unnesting
mjwestgate Sep 18, 2026
16272c5
Minor fixes to tests
mjwestgate Sep 18, 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 .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@
^data-raw/
^data-raw$
^cheatsheet/
^cheatsheet$
^cheatsheet$
^\.positai$
^\.claude$
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ docs/*
docs
SECRETS.txt
.secure-credentials
/TEST-SENSITIVE-DATA
/TEST-SENSITIVE-DATA
.positai
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: galah
Type: Package
Title: Biodiversity Data from the GBIF Node Network
Version: 2.2.0
Version: 2.3.0
Authors@R:
c(person(given = "Martin",
family = "Westgate",
Expand Down
5 changes: 5 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ S3method(compute,prequery)
S3method(compute,query)
S3method(compute,query_set)
S3method(count,data_request)
S3method(describe,data_request)
S3method(distinct,data_request)
S3method(filter,data_request)
S3method(filter,files_request)
Expand Down Expand Up @@ -80,6 +81,7 @@ export(collect_media)
export(compound)
export(compute)
export(count)
export(describe)
export(distinct)
export(filter)
export(galah_apply_profile)
Expand All @@ -94,6 +96,9 @@ export(galah_polygon)
export(galah_radius)
export(galah_select)
export(geolocate)
export(geolocate_bbox)
export(geolocate_polygon)
export(geolocate_radius)
export(glimpse)
export(group_by)
export(identify)
Expand Down
28 changes: 26 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
# galah 2.3.0

### New functions and options
* New function `describe()` to check what fields are available (#291).
* `authenticate()` gains arguments to allow in-pipe email- or JWT-based authentication. Support added for JWT-based authentication on VBP (#296).
* `request_data()` and friends gain a `from` argument, allowing in-pipe atlas specification (#297).
* New names for spatial functions: `geolocate_polygon()`, `geolocate_bbox()` and `geolocate_radius()`.
* Now possible to call `select()` on GBIF occurrence queries, though they are applied post-hoc.

### Bug fixes & performance improvements
* `isAuthoritative` and `isThreatened` returned by default by `search_all()` (#293).
* Calling functions using `pkg::fun()` syntax work without first calling `library(galah)` (#294, #298).
* `query_API()` now uses `cli::cli_progress_step()`, `httr2::req_retry()` and `httr::req_perform_parallel()` for improved performance. Timeout is now 60 seconds, rather than 20.
* Misc bug fixes for `atlas_occurrences()`, `glimpse()` and `show_values()` for GBIF (#299).
* Upgraded to v2 of specieslist API for ALA (#300).
* `galah` now auto-populates the `q` parameter for living atlas API calls for server-side performance reasons (#301).
* Added check that object has correct Coordinate Reference System when using `geolocate()` (#302)
* Improved query parsing for more complex text strings (#303)

### Lifecycle
* `galah_` prefix functions for piping formally superseded by their `dplyr` alternatives.
* Using `filter`, `select` etc as arguments to the `atlas_` family formally superseded in favor of piping.
* `all_fields` argument in `show_values()` used to return all columns in a specified list superseded to supplying all columns by default.

# galah 2.2.0

### Improved organisational support
Expand All @@ -12,7 +36,7 @@
* `dplyr::glimpse()` can be used to see what the resulting query will look like.
* New functions `capture()` and `compound()` as prequels to `collapse()` (#278).

## Changes to metadata functions
### Changes to metadata functions
* All metadata requests now accept `select()`.
* Metadata types that support `unnest()` now also support `filter()`, even when `unnest()` is not supplied.
* All `show_all()` and `search_all()` functions gain an `all_fields` argument.
Expand All @@ -27,7 +51,7 @@
* Move to `{cli}` for `print()` calls, not `cat()`.
* Reduce usage of `@importFrom` in favour of `pkg::fun()` syntax, as per R style guide.
* `basisOfRecord` now included as default field (i.e. with `select(group = "basic")`). (#281)
* `query` objects now have a `request` slot showing the request that generated them .
* `query` objects now have a `request` slot showing the request that generated them.


# galah 2.1.2
Expand Down
18 changes: 0 additions & 18 deletions R/galah_apply_profile.R → R/apply_profile.R
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,6 @@ apply_profile <- function(.data, ...){
apply_profile = result)
}

#' @rdname apply_profile
#' @export
galah_apply_profile <- function(...){
dots <- rlang::enquos(..., .ignore_empty = "all") |>
detect_request_object()
switch(class(dots[[1]])[1],
"data_request" = {
result <- parse_quosures_basic(dots[-1]) |>
parse_profile()
update_request_object(dots[[1]],
apply_profile = result)
},
{
parse_quosures_basic(dots) |>
parse_profile()
})
}

#' Internal parsing of `profile` args
#' @noRd
#' @keywords Internal
Expand Down
2 changes: 1 addition & 1 deletion R/atlas_counts.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#' @rdname atlas_
#' @order 2
#' @param group_by `tibble`: generated by a call to [galah_group_by()].
#' @param group_by `r lifecycle::badge("superseded")` `tibble`: generated by a call to [galah_group_by()].
#' @param limit `numeric`: maximum number of categories to return, defaulting to 100.
#' If limit is NULL, all results are returned. For some categories this will
#' take a while.
Expand Down
4 changes: 2 additions & 2 deletions R/atlas_distributions.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#' @param request optional `data_request` object: generated by a call to
#' [galah_call()].
#' @param identify `data.frame`: generated by a call to
#' [galah_identify()].
#' identify().
#' @param filter `data.frame`: generated by a call to
#' [galah_filter()]
#' filter()
#' @return An object of classes `sf`, `tbl`, `tbl_df` and `data.frame`
#' (aka a Simple feature collection) of distribution maps, with one column per
#' map, and spatial data stored in the `geometry` column.
Expand Down
39 changes: 23 additions & 16 deletions R/atlas_media.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,27 @@ atlas_media <- function(request = NULL,
apply_profile = NULL,
all_fields = FALSE
) {

# check media is available
media_supported()

# capture supplied arguments
args <- as.list(environment())
# convert to `data_request` object
.query <- check_atlas_inputs(args)
.query$type <- "occurrences" # default, but in case supplied otherwise

# check media is available
media_supported(atlas = .query$atlas)

# ensure a filter is present (somewhat redundant with `collapse`)
if(is.null(.query$filter)){
cli::cli_abort("You must specify a valid `filter()` to use `atlas_media()`")
}

# work out which fields are most available for this atlas
present_fields <- image_fields(atlas = .query$atlas)

# ensure media columns are present in `select`
if(is.null(.query$select)){
.query <- .query |>
dplyr::select(group = c("basic", "media"))
present_fields <- image_fields()
present_fields <- present_fields[present_fields != "multimedia"] # check these fields for Spain
query_collapse <- collapse(.query)
# if `select` is present, ensure that at least one 'media' field is requested
}else{
Expand All @@ -45,42 +45,49 @@ atlas_media <- function(request = NULL,
strsplit(split = ",") |>
purrr::pluck(!!!list(1))

# `multimedia` should be in `select`, but not `filter`
image_select <- image_fields()
image_select <- image_select[image_select != "multimedia"]

# abort if no fields are given to `select`
if(!any(selected_fields %in% image_select)){
if(!any(selected_fields %in% present_fields)){
selected_text <- glue::glue_collapse(selected_fields, sep = ", ")
c("No media fields requested by `select()`",
i = "try `galah_select({selected_text}, group = 'media')` instead") |>
cli::cli_abort()
}else{
present_fields <- selected_fields[selected_fields %in% image_select]
present_fields <- selected_fields[selected_fields %in% present_fields]
query_collapse <- x
}
} # end `select` checks

# add media content to filters
if(length(present_fields) > 0){
# do region-specific filter parsing
media_fq <- image_filters(present_fields)
media_fq <- image_filters(present_fields, atlas = .query$atlas)
# add back to source object
if(length(media_fq) > 1){
media_fq <- glue::glue("({glue::glue_collapse(media_fq, ' OR ')})")
}
url <- httr2::url_parse(query_collapse$url)
url$query$fq <- glue::glue("{url$query$fq}AND{media_fq}")
# NOTE: since v 2.3.0, we need to adapt to whether there are `q` or `fq filters`
if(is.null(url$query$q)){
url$query$fq <- media_fq
}else{
if(is.null(url$query$fq)){
url$query$fq <- media_fq
}else{
url$query$fq <- glue::glue("{url$query$fq}AND{media_fq}")
}
}
query_collapse$url <- httr2::url_build(url)
}

# get occurrences, expand to one row per media entry
occ <- query_collapse |>
collect(wait = TRUE) |>
build_media_id(media_fields = present_fields)
build_media_id(media_fields = present_fields[present_fields != "multimedia"])
# NOTE: `multimedia` field contains a description of which field has IDs
# _not_ IDs themselves; hence removal in above processing stage

# collect media metadata
media_query <- request_metadata() |>
media_query <- request_metadata(from = .query$atlas) |>
filter(media == dplyr::pull(occ, "media_id"))
if(isTRUE(all_fields)){
media_query <- media_query |>
Expand Down
12 changes: 6 additions & 6 deletions R/atlas_occurrences.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#'
#' * They have the ability to accept `filter`, `select` etc as arguments,
#' rather than within a pipe; but **only** when using the `galah_` forms of
#' those functions (e.g. [galah_filter()]).
#' those functions (see [superseded_functions]).
#' * `atlas_` functions do not require you to specify the `method` or `type`
#' arguments to [galah_call()], as they are more specific in what data are
#' being requested.
Expand All @@ -20,11 +20,11 @@
#' @order 1
#' @param request optional `data_request` object: generated by a call to
#' [galah_call()].
#' @param identify `tibble`: generated by a call to [galah_identify()].
#' @param filter `tibble`: generated by a call to [galah_filter()]
#' @param geolocate `string`: generated by a call to [galah_geolocate()]
#' @param apply_profile `string`: generated by a call to [galah_apply_profile()]
#' @param select `tibble`: generated by a call to [galah_select()]
#' @param identify `r lifecycle::badge("superseded")` `tibble`: generated by a call to [galah_identify()].
#' @param filter `r lifecycle::badge("superseded")` `tibble`: generated by a call to [galah_filter()]
#' @param geolocate `r lifecycle::badge("superseded")` `string`: generated by a call to [galah_geolocate()]
#' @param apply_profile `r lifecycle::badge("superseded")` `string`: generated by a call to [galah_apply_profile()]
#' @param select `r lifecycle::badge("superseded")` `tibble`: generated by a call to [galah_select()]
#' @param mint_doi `logical`: by default no DOI will be generated. Set to
#' `TRUE` if you intend to use the data in a publication or similar.
#' @param doi `string`: (Optional) DOI to download. If provided overrides
Expand Down
2 changes: 1 addition & 1 deletion R/atlas_species.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ atlas_species <- function(request = NULL,
check_distinct_for_atlas_species <- function(.query){
if(is.null(.query$distinct)){
.query |>
distinct(species_facets(), .keep_all = TRUE)
distinct(species_facets(.query), .keep_all = TRUE)
}else{
.query$distinct$keep_all <- TRUE
.query
Expand Down
6 changes: 3 additions & 3 deletions R/atlas_taxonomy.R
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ atlas_taxonomy <- function(request = NULL,
.query$type <- "taxonomy" # default, but in case supplied otherwise
check_identify(.query)
check_down_to(.query)
constrain_ids <- check_constraints(args = args,
constrain_ids <- check_constraints(.query,
call = as.list(sys.call()))

# extract required information from `identify`
Expand Down Expand Up @@ -58,11 +58,11 @@ atlas_taxonomy <- function(request = NULL,
#' Internal function to check whether constraints have been passed
#' @noRd
#' @keywords Internal
check_constraints <- function(args, call){
check_constraints <- function(.query, call){
if(any(names(call) == "constrain_ids")){ # i.e. if user specifies an argument
call$constrain_ids
}else{ # if NULL only occurs because no argument is set
if(potions::pour("atlas", "region") == "Australia"){
if(.query$atlas == "Australia"){
"biodiversity.org.au"
}
}
Expand Down
Loading
Loading