{"id":36508916,"url":"https://github.com/scttfrdmn/globus-go-sdk","last_synced_at":"2026-07-23T05:00:54.063Z","repository":{"id":291181584,"uuid":"973332779","full_name":"scttfrdmn/globus-go-sdk","owner":"scttfrdmn","description":"Go SDK for Globus platform services - Authentication, Data Transfer, Groups, Search, Flows \u0026 Compute APIs with comprehensive Python SDK parity. Features OAuth2 flows, robust error handling, extensive testing, and production-ready reliability.","archived":false,"fork":false,"pushed_at":"2026-07-20T19:08:12.000Z","size":13284,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-07-20T20:26:16.414Z","etag":null,"topics":["api-client","authentication","cloud","compute","data-transfer","distributed-computing","flows","globus","go","golang","golang-sdk","groups","hpc","oauth2","python-sdk-parity","research","rest-api","scientific-computing","sdk","search"],"latest_commit_sha":null,"homepage":"https://github.com/scttfrdmn/globus-go-sdk","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scttfrdmn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-26T19:00:39.000Z","updated_at":"2026-07-20T19:09:14.000Z","dependencies_parsed_at":"2025-08-09T03:03:33.766Z","dependency_job_id":"53e881f4-684d-4f27-ae36-b602514d1775","html_url":"https://github.com/scttfrdmn/globus-go-sdk","commit_stats":null,"previous_names":["scttfrdmn/globus-go-sdk"],"tags_count":47,"template":false,"template_full_name":null,"purl":"pkg:github/scttfrdmn/globus-go-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scttfrdmn%2Fglobus-go-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scttfrdmn%2Fglobus-go-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scttfrdmn%2Fglobus-go-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scttfrdmn%2Fglobus-go-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scttfrdmn","download_url":"https://codeload.github.com/scttfrdmn/globus-go-sdk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scttfrdmn%2Fglobus-go-sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35789247,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-23T02:00:06.683Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-client","authentication","cloud","compute","data-transfer","distributed-computing","flows","globus","go","golang","golang-sdk","groups","hpc","oauth2","python-sdk-parity","research","rest-api","scientific-computing","sdk","search"],"created_at":"2026-01-12T02:33:16.597Z","updated_at":"2026-07-23T05:00:54.052Z","avatar_url":"https://github.com/scttfrdmn.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SPDX-License-Identifier: Apache-2.0\n# SPDX-FileCopyrightText: 2025 Scott Friedman and Project Contributors\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"doc/images/globus-go-sdk-logo.png\" alt=\"Globus Go SDK Logo\" width=\"400\"/\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eGlobus Go SDK\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/scttfrdmn/globus-go-sdk/v3\"\u003e\u003cimg src=\"https://pkg.go.dev/badge/github.com/scttfrdmn/globus-go-sdk/v3.svg\" alt=\"Go Reference\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://goreportcard.com/report/github.com/scttfrdmn/globus-go-sdk/v3\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/scttfrdmn/globus-go-sdk/v3\" alt=\"Go Report Card\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/scttfrdmn/globus-go-sdk/actions/workflows/go.yml\"\u003e\u003cimg src=\"https://github.com/scttfrdmn/globus-go-sdk/actions/workflows/go.yml/badge.svg\" alt=\"Build Status\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/scttfrdmn/globus-go-sdk\" alt=\"License\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/scttfrdmn/globus-go-sdk/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/scttfrdmn/globus-go-sdk\" alt=\"Release\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/scttfrdmn/globus-go-sdk\"\u003e\u003cimg src=\"https://codecov.io/gh/scttfrdmn/globus-go-sdk/branch/main/graph/badge.svg\" alt=\"Coverage\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nA Go SDK for interacting with Globus services, providing a simple and idiomatic Go interface to Globus APIs.\n\n\u003e **STATUS**: **v3** is production-ready ✅ and tracks the final Python SDK v3 line (v3.65.0). **v4** implements Python SDK **v4.8.1** parity (see [.github/upstream-versions.json](.github/upstream-versions.json) for the exact ported-vs-upstream status). See [Version Guide](#-version-guide) below.\n\n\u003e **DISCLAIMER**: The Globus Go SDK is an independent, community-developed project and is not officially affiliated with, endorsed by, or supported by Globus, the University of Chicago, or their affiliated organizations. This SDK is maintained by independent contributors and is not a product of Globus or the University of Chicago.\n\n## 🚀 Version Guide\n\n**Choose the right version for your needs:**\n\n| Version | Status | When to Use | Installation |\n|---------|--------|-------------|--------------|\n| **v3** (Python v3.65.0 parity) | ✅ **Production Ready** | All production applications | `go get github.com/scttfrdmn/globus-go-sdk/v3` |\n| **v4** (Python v4.8.1 parity) | 🔶 Early Adopters | Testing v4 features, non-critical apps | `go get github.com/scttfrdmn/globus-go-sdk/v4` |\n\n**v3 Features:** Connection pooling, rate limiting, token storage, comprehensive tests\n**v4 Features:** Context-first API, explicit scopes, Close() methods, GCS downloads, device auth, action providers, full test coverage\n\n**Recommendation:** Use **v3** for production. Try **v4** for new projects if you want the latest API design.\n\n## 📚 Documentation\n\n**[Read the full documentation](https://scttfrdmn.github.io/globus-go-sdk/)**\n\n- [Installation Guide](https://scttfrdmn.github.io/globus-go-sdk/getting-started/installation/)\n- [Quick Start](https://scttfrdmn.github.io/globus-go-sdk/getting-started/quickstart/)\n- [API Reference](https://scttfrdmn.github.io/globus-go-sdk/api/)\n- [Code Examples](https://scttfrdmn.github.io/globus-go-sdk/examples/transfer/)\n\n## 📖 API Documentation\n\n**Complete API documentation is available at [pkg.go.dev](https://pkg.go.dev/github.com/scttfrdmn/globus-go-sdk/v3)**\n\n### Service-Specific Documentation\n\n- **[Core SDK](https://pkg.go.dev/github.com/scttfrdmn/globus-go-sdk/v3/pkg)** - Main SDK entry point and configuration\n- **[Authentication](https://pkg.go.dev/github.com/scttfrdmn/globus-go-sdk/v3/pkg/services/auth)** - OAuth2 flows, token management, MFA support\n- **[Groups](https://pkg.go.dev/github.com/scttfrdmn/globus-go-sdk/v3/pkg/services/groups)** - Group and membership management operations\n- **[Transfer](https://pkg.go.dev/github.com/scttfrdmn/globus-go-sdk/v3/pkg/services/transfer)** - File transfer with resumable and recursive support\n- **[Search](https://pkg.go.dev/github.com/scttfrdmn/globus-go-sdk/v3/pkg/services/search)** - Advanced search with query building and pagination\n- **[Flows](https://pkg.go.dev/github.com/scttfrdmn/globus-go-sdk/v3/pkg/services/flows)** - Automation workflows and batch operations\n- **[Compute](https://pkg.go.dev/github.com/scttfrdmn/globus-go-sdk/v3/pkg/services/compute)** - Function execution and endpoint management\n- **[Timers](https://pkg.go.dev/github.com/scttfrdmn/globus-go-sdk/v3/pkg/services/timers)** - Timer and scheduling services\n- **[Tokens](https://pkg.go.dev/github.com/scttfrdmn/globus-go-sdk/v3/pkg/services/tokens)** - Token introspection and validation\n\n## Features\n\n- **Authentication**: OAuth2 flows with token management and automatic refreshing\n- **Token Management**: Complete token lifecycle management with automatic refreshing\n- **Token Storage**: Persistent token storage (memory and file-based implementations)\n- **Groups**: Group management and membership operations\n- **Transfer**: File transfer with recursive directory support and resumable transfers\n- **Search**: Advanced search capabilities with query building and pagination\n- **Flows**: Automation workflows with batch operations\n- **Compute**: Function execution, endpoint management, workflows, and task groups\n- **Performance**: Connection pooling, rate limiting, and backoff strategies\n- **Observability**: Structured logging and distributed tracing\n- **Reliability**: Comprehensive error handling with retries and circuit breakers\n- **Compatibility**: API version compatibility checking and management\n- **Integration**: Extensive testing infrastructure\n- **Examples**: CLI, token management, compute workflows, and web application examples\n- **Utilities**: Verification tools to test credentials\n\n## Installation\n\n### Requirements\n\n- Go 1.18 or higher (uses generics for some utility functions)\n- No external dependencies except for testing\n\n### Using `go get`\n\n```bash\ngo get github.com/scttfrdmn/globus-go-sdk/v3\n```\n\n### Using Go modules in your project\n\n```go\n// v3 (Production - Recommended)\nimport \"github.com/scttfrdmn/globus-go-sdk/v3/pkg\"\n\n// v4 (Early Adopters)\nimport \"github.com/scttfrdmn/globus-go-sdk/v4/pkg/core\"\n```\n\n## Testing with Globus Credentials\n\nThis SDK includes a standalone credential verification tool to test your Globus credentials:\n\n```bash\n# Clone the repository\ngit clone https://github.com/scttfrdmn/globus-go-sdk.git\ncd globus-go-sdk\n\n# Copy the example .env.test file and add your credentials\ncp .env.test.example .env.test\n# Edit .env.test with your favorite editor and add your credentials\n\n# Build and run the verification tool\ncd cmd/verify-credentials\ngo build\n./verify-credentials\n```\n\n### Comprehensive Testing\n\nFor complete SDK testing, including all services with real credentials:\n\n```bash\n# After setting up your .env.test file\n./scripts/comprehensive_testing.sh  # Run all tests with real credentials\n```\n\nThis script runs all unit tests, examples, integration tests, and verifies all services work with your real credentials. Results are logged to `comprehensive_testing.log`.\n\nSee [doc/COMPREHENSIVE_TESTING.md](doc/COMPREHENSIVE_TESTING.md) for detailed testing guidelines.\n\n### Integration Testing\n\nFor targeted integration testing:\n\n```bash\n# After setting up your .env.test file\n./scripts/run_integration_tests.sh --verify  # Verify credentials only\n./scripts/run_integration_tests.sh           # Run all integration tests\n```\n\nSee [doc/INTEGRATION_TESTING.md](doc/INTEGRATION_TESTING.md) for more details on integration testing with credentials.\n\n## SDK Organization\n\nThis SDK follows the structure and patterns established by the official Globus Python and JavaScript SDKs. It is organized into service-specific packages that each provide clients for interacting with Globus services.\n\n### Core Components\n\n- `pkg/core`: Base client functionality, error handling, logging, etc.\n- `pkg/core/authorizers`: Authentication mechanisms\n- `pkg/core/transport`: HTTP transport layer\n- `pkg/core/config`: Configuration management\n\n### Services\n\n- `pkg/services/auth`: OAuth2 authentication and authorization\n- `pkg/services/tokens`: Token management with storage and automatic refreshing\n- `pkg/services/groups`: Group management\n- `pkg/services/transfer`: File transfer and endpoint management\n- `pkg/services/search`: Data search and discovery\n- `pkg/services/flows`: Automation and workflow orchestration\n- `pkg/services/compute`: Distributed computation and function execution\n\n## Quick Start\n\n### Simple Transfer Example (v3)\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n\n    \"github.com/scttfrdmn/globus-go-sdk/v3/pkg/core/authorizers\"\n    \"github.com/scttfrdmn/globus-go-sdk/v3/pkg/services/transfer\"\n)\n\nfunc main() {\n    // Create an authorizer with your access token\n    authorizer := authorizers.StaticTokenCoreAuthorizer(\"your-access-token\")\n\n    // Create a transfer client\n    client, err := transfer.NewClient(\n        transfer.WithAuthorizer(authorizer),\n    )\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    // List your endpoints\n    endpoints, err := client.ListEndpoints(context.Background(), nil)\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    fmt.Printf(\"Found %d endpoints\\n\", len(endpoints.Data))\n}\n```\n\n### Simple Transfer Example (v4 with Close())\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n\n    \"github.com/scttfrdmn/globus-go-sdk/v4/pkg/core\"\n    \"github.com/scttfrdmn/globus-go-sdk/v4/pkg/services/transfer\"\n)\n\nfunc main() {\n    ctx := context.Background()\n\n    // Create config with explicit scopes\n    config := \u0026core.Config{\n        AccessToken: \"your-access-token\",\n        Scopes:      []string{core.Scopes.TransferAll},\n    }\n\n    // Create transfer client\n    client, err := transfer.NewClient(ctx, config)\n    if err != nil {\n        log.Fatal(err)\n    }\n    defer client.Close() // Clean up resources\n\n    // Use the client...\n    fmt.Println(\"Client ready!\")\n}\n```\n\n### Authentication with Token Management (v3)\n\nfunc main() {\n    // Create a token storage for persisting tokens\n    storage, err := tokens.NewFileStorage(\"~/.globus-tokens\")\n    if err != nil {\n        log.Fatalf(\"Failed to create token storage: %v\", err)\n    }\n    \n    // Create a new SDK configuration\n    config := pkg.NewConfigFromEnvironment().\n        WithClientID(os.Getenv(\"GLOBUS_CLIENT_ID\")).\n        WithClientSecret(os.Getenv(\"GLOBUS_CLIENT_SECRET\"))\n\n    // Create a new Auth client\n    authClient, err := config.NewAuthClient()\n    if err != nil {\n        log.Fatalf(\"Failed to create auth client: %v\", err)\n    }\n    authClient.SetRedirectURL(\"http://localhost:8080/callback\")\n    \n    // Create a token manager for automatic refresh using the functional options pattern\n    tokenManager, err := tokens.NewManager(\n        tokens.WithStorage(storage),\n        tokens.WithRefreshHandler(authClient),\n    )\n    if err != nil {\n        log.Fatalf(\"Failed to create token manager: %v\", err)\n    }\n    \n    // Configure token refresh settings\n    tokenManager.SetRefreshThreshold(5 * time.Minute)\n    \n    // Start background refresh\n    stopRefresh := tokenManager.StartBackgroundRefresh(15 * time.Minute)\n    defer stopRefresh() // Stop background refresh when done\n    \n    // Check if we already have tokens\n    entry, err := tokenManager.GetToken(context.Background(), \"default\")\n    if err == nil \u0026\u0026 !entry.TokenSet.IsExpired() {\n        // We have valid tokens, use them\n        fmt.Printf(\"Using existing token (expires at: %s)\\n\", entry.TokenSet.ExpiresAt.Format(time.RFC3339))\n        return\n    }\n    \n    // We need new tokens, start the OAuth2 flow\n    authURL := authClient.GetAuthorizationURL(\"my-state\")\n    fmt.Printf(\"Visit this URL to log in: %s\\n\", authURL)\n    \n    // Start a local server to handle the callback\n    http.HandleFunc(\"/callback\", func(w http.ResponseWriter, r *http.Request) {\n        code := r.URL.Query().Get(\"code\")\n        \n        // Exchange code for tokens\n        tokenResponse, err := authClient.ExchangeAuthorizationCode(context.Background(), code)\n        if err != nil {\n            log.Fatalf(\"Failed to exchange code: %v\", err)\n            http.Error(w, \"Failed to exchange code\", http.StatusInternalServerError)\n            return\n        }\n        \n        // Create a token entry\n        entry := \u0026tokens.Entry{\n            Resource: \"default\",\n            TokenSet: \u0026tokens.TokenSet{\n                AccessToken:  tokenResponse.AccessToken,\n                RefreshToken: tokenResponse.RefreshToken,\n                ExpiresAt:    time.Now().Add(time.Duration(tokenResponse.ExpiresIn) * time.Second),\n                Scope:        tokenResponse.Scope,\n            },\n        }\n        \n        // Store the tokens\n        err = storage.Store(entry)\n        if err != nil {\n            log.Fatalf(\"Failed to store token: %v\", err)\n            http.Error(w, \"Failed to store token\", http.StatusInternalServerError)\n            return\n        }\n        \n        fmt.Fprintf(w, \"Authentication successful! You can close this window.\")\n        fmt.Printf(\"Authentication successful! Tokens stored.\\n\")\n    })\n    \n    log.Fatal(http.ListenAndServe(\":8080\", nil))\n}\n```\n\n### Groups\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"os\"\n\n    \"github.com/scttfrdmn/globus-go-sdk/v3/v3/pkg\"\n)\n\nfunc main() {\n    // Create a new SDK configuration\n    config := pkg.NewConfigFromEnvironment()\n\n    // Create a new Groups client with an access token using the functional options pattern\n    groupsClient, err := config.NewGroupsClient(os.Getenv(\"GLOBUS_ACCESS_TOKEN\"))\n    if err != nil {\n        log.Fatalf(\"Failed to create groups client: %v\", err)\n    }\n    \n    // List groups the user is a member of\n    groupList, err := groupsClient.ListGroups(context.Background(), nil)\n    if err != nil {\n        log.Fatalf(\"Failed to list groups: %v\", err)\n    }\n    \n    fmt.Printf(\"You are a member of %d groups:\\n\", len(groupList.Groups))\n    for _, group := range groupList.Groups {\n        fmt.Printf(\"- %s (%s)\\n\", group.Name, group.ID)\n    }\n}\n```\n\n### Transfer\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"os\"\n    \"time\"\n\n    \"github.com/scttfrdmn/globus-go-sdk/v3/v3/pkg\"\n    \"github.com/scttfrdmn/globus-go-sdk/v3/v3/pkg/services/transfer\"\n)\n\nfunc main() {\n    // Create a new SDK configuration\n    config := pkg.NewConfigFromEnvironment()\n\n    // Create a new Transfer client with an access token using the functional options pattern\n    transferClient, err := config.NewTransferClient(os.Getenv(\"GLOBUS_ACCESS_TOKEN\"))\n    if err != nil {\n        log.Fatalf(\"Failed to create transfer client: %v\", err)\n    }\n    \n    // List endpoints the user has access to\n    endpoints, err := transferClient.ListEndpoints(context.Background(), nil)\n    if err != nil {\n        log.Fatalf(\"Failed to list endpoints: %v\", err)\n    }\n    \n    fmt.Printf(\"Found %d endpoints:\\n\", len(endpoints.DATA))\n    for i, endpoint := range endpoints.DATA {\n        fmt.Printf(\"%d. %s (%s)\\n\", i+1, endpoint.DisplayName, endpoint.ID)\n    }\n    \n    // Submit a file transfer (if source and destination endpoints are provided)\n    sourceEndpointID := os.Getenv(\"SOURCE_ENDPOINT_ID\")\n    destEndpointID := os.Getenv(\"DEST_ENDPOINT_ID\")\n    \n    if sourceEndpointID != \"\" \u0026\u0026 destEndpointID != \"\" {\n        // Regular file transfer\n        task, err := transferClient.SubmitTransfer(\n            context.Background(),\n            sourceEndpointID,\n            destEndpointID,\n            \u0026transfer.TransferData{\n                Label: \"SDK Example Transfer\",\n                Items: []transfer.TransferItem{\n                    {\n                        Source:      \"/~/source.txt\",\n                        Destination: \"/~/destination.txt\",\n                    },\n                },\n                SyncLevel: transfer.SyncChecksum,\n                Verify:    true,\n            },\n        )\n        if err != nil {\n            log.Fatalf(\"Failed to submit transfer: %v\", err)\n        }\n        \n        fmt.Printf(\"Transfer submitted, task ID: %s\\n\", task.TaskID)\n        \n        // Monitor the task\n        for {\n            status, err := transferClient.GetTaskStatus(context.Background(), task.TaskID)\n            if err != nil {\n                log.Fatalf(\"Failed to get task status: %v\", err)\n            }\n            \n            fmt.Printf(\"Task status: %s (%d/%d files)\\n\", \n                status.Status, status.FilesTransferred, status.FilesTotal)\n                \n            if status.Status == \"SUCCEEDED\" || status.Status == \"FAILED\" {\n                break\n            }\n            \n            time.Sleep(2 * time.Second)\n        }\n        \n        // Submit a recursive directory transfer\n        result, err := transferClient.SubmitRecursiveTransfer(\n            context.Background(),\n            sourceEndpointID, \"/~/source_dir\",\n            destEndpointID, \"/~/dest_dir\",\n            \u0026transfer.RecursiveTransferOptions{\n                Label:     \"SDK Example Recursive Transfer\",\n                SyncLevel: transfer.SyncChecksum,\n                BatchSize: 100,\n            },\n        )\n        if err != nil {\n            log.Fatalf(\"Failed to submit recursive transfer: %v\", err)\n        }\n        \n        fmt.Printf(\"Recursive transfer submitted with %d tasks\\n\", len(result.TaskIDs))\n        fmt.Printf(\"Transferred %d items\\n\", result.ItemsTransferred)\n    }\n}\n```\n\n### Search\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"os\"\n\n    \"github.com/scttfrdmn/globus-go-sdk/v3/v3/pkg\"\n)\n\nfunc main() {\n    // Create a new SDK configuration\n    config := pkg.NewConfigFromEnvironment()\n\n    // Create a new Search client with an access token using the functional options pattern\n    searchClient, err := config.NewSearchClient(os.Getenv(\"GLOBUS_ACCESS_TOKEN\"))\n    if err != nil {\n        log.Fatalf(\"Failed to create search client: %v\", err)\n    }\n    \n    // List indexes the user has access to\n    indexes, err := searchClient.ListIndexes(context.Background(), nil)\n    if err != nil {\n        log.Fatalf(\"Failed to list indexes: %v\", err)\n    }\n    \n    fmt.Printf(\"Found %d indexes:\\n\", len(indexes.Indexes))\n    for i, index := range indexes.Indexes {\n        fmt.Printf(\"%d. %s (%s)\\n\", i+1, index.DisplayName, index.ID)\n    }\n    \n    // Search an index (if index ID is provided)\n    indexID := os.Getenv(\"GLOBUS_SEARCH_INDEX_ID\")\n    if indexID != \"\" {\n        searchReq := \u0026pkg.SearchRequest{\n            IndexID: indexID,\n            Query:   \"example\",\n            Options: \u0026pkg.SearchOptions{\n                Limit: 10,\n            },\n        }\n        \n        results, err := searchClient.Search(context.Background(), searchReq)\n        if err != nil {\n            log.Fatalf(\"Failed to search: %v\", err)\n        }\n        \n        fmt.Printf(\"Search found %d results\\n\", results.Count)\n        for i, result := range results.Results {\n            fmt.Printf(\"%d. %s (Score: %.2f)\\n\", i+1, result.Subject, result.Score)\n        }\n    }\n}\n```\n\n### Flows\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"os\"\n    \"time\"\n\n    \"github.com/scttfrdmn/globus-go-sdk/v3/v3/pkg\"\n)\n\nfunc main() {\n    // Create a new SDK configuration\n    config := pkg.NewConfigFromEnvironment()\n\n    // Create a new Flows client with an access token using the functional options pattern\n    flowsClient, err := config.NewFlowsClient(os.Getenv(\"GLOBUS_ACCESS_TOKEN\"))\n    if err != nil {\n        log.Fatalf(\"Failed to create flows client: %v\", err)\n    }\n    \n    // List flows the user has access to\n    flows, err := flowsClient.ListFlows(context.Background(), nil)\n    if err != nil {\n        log.Fatalf(\"Failed to list flows: %v\", err)\n    }\n    \n    fmt.Printf(\"Found %d flows:\\n\", len(flows.Flows))\n    for i, flow := range flows.Flows {\n        fmt.Printf(\"%d. %s (%s)\\n\", i+1, flow.Title, flow.ID)\n    }\n    \n    // Run a flow (if flow ID is provided)\n    flowID := os.Getenv(\"GLOBUS_FLOW_ID\")\n    if flowID != \"\" {\n        runReq := \u0026pkg.RunRequest{\n            FlowID: flowID,\n            Label:  \"Example Run \" + time.Now().Format(\"20060102\"),\n            Input: map[string]interface{}{\n                \"message\": \"Hello from Globus Go SDK!\",\n            },\n        }\n        \n        run, err := flowsClient.RunFlow(context.Background(), runReq)\n        if err != nil {\n            log.Fatalf(\"Failed to run flow: %v\", err)\n        }\n        \n        fmt.Printf(\"Flow run started: %s (Status: %s)\\n\", run.RunID, run.Status)\n    }\n}\n```\n\n## Documentation\n\nFor detailed documentation, see:\n\n- [Online Documentation](https://scttfrdmn.github.io/globus-go-sdk/) ← Comprehensive documentation hosted on GitHub Pages\n- [GoDoc Reference](https://pkg.go.dev/github.com/scttfrdmn/globus-go-sdk/v3/)\n- [User Guide](doc/user-guide.md)\n- [Quick Start Examples](doc/QUICK_START_EXAMPLES.md)\n- [v3.60.0 Migration Guide](doc/V3.60.0_MIGRATION_GUIDE.md)\n- [v0.8.0 Migration Guide](doc/V0.8.0_MIGRATION_GUIDE.md)\n- [Client Initialization](doc/CLIENT_INITIALIZATION.md)\n- [Functional Options Pattern Best Practices](doc/functional-options-guide.md)\n- [Error Handling](doc/ERROR_HANDLING.md)\n\n### API Reference Documentation\n- [API Reference Overview](doc/reference/README.md)\n- **Auth Service:**\n  - [Auth Client](doc/reference/auth/client.md)\n  - [OAuth2 Flows](doc/reference/auth/oauth2.md)\n  - [Token Validation](doc/reference/auth/token.md)\n  - [MFA Support](doc/reference/auth/mfa.md)\n- **Tokens Package:**\n  - [Token Manager](doc/reference/tokens/manager.md)\n  - [Token Storage](doc/reference/tokens/storage.md)\n  - [Token Refresh](doc/reference/tokens/refresh.md)\n- **Transfer Service:**\n  - [Transfer Client](doc/reference/transfer/client.md)\n  - [Endpoint Operations](doc/reference/transfer/endpoints.md)\n  - [Transfer Operations](doc/reference/transfer/transfers.md)\n  - [Recursive Transfers](doc/reference/transfer/recursive.md)\n  - [Resumable Transfers](doc/reference/transfer/resumable.md)\n- **Search Service:**\n  - [Search Client](doc/reference/search/client.md)\n  - [Query Operations](doc/reference/search/queries.md)\n  - [Advanced Queries](doc/reference/search/advanced.md)\n  - [Batch Operations](doc/reference/search/batch.md)\n- **Flows Service:**\n  - [Flows Client](doc/reference/flows/client.md)\n  - [Flow Operations](doc/reference/flows/flows.md)\n  - [Run Operations](doc/reference/flows/runs.md)\n  - [Batch Operations](doc/reference/flows/batch.md)\n- **Compute Service:**\n  - [Compute Client](doc/reference/compute/client.md)\n  - [Container Operations](doc/reference/compute/containers.md)\n  - [Batch Operations](doc/reference/compute/batch.md)\n  - [Environment Operations](doc/reference/compute/environments.md)\n- **Groups Service:**\n  - [Groups Client](doc/reference/groups/client.md)\n  - [Group Operations](doc/reference/groups/groups.md)\n  - [Membership Operations](doc/reference/groups/members.md)\n  - [Role Operations](doc/reference/groups/roles.md)\n- **Timers Service:**\n  - [Timers Client](doc/reference/timers/client.md)\n  - [Timer Operations](doc/reference/timers/timers.md)\n  - [Run Operations](doc/reference/timers/jobs.md)\n\n### Guides and Examples\n- [Token Management Example](examples/token-management/README.md)\n- [Tokens Package Guide](doc/tokens-package.md)\n- [Token Storage Guide](doc/token-storage.md)\n- [Recursive Transfers Guide](doc/recursive-transfers.md)\n- [Resumable Transfers Guide](doc/resumable-transfers.md)\n- [Logging and Tracing Guide](doc/logging-and-tracing.md)\n- [Integration Testing Guide](doc/INTEGRATION_TESTING.md)\n- [Search Client Guide](doc/search-client.md)\n- [Timers Client Guide](doc/timers-client.md)\n- [Memory Optimization Guide](doc/memory-optimization.md)\n- [Connection Pooling Guide](doc/connection-pooling.md)\n- [MFA Authentication Guide](doc/mfa-authentication.md)\n- [Shell Testing Guide](doc/shell-testing.md)\n- [Security Guidelines](doc/SECURITY_GUIDELINES.md)\n- [Security Audit Plan](doc/SECURITY_AUDIT_PLAN.md)\n- [Data Schemas](doc/data-schemas.md)\n- [Extending the SDK](doc/extending-the-sdk.md)\n- [CLI Example](cmd/globus-cli/README.md)\n- [Compute Workflows Example](examples/compute-workflow/main.go)\n- [Compute Workflows Guide](doc/compute-workflows.md)\n- [Unified Systems Example](examples/unified-systems/main.go) ← New for v3.60.0!\n- [Unified Systems Guide](examples/unified-systems/README.md) ← New for v3.60.0!\n\n## Development\n\n### Git Hooks\n\nThe repository includes Git hooks to run tests locally before commits and pushes. Install them with:\n\n```bash\n./scripts/install-all-hooks.sh\n```\n\nFor more information, see [Git Hooks](doc/development/git-hooks.md).\n\n## Development Status\n\n**Current versions:**\n- **v3**: Production-ready, Python SDK v3.65.0 parity (final v3 line) ✅\n- **v4**: Python SDK v4.8.1 parity, early adopters 🔶\n\n| Component | v3 Status | v4 Status |\n|-----------|-----------|-----------|\n| Core Infrastructure | ✅ Complete | ✅ Complete |\n| Auth Client | ✅ Complete | ✅ Complete (+ device flow) |\n| Token Storage | ✅ Complete | ⚠️ Not yet |\n| Token Manager | ✅ Complete | ⚠️ Not yet |\n| Groups Client | ✅ Complete | ✅ Complete |\n| Transfer Client | ✅ Complete | ✅ Complete (+ tunnels/streams) |\n| Search Client | ✅ Complete | ✅ Complete |\n| Flows Client | ✅ Complete | ✅ Complete (+ action providers) |\n| Timers Client | ✅ Complete | ✅ Complete |\n| Compute Client | ✅ Complete | ✅ Complete (+ batch) |\n| GCS Package | ❌ N/A | ✅ EXPERIMENTAL |\n| Connection Pooling | ✅ Yes | ⚠️ Not yet |\n| Rate Limiting | ✅ Yes | ⚠️ Not yet |\n| Resource Cleanup | ❌ N/A | ✅ Close() |\n| Test Coverage | ✅ 70%+ | ✅ All services |\n\nSee [DEVELOPMENT_ROADMAP.md](DEVELOPMENT_ROADMAP.md) for development strategy and [CHANGELOG.md](CHANGELOG.md) for release history.\n\n## 🔧 Troubleshooting\n\n### Common Issues\n\n#### Import Path Errors\n```bash\n# ❌ Wrong\nimport \"github.com/scttfrdmn/globus-go-sdk/v3/v3/pkg\"\n\n# ✅ Correct\nimport \"github.com/scttfrdmn/globus-go-sdk/v3/pkg\"\n```\n\n#### \"Access token is required\" (v4)\nv4 requires explicit scopes. Make sure you provide both token and scopes:\n```go\nconfig := \u0026core.Config{\n    AccessToken: \"your-token\",\n    Scopes:      []string{core.Scopes.TransferAll}, // Required in v4!\n}\n```\n\n#### Rate Limiting / 429 Errors\nv3 has built-in rate limiting. For v4, this is not yet implemented:\n- **v3**: Automatically handles 429 responses with backoff\n- **v4**: You'll need to implement your own retry logic (for now)\n\n#### Token Expiration\n- **v3**: Use `tokens.NewManager()` for automatic token refresh\n- **v4**: Manual token management required (auto-refresh not yet implemented)\n\n#### Connection Leaks (v4)\nAlways call `Close()` in v4 to prevent connection leaks:\n```go\nclient, err := transfer.NewClient(ctx, config)\nif err != nil {\n    return err\n}\ndefer client.Close() // Important!\n```\n\n### Getting Help\n\n1. **Check the documentation**: [https://scttfrdmn.github.io/globus-go-sdk/](https://scttfrdmn.github.io/globus-go-sdk/)\n2. **Search existing issues**: [GitHub Issues](https://github.com/scttfrdmn/globus-go-sdk/issues)\n3. **Check examples**: See the `examples/` directory\n4. **Ask questions**: Open a GitHub issue with the \"question\" label\n\n### FAQ\n\n**Q: Should I use v3 or v4?**\nA: Use v3 for production. It's feature-complete and battle-tested.\n\n**Q: When will v4 be production-ready?**\nA: When users request the missing features. See [DEVELOPMENT_ROADMAP.md](DEVELOPMENT_ROADMAP.md).\n\n**Q: Can I use both v3 and v4 in the same project?**\nA: Technically yes (different import paths), but not recommended. Pick one.\n\n**Q: How do I get an access token?**\nA: See the [Authentication Guide](https://scttfrdmn.github.io/globus-go-sdk/getting-started/authentication/)\n\n**Q: Is this officially supported by Globus?**\nA: No, this is a community project. See the disclaimer at the top of this README.\n\n## Alignment with Official SDKs\n\nThis SDK follows the patterns established by the official Globus SDKs for [Python](https://github.com/globus/globus-sdk-python) and [JavaScript](https://github.com/globus/globus-sdk-javascript).\n\n- **v3** aligns with Python SDK v3.65.0 (final v3 line)\n- **v4** aligns with Python SDK v4.8.1; parity tracked in [.github/upstream-versions.json](.github/upstream-versions.json)\n\nSee [ALIGNMENT.md](ALIGNMENT.md) for details and [CHANGELOG.md](CHANGELOG.md) for release history.\n\n## Contributing\n\nContributions are welcome! Please see the project's GitHub repository for more information.\n\n## License\n\nApache 2.0\n\n## Resources\n\n- [Globus API Documentation](https://docs.globus.org/api/)\n- [Python SDK Documentation](https://globus-sdk-python.readthedocs.io/)\n- [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments)\n- [Effective Go](https://golang.org/doc/effective_go)\n- [SDK Development Roadmap](DEVELOPMENT_ROADMAP.md)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscttfrdmn%2Fglobus-go-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscttfrdmn%2Fglobus-go-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscttfrdmn%2Fglobus-go-sdk/lists"}