Аутентифицируйся на Github через Travis-CI, используя httr, а также локально (локально работает, удаленно нет) - PullRequest
7 голосов
/ 07 января 2020

У меня есть файл Rmd, который использует httr для доступа к Github-API. Локально, я могу пройти аутентификацию с помощью Github, если я выполню следующее в консоли R перед рендерингом Rmd:

myapp <- oauth_app("APP", key = "xyz", secret = "pqr")
github_token <- oauth2.0_token(oauth_endpoints("github"), myapp)

Ключ и секрет были созданы в Github и существуют в моей рабочей области. когда я выполняю рендеринг, получается github_token, и я могу получить доступ к Github-API, не превышая ограничения доступа при локальном рендеринге.

Теперь тот же Rmd также автоматически создается в Travis-CI и затем развернут на gh-pages, когда я пу sh мастер ветвь. У меня есть эта рабочая без аутентификации, но она ограничивает мой лимит запросов к Githhub-API до 60 в час, и мне нужен более высокий лимит, который можно получить при аутентификации. Поэтому для этого у меня есть персональный токен доступа (PAT), также настроенный в Github; на странице, на которой установлен PAT, написано: «Персональные токены доступа работают как обычные токены доступа OAuth. Их можно использовать вместо пароля для Git через HTTPS или для аутентификации в API через Basi c Authentication» .

Вот часть моего Rmd, где я пытаюсь определить, является ли рендеринг локальным или удаленным, и получить соответствующий токен. Однако, когда это выполняется в Travis-CI, токен не распознается, поэтому я не думаю, что использую его правильно.

# Figure out the build location, and get the needed token
at_home <- FALSE
at_TCI <- FALSE
token_found <- FALSE
token_OK <- FALSE # not used now/yet

# Check to see if we are at TRAVIS-CI
# This next variable is in the Travis build environment & is a character string
token_value <- Sys.getenv("TRAVIS_CI") 
if (token_value != "") {
  token_found <- TRUE
  at_TCI <- TRUE
}

# Check to see if we are on the local/home machine
# This token is generated interactively via "Web Application Flow",
# and is deposited in the local workspace
# See developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/#web-application-flow
# This token has classes 'Token2.0', 'Token', 'R6' <Token2.0>
if (!at_TCI) {
  token_found <- exists("github_token")
  if (token_found) {
    token_value <- github_token
    at_home <- TRUE
  }
}

# See where we stand and act accordingly
if (!token_found) {
  message("Could not retrieve token - GET calls will be rate-limited by Github")
  # TEMPORARY: just use a few lines for faster testing & not blasting GH limits
  DF <- DF[1:5,]
}
if (token_found) {
  set_config(config(token = token_value)) # applies to all GET requests below
}

Я не думаю, что set_config вызов работает правильно, когда я нахожусь в Travis-CI, потому что я получаю ошибку, которая, кажется, приходит от вызова GET, который происходит позже (действительно трудно устранить неполадки на T-CI, но Rmd работает хорошо локально). Вот пример GET вызова, который завершается неудачно после запуска приведенного выше фрагмента, но работает локально:

repoOK[i] <- identical(status_code(GET(DF$repo[i])), 200L)

, где DF$repo[i] - это URL.

Я новичок в httr и Github-API, но я провел много времени, экспериментируя с заклинаниями, найденными здесь на SO, и с документацией Github, но пока что безуспешно с удаленной сборкой. Поэтому я призываю милости сообщества SO!

РЕДАКТИРОВАТЬ: GH репо с полным кодом.

РЕДАКТИРОВАТЬ 2: Никто не ответил в течение периода щедрости (!). Так что я буду работать над основной веткой. Эта ветка имеет код, который работает локально, но не работает в Travis-CI. Кроме того, в этой ветке устранено все Python, чтобы избежать других проблем и сохранить вещи в чистоте. Эта ветка выдает следующую ошибку на Travis-CI:

Ошибка в getGHdates (DF $ repo [i], "commitits"): превышена скорость доступа к Github, повторите попытку позже

1 Ответ

1 голос
/ 23 января 2020

Ответ, как представляется, заключается в том, что при локальной работе нельзя использовать тот же метод аутентификации, который необходим для удаленного использования в Travis-CI. Для правильной визуализации Rmd в обоих местах мне пришлось написать более сложный код, чем я надеялся. В частности, для локальной работы достаточно пройти аутентификацию следующим образом.

Сначала при запуске консоли R (как указано выше);

myapp <- oauth_app("APP", key = "xyz", secret = "pqr")
github_token <- oauth2.0_token(oauth_endpoints("github"), myapp)

Затем в коде Rmd необходимо:

# Figure out the build location, and get the needed token
at_home <- FALSE
at_TCI <- FALSE
token_found <- FALSE
where <- NULL

# Check to see if we are at TRAVIS-CI
# This token has class character
token_value <- Sys.getenv("TRAVIS_CI")
if (token_value != "") {
  token_found <- TRUE
  at_TCI <- TRUE
}

# Check to see if we are on the local/home machine
# This token is generated interactively via "Web Application Flow",
# and is deposited in the local workspace with the name github_token before rendering
# See developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/#web-application-flow
# This token has classes 'Token2.0', 'Token', 'R6' <Token2.0>
if (!at_TCI) {
  token_found <- exists("github_token")
  if (token_found) {
    token_value <- github_token
    at_home <- TRUE
  }
}

# See where we stand and act accordingly
if (!token_found) {
  message("Could not retrieve token - GET calls will be rate-limited by Github")
  # TEMPORARY: just use a few lines for faster testing & not blasting GH limits
  DF <- DF[1:5,]
}
if (token_found) {
  if (at_home) set_config(config(token = token_value))
  # This is sufficient for at_home and the GET calls elsewhere have a simple form
  if (at_home) where <- "home"
  if (at_TCI) where <- "TCI"
}

if (is.null(where)) stop("I'm lost")

# Report for troubleshooting
# cat("at_home = ", at_home, "\n")
# cat("at_TCI = ", at_TCI, "\n")
# cat("token_found = ", token_found, "\n")

При таком расположении вызовы API Github с использованием GET работают нормально.

Однако при удаленной работе в Travis-CI этот подход не работает. Для этого случая нужно сделать что-то вроде этого:

for (i in 1:ne) {
  if (!is.na(DF$web[i])) {
    if (at_home) access_string <- DF$web[i]
    if (at_TCI) {
      GH <- grepl("github\\.com", DF$web[i])
      if (!GH) access_string <- DF$web[i] # local access
      if (GH) access_string <- paste0(DF$web[i], "?access_token=",
        token_value) # remote access from Travis-CI
    }
    webOK[i] <- identical(status_code(GET(access_string)), 200L)
    webLink[i] <- TRUE
    if (webLink[i] != webOK[i]) badWeb[i] <- TRUE
  }
}

Я нашел совет вставить токен в GET вызов здесь .

Если вы читали это далеко, удачи в вашем собственном проекте! Полный код в этом GH репо .

...