Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set up skeleton API package #1

Merged
merged 22 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
274f7c1
Add skeleton porcelain endpoint and deps
pratikunterwegs Jul 24, 2024
0f0868d
Add skeleton tests for {daedalus.api}
pratikunterwegs Jul 24, 2024
43cddd5
Add root JSON schema and WORDLIST
pratikunterwegs Jul 24, 2024
78af9b5
Update and add GHA workflows
pratikunterwegs Jul 24, 2024
ccddae7
Correct test code for num type and expressions
pratikunterwegs Jul 24, 2024
3d67ba4
Update `.lintr` with reduced linters and specific exclusions
pratikunterwegs Jul 24, 2024
3c5335d
Update or add pkg infrastructure files
pratikunterwegs Jul 24, 2024
57f6fa5
Update DESCRIPTION and .Rbuildignore, add _pkgdown.yml
pratikunterwegs Jul 24, 2024
00ea0aa
Add Dockerfile, Rprofile.site, and daedalus_api
pratikunterwegs Jul 24, 2024
bd29dac
Add Readmes
pratikunterwegs Jul 24, 2024
205230a
Update Dockerfile with {stringi} manual install, update to r-ver 4.4.1
pratikunterwegs Jul 25, 2024
b552bf6
Add docker build/push/test scripts
richfitz Jul 26, 2024
50434ac
Update instructions
richfitz Jul 26, 2024
0470324
Use namespace everywhere
richfitz Jul 26, 2024
4751929
Add badge
richfitz Jul 26, 2024
bf52d34
Fix branch name
richfitz Jul 26, 2024
47609d4
Install R pkgs from MRC-IDE R-universe
pratikunterwegs Jul 26, 2024
792b3e7
Ignore porcelain files via .gitattributes
pratikunterwegs Jul 26, 2024
9e12b17
Rm `uglify()` and `prepare_code()`
pratikunterwegs Jul 26, 2024
c967320
Update package doc, style porcelain.R
pratikunterwegs Jul 26, 2024
af7f830
Update {daedalus} remote to jameel-institute
pratikunterwegs Jul 26, 2024
9743dd6
Add Jameel R-universe to Dockerfile
pratikunterwegs Jul 26, 2024
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: 4 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@
^\.covrignore$
^\.github$
\.*gcov$
^codecov\.yml$
^.*\.Rproj$
^\.Rproj\.user$
^_pkgdown\.yml$
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
R/porcelain.R linguist-generated=true
5 changes: 5 additions & 0 deletions .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:

name: R-CMD-check

permissions: read-all

jobs:
R-CMD-check:
runs-on: ${{ matrix.config.os }}
Expand Down Expand Up @@ -47,3 +49,6 @@ jobs:
- uses: r-lib/actions/check-r-package@v2
with:
upload-snapshots: true
build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")'
# TODO: add error on NOTE once {daedalus} fns are used
# currently not added due to NOTE on {daedalus} import without use
52 changes: 52 additions & 0 deletions .github/workflows/lint-changed-files.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
workflow_dispatch:
pull_request:
branches: [main, master]
paths:
- '**.R'
- '**.Rmd'
- '**/.lintr'
- '**/.lintr.R'

name: lint-changed-files

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
lint-changed-files:
runs-on: ubuntu-latest
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4

- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true

- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: |
any::gh
any::lintr
any::purrr
any::cyclocomp
needs: check

- name: Install package
run: R CMD INSTALL .

- name: Extract and lint files changed by this PR
run: |
files <- gh::gh("/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files")
changed_files <- purrr::map_chr(files, "filename")
all_files <- list.files(recursive = TRUE)
exclusions_list <- as.list(setdiff(all_files, changed_files))
lintr::lint_package(exclusions = exclusions_list)
shell: Rscript {0}
env:
LINTR_ERROR_ON_LINT: true
17 changes: 14 additions & 3 deletions .github/workflows/test-coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:

name: test-coverage

permissions: read-all

jobs:
test-coverage:
runs-on: ubuntu-latest
Expand All @@ -24,23 +26,32 @@ jobs:

- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::covr
extra-packages: any::covr, any::xml2
needs: coverage

- name: Test coverage
run: |
covr::codecov(
cov <- covr::package_coverage(
quiet = FALSE,
clean = FALSE,
install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package")
)
covr::to_cobertura(cov)
shell: Rscript {0}

- uses: codecov/codecov-action@v4
with:
fail_ci_if_error: ${{ github.event_name != 'pull_request' && true || false }}
file: ./cobertura.xml
plugin: noop
disable_search: true
token: ${{ secrets.CODECOV_TOKEN }}

- name: Show testthat output
if: always()
run: |
## --------------------------------------------------------------------
find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \; || true
find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true
shell: bash

- name: Upload test results
Expand Down
59 changes: 59 additions & 0 deletions .github/workflows/update-citation-cff.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Workflow derived from https://github.com/r-lib/actions/tree/master/examples
# The action runs when:
# - The DESCRIPTION or inst/CITATION are modified
# - Can be run manually
# For customizing the triggers, visit https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows
on:
push:
branches:
- main
paths:
- DESCRIPTION
- inst/CITATION
- .github/workflows/update-citation-cff.yaml
workflow_dispatch:

name: Update CITATION.cff
permissions:
contents: write
pull-requests: write

jobs:
update-citation-cff:
runs-on: ubuntu-latest
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: r-lib/actions/setup-r@v2
- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: |
any::cffr
any::V8

- name: Update CITATION.cff
run: |

library(cffr)

# Customize with your own code
# See https://docs.ropensci.org/cffr/articles/cffr.html

# Write your own keys
mykeys <- list()

# Create your CITATION.cff file
cff_write(keys = mykeys)

shell: Rscript {0}
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
commit-message: Update `CITATION.cff`
title: Update `CITATION.cff`
body: |
This pull request updates the citation file, ensuring all authors are credited and there are no discrepancies.

Please verify the changes before merging.
branch: update-citation-cff
26 changes: 20 additions & 6 deletions .lintr
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
linters: linters_with_defaults(
object_length_linter = NULL,
object_usage_linter = NULL,
cyclocomp_linter = NULL
)
exclusions: list("tests/testthat.R", "R/cpp11.R")
linters: all_linters(
indentation_linter = NULL, # unstable as of lintr 3.1.0
extraction_operator_linter = NULL # allow R6 syntax from {porcelain}
)
exclusions: list(
"R/porcelain.R" = list(
object_name_linter = Inf # allow fn name `__porcelain__`
),
"tests/testthat.R" = list(
unused_import_linter = Inf,
undesirable_function_linter = Inf # allow library() calls
),
"tests/testthat/test-main.R" = list(
implicit_integer_linter = Inf # allow port notation without integer L
),
"vignettes" = list(
undesirable_function_linter = Inf
),
"R/cpp11.R"
)
34 changes: 25 additions & 9 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
Package: daedalus.api
Title: Package Title Here
Version: 0.1.0
Title: Serve the 'daedalus' model via an API
Version: 0.0.1
Authors@R: c(
person("First", "Last", , "email@example.com", role = c("aut", "cre")),
person("Pratik", "Gupte", , "p.gupte24@imperial.ac.uk", role = c("aut", "cre"),
comment = c(ORCID = "0000-0001-5294-7819")),
person("Imperial College of Science, Technology and Medicine", role = "cph")
)
Description: Description of the pacakge in more than one full sentence.
Description: API server for the 'daedalus' model, using 'porcelain' and
'plumber'.
License: MIT + file LICENSE
URL: https://github.com/j-idea/daedalus.api
BugReports: https://github.com/j-idea/daedalus.api/issues
Suggests:
URL: https://github.com/jameel-institute/daedalus.api
BugReports: https://github.com/jameel-institute/daedalus.api/issues
Imports:
daedalus,
docopt,
jsonlite,
lgr,
porcelain
Suggests:
httr,
mockery,
spelling,
testthat (>= 3.0.0)
Remotes:
jameel-institute/daedalus,
reside-ic/porcelain
Config/testthat/edition: 3
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.1.1
Language: en-GB
Roxygen: list(markdown = TRUE, roclets = c("rd", "namespace",
"porcelain::porcelain_roclet"))
RoxygenNote: 7.3.2
21 changes: 21 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# MIT License

Copyright (c) 2024 Imperial College of Science, Technology and Medicine

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
# Generated by roxygen2: do not edit by hand

export(api)
32 changes: 32 additions & 0 deletions R/api.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
##' Create an daedalus.api server, a porcelain object
##'
##' @title Create daedalus.api
##'
##' @param validate Logical, indicating if validation should be done
##' on responses. This should be `FALSE` in production
##' environments. See [porcelain::porcelain] for details
##'
##' @param log_level Logging level to use. Sensible options are "off",
##' "info" and "all".
##'
##' @return A [porcelain::porcelain] object. Notably this does *not*
##' start the server
##'
##' @export
api <- function(validate = NULL, log_level = "info") {
logger <- make_logger(log_level)
api <- porcelain::porcelain$new(validate = validate, logger = logger)
api$include_package_endpoints()
api
}

##' @porcelain GET / => json(root)
root <- function() {
versions <- c(
list(
daedalus = utils::packageVersion("daedalus"),
daedalus.api = utils::packageVersion("daedalus.api")
)
)
lapply(versions, function(v) scalar(as.character(v)))
}
6 changes: 6 additions & 0 deletions R/daedalus.api-package.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#' @keywords internal
"_PACKAGE"

## usethis namespace: start
## usethis namespace: end
NULL
9 changes: 9 additions & 0 deletions R/logging.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## See reside-266, might move this into porcelain
make_logger <- function(log_level) {
logger <- lgr::get_logger("daedalus.api", reset = TRUE)
logger$set_propagate(FALSE)
logger$set_threshold(log_level)
appender <- lgr::AppenderConsole$new(layout = lgr::LayoutJson$new())
logger$add_appender(appender, name = "json")
logger
}
21 changes: 21 additions & 0 deletions R/main.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
parse_main <- function(args = commandArgs(TRUE)) {
usage <- "Usage:
daedalus.api [options]

Options:
--log-level=LEVEL Log-level (off, info, all) [default: info]
--validate Enable json schema validation
--port=PORT Port to run api on [default: 8001]"
dat <- docopt::docopt(usage, args)
list(
log_level = dat$log_level,
validate = dat$validate,
port = as.integer(dat$port)
)
}


main <- function(args = commandArgs(TRUE)) {
dat <- parse_main(args)
api(dat$validate, dat$log_level)$run("0.0.0.0", port = dat$port)
}
12 changes: 12 additions & 0 deletions R/porcelain.R

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

8 changes: 6 additions & 2 deletions R/util.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
`%||%` <- function(x, y) { # nolint
if (is.null(x)) y else x
scalar <- function(x) {
jsonlite::unbox(x)
}

package_version_string <- function(name) {
as.character(utils::packageVersion(name))
}
Loading
Loading