package eia import ( "context" "fmt" "net/url" "slices" "time" "github.com/deepmap/oapi-codegen/pkg/securityprovider" "github.com/rs/zerolog" eiaapi "gitea.libretechconsulting.com/50W/eia-api-go/api" ) const ( defaultBaseURL = "https://api.eia.gov" defaultPingTimeout = 10 * time.Second defaultLogLevel = zerolog.DebugLevel ) // Simple wrapper around generated EIA API client // that embeds a client with a bearer auth interceptor // and optional logging middleware // // Performs a basic availability check against the API // when creating a new client, and exposes a Ping() method // for health / readiness probes type Client struct { ctx context.Context apiKey string healthCheckTimeout time.Duration *eiaapi.Client *eiaapi.ClientWithResponses } type ClientOpts struct { Context context.Context // Base context for requests APIKey string // API Key [EIA Opendata API v2](https://www.eia.gov/opendata/index.php) Logger *zerolog.Logger // Optional logger, if set is injected into logging middleware LogLevel *zerolog.Level // Optional log level, default is zerolog.DebugLevel BaseURL *url.URL // Optional, default is https://api.eia.gov HealthCheckTimeout *time.Duration // Timeout for Ping() function, default is 10s } type Facet struct { Name string Data interface{} } func NewFacets(facets ...*Facet) *eiaapi.Facets { newFacets := make(map[string]interface{}, len(facets)) for _, f := range facets { for i := 0; ; i++ { if _, set := newFacets[fmt.Sprintf("facets[%s][%d]", f.Name, i)]; set { continue } newFacets[fmt.Sprintf("facets[%s][%d]", f.Name, i)] = f.Data break } } return &newFacets } func NewClient(opts *ClientOpts) (*Client, error) { baseURL := defaultBaseURL if opts.BaseURL != nil { baseURL = opts.BaseURL.String() } hcTimeout := defaultPingTimeout if opts.HealthCheckTimeout != nil && *opts.HealthCheckTimeout > time.Duration(0) { hcTimeout = *opts.HealthCheckTimeout } middlewares := make([]eiaapi.ClientOption, 0, 2) // Injects Authorization: Bearer header into // outbound API calls // basicAuth, err := securityprovider.NewSecurityProviderBearerToken(opts.APIKey) // if err != nil { // return nil, err // } // middlewares = append(middlewares, eiaapi.WithRequestEditorFn(basicAuth.Intercept)) // Injects API key as query parameter: ?api_key= paramAuth, err := securityprovider.NewSecurityProviderApiKey("query", "api_key", opts.APIKey) if err != nil { return nil, err } middlewares = append(middlewares, eiaapi.WithRequestEditorFn(paramAuth.Intercept)) // Logging middleware, if logger is given if opts.Logger != nil { logLevel := defaultLogLevel if opts.LogLevel != nil { logLevel = *opts.LogLevel } middlewares = append(middlewares, eiaapi.WithRequestEditorFn(newLoggingMiddleware(opts.Logger, logLevel))) } client, err := eiaapi.NewClient(baseURL, slices.Clip(middlewares)...) if err != nil { return nil, err } clientWithResponses, err := eiaapi.NewClientWithResponses(baseURL, slices.Clip(middlewares)...) if err != nil { return nil, err } return &Client{ apiKey: opts.APIKey, ctx: opts.Context, healthCheckTimeout: hcTimeout, Client: client, ClientWithResponses: clientWithResponses, }, nil }