// Package tmdb provides a client for The Movie Database (TMDB) API. // // This package offers a clean interface for interacting with TMDB's REST API, // including automatic rate limiting, retry logic, and convenient URL building utilities. // // # Getting Started // // First, create an API connection using your TMDB API token: // // api, err := tmdb.NewAPIConnection() // if err != nil { // log.Fatal(err) // } // // The token is read from the TMDB_TOKEN environment variable. // // # Making Requests // // The package provides clean URL building functions to construct API requests: // // // Simple endpoint // url := tmdb.requestURL("movie", "550") // // Result: "https://api.themoviedb.org/3/movie/550" // // // With query parameters // url := tmdb.buildURL([]string{"search", "movie"}, map[string]string{ // "query": "Inception", // "page": "1", // }) // // Result: "https://api.themoviedb.org/3/search/movie?language=en-US&page=1&query=Inception" // // All requests made with buildURL automatically include "language=en-US" by default. // // # Rate Limiting // // TMDB has rate limits around 40 requests per second. This package implements // automatic retry logic with exponential backoff: // // - Initial backoff: 1 second // - Exponential growth: 1s → 2s → 4s → 8s → 16s → 32s (max) // - Maximum retries: 3 attempts // - Respects Retry-After header when provided by the API // // Example of rate-limited request: // // data, err := api.get(url) // if err != nil { // // Will return error only after exhausting all retries // log.Printf("Request failed: %v", err) // } // // # Searching for Movies // // Search for movies by title: // // results, err := tmdb.SearchMovies(token, "Fight Club", false, 1) // if err != nil { // log.Fatal(err) // } // // for _, movie := range results.Results { // fmt.Printf("%s %s\n", movie.Title, movie.ReleaseYear()) // fmt.Printf("Poster: %s\n", movie.GetPoster(&api.Image, "w500")) // } // // # Getting Movie Details // // Fetch detailed information about a specific movie: // // movie, err := tmdb.GetMovie(550, token) // if err != nil { // log.Fatal(err) // } // // fmt.Printf("Title: %s\n", movie.Title) // fmt.Printf("Overview: %s\n", movie.Overview) // fmt.Printf("Release Date: %s\n", movie.ReleaseDate) // fmt.Printf("IMDb ID: %s\n", movie.IMDbID) // // # Getting Credits // // Retrieve cast and crew information: // // credits, err := tmdb.GetCredits(550, token) // if err != nil { // log.Fatal(err) // } // // fmt.Println("Cast:") // for _, actor := range credits.Cast { // fmt.Printf(" %s as %s\n", actor.Name, actor.Character) // } // // fmt.Println("\nCrew:") // for _, member := range credits.Crew { // if member.Job == "Director" { // fmt.Printf(" Director: %s\n", member.Name) // } // } // // # Image URLs // // The API configuration includes base URLs for images. Use helper methods to // construct full image URLs: // // posterURL := movie.GetPoster(&api.Image, "w500") // // Available sizes: "w92", "w154", "w185", "w342", "w500", "w780", "original" // // # Error Handling // // The package returns wrapped errors for easy debugging: // // data, err := api.get(url) // if err != nil { // if strings.Contains(err.Error(), "rate limit exceeded") { // // Handle rate limiting // } else if strings.Contains(err.Error(), "unexpected status code") { // // Handle HTTP errors // } else { // // Handle network errors // } // } // // Common error scenarios: // - "rate limit exceeded: maximum retries reached" - All retry attempts exhausted // - "unexpected status code: 401" - Invalid API token // - "unexpected status code: 404" - Resource not found // - Network errors for connectivity issues // // # Environment Variables // // The package uses the following environment variable: // // - TMDB_TOKEN: Your TMDB API access token (required) // // Obtain an API token from: https://www.themoviedb.org/settings/api // // # Best Practices // // 1. Reuse the API connection instead of creating new ones for each request // 2. Use buildURL for consistency and automatic language parameter injection // 3. Handle rate limit errors gracefully - they indicate temporary service issues // 4. Cache API responses when appropriate to reduce API calls // 5. Use specific image sizes instead of "original" to save bandwidth // // # API Documentation // // For complete TMDB API documentation, visit: // https://developer.themoviedb.org/docs // // # Rate Limiting Details // // From TMDB's documentation: // "While our legacy rate limits have been disabled for some time, we do still // have some upper limits to help mitigate needlessly high bulk scraping. They // sit somewhere in the 40 requests per second range." // // This package automatically handles rate limiting with exponential backoff to // ensure respectful API usage. package tmdb