⚠️ Nota (2026): Este post foi reescrito. A versão original usava o pacote rdrop2, que dependia da API v1 do Dropbox — descontinuada desde setembro de 2023. O conteúdo abaixo mostra a abordagem atual com httr2 + API v2. A versão original foi preservada em index-old.html neste mesmo bundle para consulta.
Armazenar arquivos na nuvem é prática comum, e o Dropbox é um dos serviços mais usados para isso. Saber interagir com esses arquivos por código é uma habilidade valiosa para quem trabalha com dados: automatizar o vai e vem de arquivos economiza tempo, elimina erro manual e permite integrar fontes de dados externas em pipelines reprodutíveis.
É parte do trabalho de ciência de dados integrar as fontes onde os dados moram. Neste post mostro como fazer isso usando o pacote httr2 diretamente com a API v2 do Dropbox — a única API ativa desde que a v1 foi encerrada. O código é um pouco mais verboso do que o rdrop2 de antigamente, mas é completamente independente de pacotes de terceiros específicos do Dropbox e segue um padrão aplicável a qualquer API REST.
TL;DR
- O pacote
rdrop2usava a API v1 do Dropbox, descontinuada em 2023 — não funciona mais.- A alternativa atual é
httr2com OAuth2 PKCE contra a API v2 do Dropbox.- Com menos de 50 linhas de código você autentica, lista, sobe, baixa e lê arquivos CSV diretamente no R.
- O token pode ser salvo em disco e reutilizado em sessões futuras sem nova autenticação interativa.
Por que o rdrop2 parou de funcionar?
O pacote rdrop2 foi durante anos a solução padrão para integrar Dropbox com R. O problema é que ele usava a API v1 do Dropbox, que foi oficialmente encerrada em setembro de 2023. Desde então, qualquer chamada feita por esse pacote retorna erro 400 ou 401. O pacote não foi atualizado para a v2, e não há perspectiva clara de que isso aconteça.
A boa notícia é que a API v2 do Dropbox é bem documentada, usa OAuth2 padrão e o httr2 — disponível no CRAN desde 2022 e mantido pela equipe do tidyverse — tem suporte nativo a esse fluxo de autenticação. A migração leva menos de uma hora.
Configuração inicial: criando o app no Dropbox
Antes de qualquer código, você precisa registrar um app no painel de desenvolvedores do Dropbox para obter as credenciais de acesso.
- Acesse dropbox.com/developers/apps e clique em Create app.
- Escolha Scoped access → Full Dropbox (ou App folder se preferir acesso restrito a uma pasta).
- Dê um nome ao seu app (ex.:
meu-r-dropbox). - Na aba Settings do app, copie o App key e o App secret.
- Em OAuth2 → Redirect URIs, adicione
http://localhost:1410/(porta padrão usada pelohttr2para o fluxo de código de autorização local). - Na aba Permissions, habilite ao menos:
files.content.read,files.content.write,files.metadata.read.
Com as credenciais em mãos, adicione-as ao seu .Renviron — nunca as coloque direto no código:
usethis::edit_r_environ()
# Adicione as linhas abaixo e salve:
# DROPBOX_APP_KEY=sua_chave_aqui
# DROPBOX_APP_SECRET=seu_segredo_aquiReinicie a sessão do R para que as variáveis sejam lidas.
Autenticação OAuth2 com httr2
O httr2 implementa o fluxo Authorization Code with PKCE, que é o recomendado pelo Dropbox para apps que rodam localmente. Na primeira execução, uma janela do navegador abre para você autorizar o app; o token retorna automaticamente para a sessão R.
library(httr2)
# Definindo o cliente OAuth2
dropbox_client <- oauth_client(
id = Sys.getenv("DROPBOX_APP_KEY"),
secret = Sys.getenv("DROPBOX_APP_SECRET"),
token_url = "https://api.dropboxapi.com/oauth2/token",
name = "dropbox-r-client"
)
# Autenticação interativa (abre o navegador uma única vez)
token <- oauth_flow_auth_code(
client = dropbox_client,
auth_url = "https://www.dropbox.com/oauth2/authorize",
pkce = TRUE
)Salvando e reutilizando o token
Para não precisar autorizar no navegador toda vez que iniciar uma sessão, salve o token em disco e carregue-o nas sessões seguintes:
# Salvar (faça isso uma vez após o oauth_flow_auth_code)
saveRDS(token, "~/.dropbox_token.rds")
# Carregar em sessões futuras
token <- readRDS("~/.dropbox_token.rds")Uma ressalva de segurança: esse arquivo .rds é uma credencial de acesso à sua conta. Adicione o caminho ao .gitignore e nunca o publique junto com o código.
Listando arquivos e pastas
O endpoint /2/files/list_folder retorna os itens de um diretório. Passamos a string vazia "" para listar a raiz:
list_dropbox <- function(path = "", token) {
request("https://api.dropboxapi.com/2/files/list_folder") |>
req_auth_bearer_token(token$access_token) |>
req_body_json(list(path = path)) |>
req_perform() |>
resp_body_json()
}
# Listar raiz
resultado <- list_dropbox("", token)
# Ver apenas os nomes
sapply(resultado$entries, `[[`, "name")
# Filtrar só pastas
entries <- resultado$entries
pastas <- Filter(function(e) e[[".tag"]] == "folder", entries)
sapply(pastas, `[[`, "name")Fazendo upload de um arquivo
O upload usa o endpoint de conteúdo (content.dropboxapi.com) e envia o arquivo como bytes brutos no corpo da requisição. Os metadados (caminho de destino, modo de conflito) vão no cabeçalho Dropbox-API-Arg como JSON:
upload_dropbox <- function(local_path, dropbox_path, token) {
request("https://content.dropboxapi.com/2/files/upload") |>
req_auth_bearer_token(token$access_token) |>
req_headers(
`Dropbox-API-Arg` = jsonlite::toJSON(
list(path = dropbox_path, mode = "overwrite", autorename = FALSE),
auto_unbox = TRUE
),
`Content-Type` = "application/octet-stream"
) |>
req_body_raw(readBin(local_path, raw(), file.info(local_path)$size)) |>
req_perform()
}
# Exemplo: enviar o dataset trees
write.csv(trees, "trees.csv")
upload_dropbox("trees.csv", "/trees.csv", token)Fazendo download de um arquivo
O download segue a mesma lógica: o caminho do arquivo no Dropbox vai no cabeçalho Dropbox-API-Arg e o corpo da resposta contém os bytes do arquivo:
download_dropbox <- function(dropbox_path, local_path, token) {
request("https://content.dropboxapi.com/2/files/download") |>
req_auth_bearer_token(token$access_token) |>
req_headers(
`Dropbox-API-Arg` = jsonlite::toJSON(
list(path = dropbox_path),
auto_unbox = TRUE
)
) |>
req_perform() |>
resp_body_raw() |>
writeBin(local_path)
}
# Exemplo: baixar trees.csv do Dropbox
download_dropbox("/trees.csv", "trees_local.csv", token)Lendo um CSV direto do Dropbox para o R
Uma das operações mais úteis em pipelines de dados é ler um arquivo da nuvem sem precisar salvá-lo em disco. A função abaixo faz o download como texto e passa direto para read.csv() via textConnection():
read_csv_dropbox <- function(dropbox_path, token) {
raw_text <- request("https://content.dropboxapi.com/2/files/download") |>
req_auth_bearer_token(token$access_token) |>
req_headers(
`Dropbox-API-Arg` = jsonlite::toJSON(
list(path = dropbox_path),
auto_unbox = TRUE
)
) |>
req_perform() |>
resp_body_string()
read.csv(textConnection(raw_text))
}
# Exemplo: ler trees.csv direto do Dropbox
new_trees <- read_csv_dropbox("/trees.csv", token)
head(new_trees)Se o seu arquivo usa separadores ou codificações específicas, você pode passar os mesmos argumentos extras que passaria para read.csv() — por exemplo sep = ";" ou encoding = "latin1".
Comparação com o rdrop2 (abordagem antiga)
A tabela abaixo mostra lado a lado a sintaxe do rdrop2 e a equivalente com httr2 + API v2, para as operações mais comuns:
| Operação | rdrop2 (API v1 — descontinuada) | httr2 + API v2 (atual) |
|---|---|---|
| Autenticação | drop_auth() | oauth_flow_auth_code(client, auth_url, pkce = TRUE) |
| Salvar token | saveRDS(token, "token.rds") | saveRDS(token, "~/.dropbox_token.rds") |
| Listar arquivos | drop_dir() | list_dropbox("", token) (função customizada) |
| Upload | drop_upload("trees.csv") | upload_dropbox("trees.csv", "/trees.csv", token) |
| Download | drop_download("trees.csv") | download_dropbox("/trees.csv", "local.csv", token) |
| Ler CSV direto | drop_read_csv("trees.csv") | read_csv_dropbox("/trees.csv", token) |
A principal diferença prática é que com httr2 você escreve funções wrapper explícitas, mas em compensação não depende de um pacote específico que pode ficar desatualizado. Uma vez que você entende o padrão de request() |> req_* |> req_perform() |> resp_*(), ele se aplica a qualquer API REST — não só ao Dropbox.
Perguntas frequentes
Preciso autenticar toda vez que uso o httr2 com o Dropbox?
Não. Você autentica uma vez com oauth_flow_auth_code(), salva o token com saveRDS() e reusa nas próximas sessões carregando esse arquivo com readRDS(). Lembre de tratar o token como uma credencial: nunca o versione no Git nem o publique junto com o código. Se o token expirar (tokens offline do Dropbox são de longa duração, mas podem ser revogados), basta repetir o fluxo de autenticação.
Dá para ler um arquivo do Dropbox sem salvar em disco?
Sim. A função read_csv_dropbox() apresentada neste post baixa o conteúdo como texto e passa direto para read.csv() via textConnection(), sem criar nenhum arquivo temporário explicitamente. Isso é especialmente útil em pipelines automatizados onde você não quer gerenciar arquivos intermediários.
O httr2 suporta arquivos grandes no upload?
Para arquivos pequenos e médios, req_body_raw() funciona bem. Para arquivos maiores que 150 MB o Dropbox recomenda o endpoint de upload session (/2/files/upload_session/start, /2/files/upload_session/append_v2, /2/files/upload_session/finish), que divide o envio em partes. O httr2 suporta isso com múltiplas chamadas — o padrão é o mesmo, apenas com mais requisições encadeadas.








