Skip to content

Commit

Permalink
Merge pull request #393 from 1Password/amanda/huggingface
Browse files Browse the repository at this point in the history
Amanda/huggingface
  • Loading branch information
SimonBarendse authored Oct 23, 2023
2 parents 6f8040b + 234fb2b commit 33b9329
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 0 deletions.
27 changes: 27 additions & 0 deletions plugins/huggingface/huggingface-cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package huggingface

import (
"github.com/1Password/shell-plugins/sdk"
"github.com/1Password/shell-plugins/sdk/needsauth"
"github.com/1Password/shell-plugins/sdk/schema"
"github.com/1Password/shell-plugins/sdk/schema/credname"
)

func HuggingFaceCLI() schema.Executable {
return schema.Executable{
Name: "HuggingFace CLI",
Runs: []string{"huggingface-cli"},
DocsURL: sdk.URL("https://huggingface.co/docs/huggingface_hub/quick-start"),
NeedsAuth: needsauth.IfAll(
needsauth.NotForHelpOrVersion(),
needsauth.NotWithoutArgs(),
needsauth.NotWhenContainsArgs("login"),
needsauth.NotWhenContainsArgs("logout"),
),
Uses: []schema.CredentialUsage{
{
Name: credname.APIToken,
},
},
}
}
22 changes: 22 additions & 0 deletions plugins/huggingface/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package huggingface

import (
"github.com/1Password/shell-plugins/sdk"
"github.com/1Password/shell-plugins/sdk/schema"
)

func New() schema.Plugin {
return schema.Plugin{
Name: "huggingface",
Platform: schema.PlatformInfo{
Name: "Hugging Face",
Homepage: sdk.URL("https://huggingface.co"),
},
Credentials: []schema.CredentialType{
UserAccessToken(),
},
Executables: []schema.Executable{
HuggingFaceCLI(),
},
}
}
1 change: 1 addition & 0 deletions plugins/huggingface/test-fixtures/token
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hf_yVvZeburdKtnwkVCWPXimmNwaFuEXAMPLE
87 changes: 87 additions & 0 deletions plugins/huggingface/user_access_token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package huggingface

import (
"context"

"github.com/1Password/shell-plugins/sdk"
"github.com/1Password/shell-plugins/sdk/importer"
"github.com/1Password/shell-plugins/sdk/provision"
"github.com/1Password/shell-plugins/sdk/schema"
"github.com/1Password/shell-plugins/sdk/schema/credname"
"github.com/1Password/shell-plugins/sdk/schema/fieldname"
)

func UserAccessToken() schema.CredentialType {
return schema.CredentialType{
Name: credname.APIToken,
DocsURL: sdk.URL("https://huggingface.co/docs/hub/security-tokens"),
ManagementURL: sdk.URL("https://huggingface.co/settings/tokens"),
Fields: []schema.CredentialField{
{
Name: fieldname.UserAccessToken,
MarkdownDescription: "Token used to authenticate to HuggingFace.",
Secret: true,
Composition: &schema.ValueComposition{
Length: 37,
Prefix: "hf_",
Charset: schema.Charset{
Uppercase: true,
Lowercase: true,
Symbols: true,
},
},
},
{
Name: fieldname.Endpoint,
MarkdownDescription: "Endpoint used to connect to HuggingFace CLI",
Optional: true,
Secret: false,
Composition: &schema.ValueComposition{
Charset: schema.Charset{
Uppercase: true,
Lowercase: true,
Digits: true,
Symbols: true,
},
},
},
{
Name: fieldname.APIUrl,
MarkdownDescription: "HF Inference Endpoint used to connect to HuggingFace CLI",
Optional: true,
Secret: false,
Composition: &schema.ValueComposition{
Charset: schema.Charset{
Uppercase: true,
Lowercase: true,
Digits: true,
Symbols: true,
},
},
},
},
DefaultProvisioner: provision.EnvVars(defaultEnvVarMapping),
Importer: importer.TryAll(
importer.TryEnvVarPair(defaultEnvVarMapping),
TryHuggingFaceTokenFile(),
)}
}

var defaultEnvVarMapping = map[string]sdk.FieldName{
"HUGGING_FACE_HUB_TOKEN": fieldname.UserAccessToken,
"HF_ENDPOINT": fieldname.Endpoint,
"HF_INFERENCE_ENDPOINT": fieldname.APIUrl,
}

func TryHuggingFaceTokenFile() sdk.Importer {
return importer.TryFile("~/.cache/huggingface/token", func(ctx context.Context, contents importer.FileContents, in sdk.ImportInput, out *sdk.ImportAttempt) {
fileData := string(contents)

out.AddCandidate(sdk.ImportCandidate{
Fields: map[sdk.FieldName]string{
fieldname.UserAccessToken: fileData,
},
})
})

}
48 changes: 48 additions & 0 deletions plugins/huggingface/user_access_token_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package huggingface

import (
"testing"

"github.com/1Password/shell-plugins/sdk"
"github.com/1Password/shell-plugins/sdk/plugintest"
"github.com/1Password/shell-plugins/sdk/schema/fieldname"
)

func TestAPITokenProvisioner(t *testing.T) {
plugintest.TestProvisioner(
t, UserAccessToken().DefaultProvisioner, map[string]plugintest.ProvisionCase{
"default": {
ItemFields: map[sdk.FieldName]string{
fieldname.UserAccessToken: "hf_yVvZeburdKtnwkVCWPXimmNwaFuEXAMPLE",
fieldname.Endpoint: "https://huggingface.co",
fieldname.APIUrl: "https://api-inference.huggingface.com",
},
ExpectedOutput: sdk.ProvisionOutput{
Environment: map[string]string{
"HUGGING_FACE_HUB_TOKEN": "hf_yVvZeburdKtnwkVCWPXimmNwaFuEXAMPLE",
"HF_ENDPOINT": "https://huggingface.co",
"HF_INFERENCE_ENDPOINT": "https://api-inference.huggingface.com",
},
},
},
})
}

func TestAPITokenImporter(t *testing.T) {
plugintest.TestImporter(
t, UserAccessToken().Importer, map[string]plugintest.ImportCase{
"config file (macOS)": {
Files: map[string]string{
"~/.cache/huggingface/token": plugintest.LoadFixture(t, "token"),
},
ExpectedCandidates: []sdk.ImportCandidate{
{
Fields: map[sdk.FieldName]string{
fieldname.UserAccessToken: "hf_yVvZeburdKtnwkVCWPXimmNwaFuEXAMPLE\n",
},
},
},
},
},
)
}
2 changes: 2 additions & 0 deletions sdk/schema/fieldname/names.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "github.com/1Password/shell-plugins/sdk"
// Credential field names.
const (
APIHost = sdk.FieldName("API Host")
APIUrl = sdk.FieldName("API URL")
APIKey = sdk.FieldName("API Key")
APIKeyID = sdk.FieldName("API Key ID")
APISecret = sdk.FieldName("API Secret")
Expand Down Expand Up @@ -53,6 +54,7 @@ const (
Token = sdk.FieldName("Token")
URL = sdk.FieldName("URL")
User = sdk.FieldName("User")
UserAccessToken = sdk.FieldName("User Access Token")
Username = sdk.FieldName("Username")
Website = sdk.FieldName("Website")
)
Expand Down

0 comments on commit 33b9329

Please sign in to comment.