Best Practices for Roxygen Imports/Depends?
Asked Answered
K

1

7

I'm writing a small convenience package for accessing a private API, and am using httr functions to conduct the requests. I'm also using Roxygen to handle documentation, etc. I'm importing httr functions as such:

#' Get a page of data from the specified endpoint.
#' @keywords internal
#' @importFrom httr GET
#'
get_data <- function(url, headers, page_number) {
  # Add querystring for page
  url_with_page <- paste0(url, "?page=", page_number)
  message("Downloading: ", url_with_page)
  # Get API response
  response <- GET(url_with_page, headers)
  return(response)
}

However, when you try to run the package with no pre-loaded packages, I get namespace errors:

Error in get_data(url, headers, 1) : 
  could not find function "GET"

I typically defer to Hadley's expertise on this sort of thing, but is this a good case for using the Depends field as well as/rather than Imports?

Edit: my NAMESPACE generated by Roxygen.

# Generated by roxygen2 (4.1.1): do not edit by hand

export(get_export)
export(get_exports)
export(get_metadata)
importFrom(httr,GET)
importFrom(httr,add_headers)
importFrom(httr,content)
importFrom(jsonlite,fromJSON)
importFrom(jsonlite,rbind.pages)

Edit: my DESCRIPTION file.

Package: APIpack
Type: Package
Title: APIpack
Version: 0.1
Date: 2016-01-04
Authors: "Matt Policastro"
Description: This package provides a set of convenience functions.
License: Proprietary
LazyData: TRUE
Imports: httr,
    jsonlite
Suggests: testthat
Knotted answered 1/2, 2016 at 17:12 Comment(13)
Does your NAMESPACE file have importFrom(httr, GET)?Zigmund
The only case to use Depends instead of Imports is if you think your end-user probably wants to use the httr functions directly whenever they load your package.Trapezius
I feel like @depends and @importFrom x belong in the package documentation moreso than the function definition. Also should be noted the importFrom will only work if you call the package directly, not if you call the package through a dependency.Hendel
Occasionally I add an @importFrom directive in the function docs but forget to have roxygen rebuild the NAMESPACE file.Beauchamp
Just added my NAMESPACE file; the directives you've mentioned seem to be present, but I'm still getting the error. @BrandonBertelsen, would this impact an internal function as I indicated above?Knotted
Doesn't the DESCRIPTION file also require the package to be listed in the Imports: section?Tango
@Tango Just added my DESCRIPTION file.Knotted
If you're using RStudio, I often find that I've forgotten to check "Build & Reload" in Project Options > Build Tools > Configure...Hendel
So, if you're using a script where you call library(APIpack) directly (rather than a dependency from another package) it should work as expected. But, the importFrom should be in your description file, this is why I suggested that you put it in the package documentation instead of the function.Hendel
It's irrelevant whether @importFrom is placed in the documentation of a function or in the package documentation. roxygen will collect all the @importFrom and @import roclets it can find and add the corresponding lines to the NAMESPACE file. It will also make sure that no line is repeated (even if the same @importFrom appears in multiple places).Bandog
@Tango Yes, it should be under DESCRIPTION Imports as well, but that is irrelevant in this case. The only time the list of packages in DESCRIPTION Imports is used is when the package is installed to make sure that the packages needed for Importing are also installed. Here, OP is testing out the package on his own machine, so it seems safe to assume that httr is installed.Trapezius
Not to be a wet blanket, but given the DESCRIPTION and NAMESPACE I provided, is there anything I should do other than just include my depends in DESCRIPTION's "Depends"? Because that appears to be the only way I can get the packages to load properly (possibly a bug?). Or, as @BrandonBertelsen suggests, should I be explicitly loading the library from within my function definition.Knotted
This answer has some helpful infromation and tipsKoralie
P
0

When using functions from an external package, it is good practice to explicitly note the package in the function call. In this case, this amounts to calling GET from the httr package using httr::GET.

In other words, try

response <- httr::GET(url_with_page, headers)

instead of

response <- GET(url_with_page, headers)
Plossl answered 14/8 at 14:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.