package openlibrary import ( "context" "encoding/json" "fmt" "net/http" "time" ) const baseURL = "https://openlibrary.org" // Client is a client for the Open Library API. type Client struct { httpClient *http.Client } // NewClient creates a new Open Library client. func NewClient() *Client { return &Client{ httpClient: &http.Client{Timeout: 10 * time.Second}, } } // Author represents the data returned from the Open Library Authors API. type Author struct { Name string `json:"name"` PersonalName string `json:"personal_name"` Bio interface{} `json:"bio"` // Bio can be a string or a struct Wikipedia string `json:"wikipedia"` } // GetAuthor fetches author data from the Open Library API. // The olid is the Open Library Author ID (e.g., "OL23919A"). func (c *Client) GetAuthor(ctx context.Context, olid string) (*Author, error) { url := fmt.Sprintf("%s/authors/%s.json", baseURL, olid) req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { return nil, err } req.Header.Set("User-Agent", "TerculEnrichmentTool/1.0 (contact@tercul.com)") resp, err := c.httpClient.Do(req) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode) } var author Author if err := json.NewDecoder(resp.Body).Decode(&author); err != nil { return nil, err } return &author, nil }