From f100c374e87d30948592ab7886978997910ad961 Mon Sep 17 00:00:00 2001 From: Edoardo La Greca Date: Mon, 18 Mar 2024 12:51:08 +0100 Subject: [PATCH] provide better documentation and refactor --- client.go | 18 +++++----- cmd/dovelet/flag.go | 7 ++-- cmd/dovelet/main.go | 8 +++-- .../application_credentials_provider.go | 36 +++++++++++-------- credentials/credentials.go | 13 ++++--- feature.go | 2 ++ 6 files changed, 48 insertions(+), 36 deletions(-) diff --git a/client.go b/client.go index 14f3aad..b38a891 100644 --- a/client.go +++ b/client.go @@ -10,20 +10,21 @@ import ( "google.golang.org/api/option" ) -// VisionClient holds the generic properties for any Google Cloud Vision client. -// This type should become a general type for all vision client types in future, for now it only holds some common data. +// A VisionClient has generic Google Cloud Vision client properties. type VisionClient struct { - // The context for each client + // context is the client context. context context.Context - // The credentials for each client + // credentials holds the client credentials. credentials option.ClientOption - // Language hints (see https://pkg.go.dev/cloud.google.com/go/vision/v2/apiv1/visionpb#ImageContext.LanguageHints) + // languageHints holds the specified language hints. + // (See https://pkg.go.dev/cloud.google.com/go/vision/v2/apiv1/visionpb#ImageContext.LanguageHints) languageHints []string - // Keep language hints for all requests, once set? + // keepLanguageHints decides whether the current language hints are kept + // for the following requests (true) or discarded after the next request (false). keepLanguageHints bool } -// New returns a pointer to a new Client object. +// NewClient returns a new VisionClient instance. func NewClient(ctx context.Context, credentials option.ClientOption) VisionClient { return VisionClient{ context: ctx, @@ -31,7 +32,8 @@ func NewClient(ctx context.Context, credentials option.ClientOption) VisionClien } } -// Set language hints for better results (see https://cloud.google.com/vision/docs/languages, the "languageHints code" column). +// Set language hints for better results (see https://cloud.google.com/vision/docs/languages, +// the "languageHints code" column). // Set keep to true to keep the languages for all successive requests. func (c *VisionClient) SetLanguageHints(languages []string, keep bool) { c.languageHints = languages diff --git a/cmd/dovelet/flag.go b/cmd/dovelet/flag.go index 0f7419b..c920b97 100644 --- a/cmd/dovelet/flag.go +++ b/cmd/dovelet/flag.go @@ -7,7 +7,7 @@ import ( "github.com/EdoardoLaGreca/dovelet" ) -// Detections type +// A CLArgs holds values command line argument values. type CLArgs struct { face bool landmark bool @@ -21,8 +21,7 @@ type CLArgs struct { flags *flag.FlagSet } -// ParseArgs parses the command-line flags from arguments and returns -// a new pointer of a Detections object.. +// ParseArgs parses the command line flags and arguments. func ParseArgs(args []string) *CLArgs { f := flag.NewFlagSet("Detections", flag.ExitOnError) faceDetection := f.Bool("face", false, "Run face detection.") @@ -91,6 +90,8 @@ func (d CLArgs) Feature() dovelet.DetectionFeature { return dovelet.TypeUnspecified } +// Language returns the language(s) specified as command line arguments for +// text detection. func (d CLArgs) Language() []string { return d.languages } diff --git a/cmd/dovelet/main.go b/cmd/dovelet/main.go index f723d86..0dfea82 100644 --- a/cmd/dovelet/main.go +++ b/cmd/dovelet/main.go @@ -14,29 +14,31 @@ import ( func main() { // Parse arguments to run this function. args := ParseArgs(os.Args[1:]) - if len(args.Args()) == 0 { fmt.Fprintf(os.Stderr, "usage of %s:\n", os.Args[0]) args.Usage() os.Exit(1) } - // Provide credentials + // Provide credentials. creds, err := credentials.NewApplicationCredentials("") if err != nil { log.Fatalf("unable to fetch credentials: %v\n", err) } + // Create a new Vision client. client := dovelet.NewClient(context.Background(), creds.Provide()) if len(args.Language()) > 0 { client.SetLanguageHints(args.Language(), false) } + + // Request image annotation with a certain feature. res, err := client.RequestImageAnnotation(args.Args(), args.Feature()) if err != nil { log.Fatalf("unable to request image annotation: %v\n", err) } - // Marshal annotations from responses + // Marshal annotations from responses. body, err := json.MarshalIndent(res.Responses, "", " ") if err != nil { log.Fatalf("unable to marshal the response: %v\n", err) diff --git a/credentials/application_credentials_provider.go b/credentials/application_credentials_provider.go index f4bbfc2..52d16b6 100644 --- a/credentials/application_credentials_provider.go +++ b/credentials/application_credentials_provider.go @@ -7,19 +7,20 @@ import ( "google.golang.org/api/option" ) -// A ApplicationCredentialsProvider retrieves credentials from the current user's home -// directory, and keeps track if those credentials are expired. +// An ApplicationCredentialsProvider has a file system path to fetch the +// credentials from. type ApplicationCredentialsProvider struct { - // FilePath holds the path to the credentials file. - FilePath string + // filePath holds the path to the credentials file. + filePath string } -// NewApplicationCredentials returns a pointer to a new Credentials object -// wrapping the file provider. -func NewApplicationCredentials(filename string) (*ApplicationCredentialsProvider, error) { - if filename != "" { +// NewApplicationCredentials fetches credentials from a file name or path in +// the file system. If the file name is empty, it uses the value of the +// `GOOGLE_APPLICATION_CREDENTIALS` shell variable. +func NewApplicationCredentials(filepath string) (*ApplicationCredentialsProvider, error) { + if filepath != "" { return &ApplicationCredentialsProvider{ - FilePath: filename, + filePath: filepath, }, nil } fpath, err := credentialsPath() @@ -27,18 +28,23 @@ func NewApplicationCredentials(filename string) (*ApplicationCredentialsProvider return nil, err } return &ApplicationCredentialsProvider{ - FilePath: fpath, + filePath: fpath, }, nil } -// Provide reads and extracts the shared credentials from the current -// users home directory. +// FilePath returns the path associated with an ApplicationCredentialsProvider. +func (acp ApplicationCredentialsProvider) FilePath() string { + return acp.filePath +} + +// Provide returns the ClientOption instance holding the credentials. func (p *ApplicationCredentialsProvider) Provide() option.ClientOption { - return option.WithCredentialsFile(p.FilePath) + return option.WithCredentialsFile(p.filePath) } -// credentialsPath returns the filename to use to read google application credentials. -// Will return an error if the user's home directory path cannot be found. +// credentialsPath returns the filename to use to read google application +// credentials. credentialsPath returns an error if the user's home +// directory path cannot be found. func credentialsPath() (string, error) { varname := "GOOGLE_APPLICATION_CREDENTIALS" fpath := os.Getenv(varname) diff --git a/credentials/credentials.go b/credentials/credentials.go index 6091ea2..f69d5a9 100644 --- a/credentials/credentials.go +++ b/credentials/credentials.go @@ -7,11 +7,10 @@ import ( "google.golang.org/api/option" ) -// A Provider is the interface for any component which will provide credentials -// Value. -type Provider interface { - // Provide returns nil if it successfully retrieved the value. - // Error is returned if the value were not obtainable, or empty. +// A Provider is any component which provides credentials. +type CredentialsProvider interface { + // Provide returns the ClientOption associated with the credentials. + // It returns an error if the credentials could not be fetched. Provide() (option.ClientOption, error) } @@ -19,11 +18,11 @@ type Provider interface { // credentials Value. type Credentials struct { m sync.Mutex - provider Provider + provider CredentialsProvider } // NewCredentials returns a pointer to a new Credentials with the provider set. -func NewCredentials(provider Provider) *Credentials { +func NewCredentials(provider CredentialsProvider) *Credentials { return &Credentials{ provider: provider, } diff --git a/feature.go b/feature.go index 9b3b443..277d4ce 100644 --- a/feature.go +++ b/feature.go @@ -4,6 +4,7 @@ import ( "cloud.google.com/go/vision/v2/apiv1/visionpb" ) +// A DetectionFeature is a Vision feature used in detection. type DetectionFeature int const ( @@ -27,6 +28,7 @@ const ( ImageProperties ) +// VisionFeature maps DetectionFeature values to visionpb.Feature_Type values. func (d DetectionFeature) VisionFeature() visionpb.Feature_Type { switch d { case TypeUnspecified: