# ExDisco
An Elixir client library for the [Discogs API](https://www.discogs.com/developers/).
Discogs is the largest crowdsourced music database in the world. ExDisco provides a type-safe, ergonomic interface for querying artists, releases, labels, and user profiles, with support for both personal token authentication and full OAuth 1.0a flows.
## Features
- **Resource APIs** — Query artists, releases, labels, and user profiles
- **Global Search** — Search across releases, artists, labels, and masters
- **Type-Safe** — All API responses mapped to Elixir structs with proper typing
- **Flexible Authentication** — Token-based auth for personal use or OAuth 1.0a for multi-user apps
- **Pagination Support** — Built-in pagination for large result sets
- **Error Handling** — Typed error handling with clear error information
## Installation
Add `ex_disco` to your dependencies in `mix.exs`:
```elixir
def deps do
[
{:ex_disco, "~> 0.1.0"}
]
end
```
## Configuration
ExDisco requires a user agent to identify your application:
```elixir
config :ex_disco, ExDisco,
user_agent: "my_app/1.0.0 (+https://github.com/me/my_app)"
```
### Authentication
Choose one of two authentication methods:
**Personal Token** — For personal scripts and CLIs:
```elixir
config :ex_disco, ExDisco,
user_token: "your_personal_token"
```
Get a token at https://www.discogs.com/settings/developers
**OAuth 1.0a** — For apps acting on behalf of multiple users:
```elixir
config :ex_disco, ExDisco,
consumer_key: "your_consumer_key",
consumer_secret: "your_consumer_secret"
```
Register your app at https://www.discogs.com/settings/developers
## Quick Start
Fetch an artist by ID:
```elixir
{:ok, %ExDisco.Artists.Artist{} = artist} = ExDisco.Artists.get(1)
```
Fetch a release:
```elixir
{:ok, %ExDisco.Releases.Release{} = release} = ExDisco.Releases.get(249504)
```
Search for music:
```elixir
{:ok, results} = ExDisco.Search.query(q: "Thriller", type: :release)
IO.inspect(results.items |> Enum.count())
# 42
```
Handle errors:
```elixir
case ExDisco.Artists.get(999999999) do
{:ok, artist} -> "Found: #{artist.name}"
{:error, error} -> "Not found: #{error.message}"
end
# "Not found: 404 Not Found"
```
## Documentation
Full API documentation is available at [HexDocs](https://hexdocs.pm/ex_disco).
The documentation is integrated into the code itself via module and function documentation. Start with the modules in this order:
1. **`ExDisco.Artists`** — Query artist information
2. **`ExDisco.Releases`** — Query release data
3. **`ExDisco.Labels`** — Query label information
4. **`ExDisco.Search`** — Global search across all resources
5. **`ExDisco.Users`** — Query user profiles (requires authentication)
6. **`ExDisco.Auth`** — Full OAuth 1.0a authentication flow
7. **`ExDisco.Request`** — Low-level request builder and execution
## Examples
### Fetch artist with releases
```elixir
with {:ok, artist} <- ExDisco.Artists.get(1),
{:ok, releases} <- ExDisco.Artists.get_releases(1) do
IO.inspect("#{artist.name} has #{Enum.count(releases)} releases")
end
```
### Search with filters
```elixir
{:ok, results} = ExDisco.Search.query(q: "daft punk", type: :artist, per_page: 5)
results.items
|> Enum.each(&IO.inspect(&1.title))
```
### Get release with stats
```elixir
with {:ok, release} <- ExDisco.Releases.get(249504),
{:ok, stats} <- ExDisco.Releases.get_stats(249504) do
IO.inspect("Rating: #{stats.rating.average}/5")
end
```
## Contributing
Contributions are welcome! Please submit a pull request or open an issue on [GitHub](https://github.com/bo1ta/ex_disco).
## License
MIT — see LICENSE for details