# `Astro.Ephemeris.Downloader`
[🔗](https://github.com/kipcole9/astro/blob/v2.5.0/lib/astro/ephemeris/downloader.ex#L1)

Downloads JPL DE-series SPK binary ephemeris files from NASA NAIF.

A compact ephemeris covering 1900–2100 is bundled with the library
(see `Astro.Ephemeris.Subset`), so no download is required for dates
in that range.

Downloading is needed only to obtain the full `de440s.bsp` kernel
(~32 MB), which extends coverage to 1849–2150. When present it takes
precedence over the bundled ephemeris. It can be fetched with
`mix astro.download_ephemeris`, and is otherwise downloaded on demand
at application start and cached on disk for subsequent runs.

### Cache location

By default the file is cached under the user cache directory as
resolved by `:filename.basedir(:user_cache, "astro")`. If that
directory cannot be created (for example, the OS user has no
writable home directory — a common situation for service accounts
in containers), Astro falls back to `<System.tmp_dir!()>/astro` and
logs a warning. The cache location can be overridden by setting
the `:ephemeris` application environment key:

    config :astro,
      ephemeris: "/path/to/de440s.bsp"

When the configured path already contains a valid ephemeris file no
download is performed. Setting an explicit path is the recommended
approach for production deployments, since the user-cache fallback
to `tmp` is ephemeral.

### Source URL

The default download source is the NASA NAIF generic kernels archive:

    https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/de440s.bsp

This can be overridden by setting the `:ephemeris_url` application
environment key (for example, when mirroring the file inside an
air-gapped environment).

# `download`

```elixir
@spec download(String.t()) :: {:ok, String.t()} | {:error, term()}
```

Downloads the ephemeris file to `path`.

The destination directory is created if it does not already exist.
On HTTP error or network failure the partial file (if any) is removed.

### Arguments

* `path` is the destination file path.

### Returns

* `{:ok, path}` on success.

* `{:error, reason}` if the download failed. `reason` is a tuple
  describing the failure, e.g. `{:http_status, 404}`,
  `{:cache_dir_unwritable, dir, posix_reason}`, or an `:httpc`
  error term.

# `ensure_ephemeris`

```elixir
@spec ensure_ephemeris(String.t()) :: {:ok, String.t()} | {:error, term()}
```

Ensures the ephemeris file is available on disk, downloading it if necessary.

### Arguments

* `path` is the destination file path.

### Returns

* `{:ok, path}` if the file already exists or was downloaded successfully.

* `{:error, reason}` if the file is missing and the download failed.

# `ephemeris_path`

```elixir
@spec ephemeris_path() :: String.t()
```

Returns the resolved ephemeris file path.

Resolution order:

* The `:ephemeris` application environment key, if set.

* `priv/de440s.bsp` — the full JPL kernel, if it has been downloaded
  (used during library development and when running from a checkout,
  and by anyone wanting coverage beyond the bundled span).

* `priv/de440s-astro.bsp` — the compact ephemeris bundled with the
  library, covering 1900–2100. Present in every hex install, so no
  download is required for dates in that span.

* The user cache directory as resolved by
  `:filename.basedir(:user_cache, "astro")`.

* `<System.tmp_dir!()>/astro` if the user cache directory cannot
  be created.

### Returns

* A binary path string.

---

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