# `Magpie`
[🔗](https://github.com/alexcassol/magpie/blob/v0.3.1/lib/magpie.ex#L1)

Core HTTP layer for the Dropbox API v2.

Builds authenticated `Req` requests and normalizes responses. RPC-style
endpoints go through `post/3`, while content endpoints (file bytes) go
through `upload_request/5` and `download_request/5`.

Requests are authenticated by the client's `Magpie.Auth.TokenProvider`: a
request step asks it for an access token, and when Dropbox answers `401
expired_access_token` a response step refreshes the token and replays the
request once.

The Dropbox endpoints can be overridden (rarely needed) via:

    config :magpie,
      base_url: "https://api.dropboxapi.com/2",
      upload_url: "https://content.dropboxapi.com/2/",
      oauth_authorize_url: "https://www.dropbox.com/oauth2/authorize",
      oauth_token_url: "https://api.dropboxapi.com/oauth2/token"

Extra options merged into every request (e.g. `plug: {Req.Test, Magpie}`
for testing) can be set with `config :magpie, req_options: [...]`.

# `response`

```elixir
@type response() :: {:ok, term()} | {:error, Magpie.Error.t()}
```

# `response_download`

```elixir
@type response_download() ::
  {:ok, %{body: binary(), headers: list() | map()}} | {:error, Magpie.Error.t()}
```

# `base_url`

Base URL for RPC endpoints.

# `download_request`

# `download_response`

```elixir
@spec download_response(Req.Response.t()) :: response_download()
```

# `new_req`

# `oauth_authorize_url`

URL where users authorize the app (OAuth 2 authorization endpoint).

# `oauth_token_url`

OAuth 2 token endpoint — note it lives outside the `/2` base URL.

# `post`

```elixir
@spec post(struct(), binary(), term()) :: response()
```

Send an RPC request to a Dropbox endpoint, JSON-encoding `body` when given.

# `post_request`

# `post_url`

```elixir
@spec post_url(struct(), binary(), binary(), term()) :: response()
```

Same as `post/3` but against an explicit base URL (used by content endpoints
that speak JSON, such as `/files/get_thumbnail_batch`).

# `process_response`

```elixir
@spec process_response(Req.Response.t()) :: response()
```

# `upload_data_request`

Upload `data` (iodata or enumerable) as the raw request body.
Used by content endpoints that take bytes directly instead of a local file.

# `upload_request`

Upload the file at local path `file` as the raw request body.
The file is streamed, so large files are not loaded into memory at once.

# `upload_url`

Base URL for content (upload/download) endpoints.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
