{"id":31914744,"url":"https://github.com/graphiant-inc/graphiant-sdk-go","last_synced_at":"2026-05-01T23:01:42.541Z","repository":{"id":296476368,"uuid":"993510898","full_name":"Graphiant-Inc/graphiant-sdk-go","owner":"Graphiant-Inc","description":"Go SDK for Graphiant NaaS","archived":false,"fork":false,"pushed_at":"2026-05-01T21:13:23.000Z","size":8343,"stargazers_count":1,"open_issues_count":0,"forks_count":4,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-01T22:19:18.422Z","etag":null,"topics":["backbone","cloud","go","golang","naas","network","networking","restapi","sdk","sdwan"],"latest_commit_sha":null,"homepage":"https://www.graphiant.com","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Graphiant-Inc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","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-05-30T23:25:22.000Z","updated_at":"2026-05-01T20:53:06.000Z","dependencies_parsed_at":"2025-05-31T11:05:50.245Z","dependency_job_id":"22bf453c-ccc8-4de2-bd3b-a4203afda779","html_url":"https://github.com/Graphiant-Inc/graphiant-sdk-go","commit_stats":null,"previous_names":["graphiant-inc/graphiant-sdk-go"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/Graphiant-Inc/graphiant-sdk-go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Graphiant-Inc%2Fgraphiant-sdk-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Graphiant-Inc%2Fgraphiant-sdk-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Graphiant-Inc%2Fgraphiant-sdk-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Graphiant-Inc%2Fgraphiant-sdk-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Graphiant-Inc","download_url":"https://codeload.github.com/Graphiant-Inc/graphiant-sdk-go/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Graphiant-Inc%2Fgraphiant-sdk-go/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32515838,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"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":["backbone","cloud","go","golang","naas","network","networking","restapi","sdk","sdwan"],"created_at":"2025-10-13T19:27:58.842Z","updated_at":"2026-05-01T23:01:42.517Z","avatar_url":"https://github.com/Graphiant-Inc.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Graphiant SDK Go\n\n[![Go Version](https://img.shields.io/badge/go-1.21+-blue.svg)](https://golang.org/dl/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Go Reference](https://pkg.go.dev/badge/github.com/Graphiant-Inc/graphiant-sdk-go.svg)](https://pkg.go.dev/github.com/Graphiant-Inc/graphiant-sdk-go)\n[![Go Report Card](https://goreportcard.com/badge/github.com/Graphiant-Inc/graphiant-sdk-go)](https://goreportcard.com/report/github.com/Graphiant-Inc/graphiant-sdk-go)\n[![Documentation](https://img.shields.io/badge/docs-latest-brightgreen.svg)](https://docs.graphiant.com/docs/graphiant-sdk-go)\n[![CI/CD](https://github.com/Graphiant-Inc/graphiant-sdk-go/actions/workflows/test.yml/badge.svg)](https://github.com/Graphiant-Inc/graphiant-sdk-go/actions)\n\nA Go client for [Graphiant Network-as-a-Service (NaaS)](https://www.graphiant.com), generated from the Graphiant OpenAPI specification.\n\nMore product context: [Graphiant Docs](https://docs.graphiant.com).\n\n## Table of contents\n\n| Section | Contents |\n|--------|----------|\n| [Documentation \u0026 links](#documentation--links) | Official guides, API reference, pkg.go.dev |\n| [Features](#features) | What the SDK provides |\n| [Quick start](#quick-start) | Install, password login, and **`GRAPHIANT_ACCESS_TOKEN`** |\n| [Advanced usage](#advanced-usage) | Patterns and error handling |\n| [Convenient wrapper functions](#convenient-wrapper-functions) | `api_custom.go` helpers |\n| [Development](#development) | Build, test, code generation |\n| [API reference (overview)](#api-reference) | Core types and common endpoints |\n| [Security](#security) | Auth and environment variables |\n| [Contributing](#contributing) | PR workflow |\n| [License](#license) | MIT |\n| [Version history](#version-history) | Changelog |\n| [Support](#support) | Links and contact |\n| [Related projects](#related-projects) | Other SDKs |\n\n## Documentation \u0026 links\n\n| Resource | Link |\n|----------|------|\n| **SDK guide** | [Graphiant SDK Go](https://docs.graphiant.com/docs/graphiant-sdk-go) |\n| **Automation** | [Graphiant Automation](https://docs.graphiant.com/docs/automation) |\n| **REST API** | [Graphiant Portal REST API](https://docs.graphiant.com/docs/graphiant-portal-rest-api) |\n| **Method index (repo)** | [DefaultAPI.md](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/docs/DefaultAPI.md) |\n| **OpenAPI bundle (this build)** | [`graphiant_api_docs_v26.4.0.json`](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/graphiant_api_docs_v26.4.0.json) — source for generated paths and models |\n| **Package** | [pkg.go.dev](https://pkg.go.dev/github.com/Graphiant-Inc/graphiant-sdk-go) |\n| **Changelog** | [CHANGELOG.md](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/CHANGELOG.md) |\n\n## Features\n\n- **Full REST coverage** — Generated client for Graphiant API endpoints.\n- **Typed models** — OpenAPI-generated structs and accessors.\n- **Bearer auth** — Username/password login or a token you supply.\n- **Environment variables** — Same **`GRAPHIANT_ACCESS_TOKEN`** / **`GRAPHIANT_USERNAME`** + **`GRAPHIANT_PASSWORD`** as [graphiant-sdk-python](https://github.com/Graphiant-Inc/graphiant-sdk-python): prefer token from env, else **`POST /v1/auth/login`** via **`AuthorizationBearerFromEnvOrLogin`** (also **`AuthorizationBearerFromEnv`**, **`AccessTokenFromEnv`**, **`ConfigureHostFromEnv`**) in `auth_env.go`.\n- **Helpers** — Optional wrappers in `api_custom.go` (e.g. device config polling).\n\n## Quick start\n\n### 1. Install\n\n```bash\ngo get github.com/Graphiant-Inc/graphiant-sdk-go\n```\n\n### 2. Basic usage\n\nThe default API base URL is `https://api.graphiant.com`. Use that host (not the portal URL) for `Configuration.Host`.\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/Graphiant-Inc/graphiant-sdk-go\"\n)\n\nfunc main() {\n\tconfig := graphiant_sdk.NewConfiguration()\n\tconfig.Host = \"https://api.graphiant.com\" // or your tenant API host\n\t\n\t// Create API client\n\tclient := graphiant_sdk.NewAPIClient(config)\n\t\n\t// Authentication request\n\tauthReq := graphiant_sdk.NewV1AuthLoginPostRequestWithDefaults()\n\tauthReq.SetUsername(\"your-username\")\n\tauthReq.SetPassword(\"your-password\")\n\t\n\t// Get authentication token\n\t_, httpRes, err := client.DefaultAPI.\n\t\tV1AuthLoginPost(context.Background()).\n\t\tV1AuthLoginPostRequest(*authReq).\n\t\tExecute()\n\t\n\tif err != nil {\n\t\tlog.Fatalf(\"Authentication failed: %v\", err)\n\t}\n\tdefer httpRes.Body.Close()\n\t\n\t// Parse authentication response\n\tvar authResult struct {\n\t\tAuth        bool   `json:\"auth\"`\n\t\tAccountType string `json:\"accountType\"`\n\t\tToken       string `json:\"token\"`\n\t}\n\t\n\tif err := json.NewDecoder(httpRes.Body).Decode(\u0026authResult); err != nil {\n\t\tlog.Fatalf(\"Failed to decode auth response: %v\", err)\n\t}\n\t\n\tif !authResult.Auth {\n\t\tlog.Fatal(\"Authentication failed\")\n\t}\n\t\n\tbearerToken := \"Bearer \" + authResult.Token\n\t\n\t// Get edge devices summary\n\tresp, _, err := client.DefaultAPI.\n\t\tV1EdgesSummaryGet(context.Background()).\n\t\tAuthorization(bearerToken).\n\t\tExecute()\n\t\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get edge summary: %v\", err)\n\t}\n\t\n\t// Print edge devices\n\tedges := resp.GetEdgesSummary()\n\tfmt.Printf(\"Found %d edge devices:\\n\", len(edges))\n\tfor _, edge := range edges {\n\t\tfmt.Printf(\"- Device ID: %d, Hostname: %s, Status: %s\\n\",\n\t\t\tedge.GetDeviceId(), edge.GetHostname(), edge.GetStatus())\n\t}\n}\n```\n\n### 3. Token or username/password (same pattern as Python SDK)\n\n1. If **`GRAPHIANT_ACCESS_TOKEN`** is set (e.g. after **`graphiant login`** and **`source ~/.graphiant/env.sh`**), that raw JWT is used—no login call.\n2. If the token is **not** set, **`AuthorizationBearerFromEnvOrLogin`** uses **`GRAPHIANT_USERNAME`** and **`GRAPHIANT_PASSWORD`** with **`POST /v1/auth/login`**.\n\nOptionally set **`GRAPHIANT_API_HOST`** (or **`GRAPHIANT_HOST`**) and call **`ConfigureHostFromEnv(config)`** after **`NewConfiguration()`**.\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\t\"github.com/Graphiant-Inc/graphiant-sdk-go\"\n)\n\nfunc main() {\n\tcfg := graphiant_sdk.NewConfiguration()\n\tgraphiant_sdk.ConfigureHostFromEnv(cfg)\n\tclient := graphiant_sdk.NewAPIClient(cfg)\n\n\tauthz, err := graphiant_sdk.AuthorizationBearerFromEnvOrLogin(context.Background(), client)\n\tif err != nil {\n\t\tlog.Fatalf(\"auth: %v\", err)\n\t}\n\n\tresp, _, err := client.DefaultAPI.\n\t\tV1EdgesSummaryGet(context.Background()).\n\t\tAuthorization(authz).\n\t\tExecute()\n\tif err != nil {\n\t\tlog.Fatalf(\"request failed: %v\", err)\n\t}\n\tedges := resp.GetEdgesSummary()\n\tfmt.Fprintf(os.Stdout, \"devices: %d\\n\", len(edges))\n}\n```\n\n```bash\n# Option A — bearer only (same as Python)\nexport GRAPHIANT_ACCESS_TOKEN=\"your_jwt\"\n\n# Option B — password login when token is unset\nexport GRAPHIANT_USERNAME=\"your_username\"\nexport GRAPHIANT_PASSWORD=\"your_password\"\n```\n\nDo **not** set a second bearer via context API keys when using `Authorization(...)` on the request, or some gateways may reject duplicate `Authorization` headers.\n\n## 🔧 Advanced Usage\n\n### Device Configuration Management\n\n```go\n// Verify device portal status before configuration\nfunc verifyDevicePortalStatus(client *graphiant_sdk.APIClient, bearerToken string, deviceID int64) error {\n\tresp, _, err := client.DefaultAPI.\n\t\tV1EdgesSummaryGet(context.Background()).\n\t\tAuthorization(bearerToken).\n\t\tExecute()\n\t\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get edges summary: %v\", err)\n\t}\n\t\n\tfor _, edge := range resp.GetEdgesSummary() {\n\t\tif edge.GetDeviceId() == deviceID {\n\t\t\tif edge.GetPortalStatus() == \"Ready\" \u0026\u0026 edge.GetTtConnCount() == 2 {\n\t\t\t\treturn nil\n\t\t\t} else {\n\t\t\t\treturn fmt.Errorf(\"device %d not ready. Status: %s, TT Connections: %d\",\n\t\t\t\t\tdeviceID, edge.GetPortalStatus(), edge.GetTtConnCount())\n\t\t\t}\n\t\t}\n\t}\n\treturn fmt.Errorf(\"device %d not found\", deviceID)\n}\n\n// Configure device interfaces\nfunc configureDeviceInterfaces(client *graphiant_sdk.APIClient, bearerToken string, deviceID int64) error {\n\t// Define circuits\n\tcircuits := map[string]graphiant_sdk.ManaV2CircuitConfig{\n\t\t\"c-gigabitethernet5-0-0\": {\n\t\t\tName:              graphiant_sdk.PtrString(\"c-gigabitethernet5-0-0\"),\n\t\t\tDescription:       graphiant_sdk.PtrString(\"c-gigabitethernet5-0-0\"),\n\t\t\tLinkUpSpeedMbps:   graphiant_sdk.PtrInt32(50),\n\t\t\tLinkDownSpeedMbps: graphiant_sdk.PtrInt32(100),\n\t\t\tConnectionType:    graphiant_sdk.PtrString(\"internet_dia\"),\n\t\t\tLabel:             graphiant_sdk.PtrString(\"internet_dia_4\"),\n\t\t\tQosProfile:        graphiant_sdk.PtrString(\"gold25\"),\n\t\t\tQosProfileType:    graphiant_sdk.PtrString(\"balanced\"),\n\t\t\tDiaEnabled:        graphiant_sdk.PtrBool(false),\n\t\t\tLastResort:        graphiant_sdk.PtrBool(false),\n\t\t},\n\t}\n\t\n\t// Define interfaces\n\tinterfaces := map[string]graphiant_sdk.ManaV2NullableInterfaceConfig{\n\t\t\"GigabitEthernet5/0/0\": {\n\t\t\tInterface: \u0026graphiant_sdk.ManaV2InterfaceConfig{\n\t\t\t\tAdminStatus:       graphiant_sdk.PtrBool(true),\n\t\t\t\tMaxTransmissionUnit: graphiant_sdk.PtrInt32(1500),\n\t\t\t\tCircuit:           graphiant_sdk.PtrString(\"c-gigabitethernet5-0-0\"),\n\t\t\t\tDescription:       graphiant_sdk.PtrString(\"wan_1\"),\n\t\t\t\tAlias:             graphiant_sdk.PtrString(\"primary_wan\"),\n\t\t\t\tIpv4: \u0026graphiant_sdk.ManaV2InterfaceIpConfig{\n\t\t\t\t\tDhcp: \u0026graphiant_sdk.ManaV2InterfaceDhcpConfig{\n\t\t\t\t\t\tDhcpClient: graphiant_sdk.PtrBool(true),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tIpv6: \u0026graphiant_sdk.ManaV2InterfaceIpConfig{\n\t\t\t\t\tDhcp: \u0026graphiant_sdk.ManaV2InterfaceDhcpConfig{\n\t\t\t\t\t\tDhcpClient: graphiant_sdk.PtrBool(true),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t\n\t// Create configuration request\n\tconfigRequest := graphiant_sdk.NewV1DevicesDeviceIdConfigPutRequest()\n\tconfigRequest.Edge = graphiant_sdk.NewManaV2EdgeDeviceConfig()\n\tconfigRequest.Edge.SetCircuits(circuits)\n\tconfigRequest.Edge.SetInterfaces(interfaces)\n\t\n\t// Verify device is ready\n\tif err := verifyDevicePortalStatus(client, bearerToken, deviceID); err != nil {\n\t\treturn fmt.Errorf(\"device not ready: %v\", err)\n\t}\n\t\n\t// Push configuration\n\t_, _, err := client.DefaultAPI.\n\t\tV1DevicesDeviceIdConfigPut(context.Background(), deviceID).\n\t\tAuthorization(bearerToken).\n\t\tV1DevicesDeviceIdConfigPutRequest(*configRequest).\n\t\tExecute()\n\t\n\tif err != nil {\n\t\treturn fmt.Errorf(\"configuration failed: %v\", err)\n\t}\n\t\n\tfmt.Printf(\"Configuration job submitted for device %d\\n\", deviceID)\n\treturn nil\n}\n```\n\n### BGP Monitoring\n\n```go\nfunc getBgpMonitoring(client *graphiant_sdk.APIClient, bearerToken string) error {\n\t// Create BGP monitoring request\n\tbgpReq := graphiant_sdk.NewV2MonitoringBgpPostRequest()\n\t\n\t// Configure selectors\n\tselectors := []graphiant_sdk.V2MonitoringBgpPostRequestSelectorsInner{\n\t\t{\n\t\t\tType:  graphiant_sdk.PtrString(\"enterprise\"),\n\t\t\tValue: graphiant_sdk.PtrString(\"your-enterprise-id\"),\n\t\t},\n\t}\n\tbgpReq.SetSelectors(selectors)\n\t\n\t// Get BGP monitoring data\n\tbgpResp, _, err := client.DefaultAPI.\n\t\tV2MonitoringBgpPost(context.Background()).\n\t\tAuthorization(bearerToken).\n\t\tV2MonitoringBgpPostRequest(*bgpReq).\n\t\tExecute()\n\t\n\tif err != nil {\n\t\treturn fmt.Errorf(\"BGP monitoring failed: %v\", err)\n\t}\n\t\n\t// Process BGP data\n\tbgpData := bgpResp.GetData()\n\tfmt.Printf(\"Retrieved %d BGP monitoring records\\n\", len(bgpData))\n\t\n\tfor _, record := range bgpData {\n\t\tfmt.Printf(\"BGP Session: %s, State: %s\\n\", \n\t\t\trecord.GetSessionId(), record.GetState())\n\t}\n\t\n\treturn nil\n}\n```\n\n### Circuit Monitoring\n\n```go\nfunc getCircuitMonitoring(client *graphiant_sdk.APIClient, bearerToken string) error {\n\t// Create circuit monitoring request\n\tcircuitReq := graphiant_sdk.NewV2MonitoringCircuitsSummaryPostRequest()\n\t\n\t// Configure selectors\n\tselectors := []graphiant_sdk.V2MonitoringCircuitsSummaryPostRequestSelectorsInner{\n\t\t{\n\t\t\tType:  graphiant_sdk.PtrString(\"enterprise\"),\n\t\t\tValue: graphiant_sdk.PtrString(\"your-enterprise-id\"),\n\t\t},\n\t}\n\tcircuitReq.SetSelectors(selectors)\n\t\n\t// Get circuit monitoring data\n\tcircuitResp, _, err := client.DefaultAPI.\n\t\tV2MonitoringCircuitsSummaryPost(context.Background()).\n\t\tAuthorization(bearerToken).\n\t\tV2MonitoringCircuitsSummaryPostRequest(*circuitReq).\n\t\tExecute()\n\t\n\tif err != nil {\n\t\treturn fmt.Errorf(\"circuit monitoring failed: %v\", err)\n\t}\n\t\n\t// Process circuit data\n\tcircuitData := circuitResp.GetData()\n\tfmt.Printf(\"Retrieved %d circuit monitoring records\\n\", len(circuitData))\n\t\n\tfor _, circuit := range circuitData {\n\t\tfmt.Printf(\"Circuit: %s, Status: %s, Bandwidth: %d Mbps\\n\",\n\t\t\tcircuit.GetCircuitId(), circuit.GetStatus(), circuit.GetBandwidthMbps())\n\t}\n\t\n\treturn nil\n}\n```\n\n### Error Handling\n\n```go\nfunc handleApiErrors(client *graphiant_sdk.APIClient, bearerToken string) {\n\tresp, httpRes, err := client.DefaultAPI.\n\t\tV1EdgesSummaryGet(context.Background()).\n\t\tAuthorization(bearerToken).\n\t\tExecute()\n\t\n\tif err != nil {\n\t\t// Handle different types of errors\n\t\tif apiErr, ok := err.(*graphiant_sdk.GenericOpenAPIError); ok {\n\t\t\tfmt.Printf(\"API Error: %s\\n\", apiErr.Error())\n\t\t\tfmt.Printf(\"Response Body: %s\\n\", string(apiErr.Body()))\n\t\t\t\n\t\t\t// Check HTTP status code\n\t\t\tif httpRes != nil {\n\t\t\t\tswitch httpRes.StatusCode {\n\t\t\t\tcase 401:\n\t\t\t\t\tfmt.Println(\"Unauthorized: Check your credentials\")\n\t\t\t\tcase 403:\n\t\t\t\t\tfmt.Println(\"Forbidden: Check your permissions\")\n\t\t\t\tcase 404:\n\t\t\t\t\tfmt.Println(\"Not Found: Resource doesn't exist\")\n\t\t\t\tcase 500:\n\t\t\t\t\tfmt.Println(\"Server Error: Try again later\")\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfmt.Printf(\"Unexpected error: %v\\n\", err)\n\t\t}\n\t\treturn\n\t}\n\tdefer httpRes.Body.Close()\n\t\n\t// Process successful response\n\tedges := resp.GetEdgesSummary()\n\tfmt.Printf(\"Successfully retrieved %d edges\\n\", len(edges))\n}\n```\n\n## 🎯 Convenient Wrapper Functions\n\nThe SDK includes high-level wrapper functions in [api_custom.go](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/api_custom.go) that simplify common operations:\n\n### Allow Device Configuration only when the device is Ready\n\n```go\nimport \"github.com/Graphiant-Inc/graphiant-sdk-go\"\n\n// Poll device status and execute configuration when ready\nfunc configureDeviceWhenReady(deviceID int64, config graphiant_sdk.V1DevicesDeviceIdConfigPutRequest) *http.Response {\n    config := graphiant_sdk.NewConfiguration()\n    client := graphiant_sdk.NewAPIClient(config)\n    \n    // Get authentication token\n    apiClient, token := getAuthToken() // Your auth function\n    \n    // Poll device status every 30 seconds for up to 10 attempts\n    // Execute configuration when device becomes ready\n    return graphiant_sdk.PollAndPutDeviceConfig(apiClient, token, deviceID, config)\n}\n```\n\n### Available Wrapper Functions\n| `PollAndPutDeviceConfig(apiClient, token, deviceID, config)` | Poll device status and execute config when ready |\n\n## 🛠️ Development\n\n### Prerequisites\n\n- Go 1.21+ (1.23 recommended)\n- Git\n- OpenAPI Generator (for code generation)\n\n### CI/CD Workflows\n\nThis repository uses GitHub Actions for continuous integration and deployment:\n\n- **Linting** ([lint.yml](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/.github/workflows/lint.yml)): Runs golangci-lint, gofmt, and go vet on pull requests and pushes\n- **Testing** ([test.yml](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/.github/workflows/test.yml)): Runs `go test` with race detection and coverage across Go 1.21, 1.22, and 1.23\n- **Building** ([build.yml](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/.github/workflows/build.yml)): Builds and verifies the Go module\n- **Releasing** ([release.yml](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/.github/workflows/release.yml)): Creates git tags and GitHub releases (manual trigger, admin-only)\n\nSee [.github/workflows/README.md](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/.github/workflows/README.md) for detailed workflow documentation.\n\n### Building from Source\n\n```bash\n# Clone repository\ngit clone https://github.com/Graphiant-Inc/graphiant-sdk-go\ncd graphiant-sdk-go\n\n# Install dependencies\ngo mod tidy\n\n# Build the project\ngo build ./...\n\n# Run tests\ngo get github.com/stretchr/testify/assert\ngo test ./...\n```\n\n### Code Generation\n\nTo regenerate the SDK from the latest API specification:\n\n```bash\n# Install OpenAPI Generator\nbrew install openapi-generator  # macOS\n# or download from: https://github.com/OpenAPITools/openapi-generator\n\n# Generate SDK\nopenapi-generator generate \\\n  -i graphiant_api_docs_v26.4.0.json \\\n  -g go \\\n  --git-user-id Graphiant-Inc \\\n  --git-repo-id graphiant-sdk-go \\\n  --package-name graphiant_sdk \\\n  --additional-properties=packageVersion=26.4.0\n```\n\n\u003e **Note:** Download the latest API bundle from the Graphiant portal under **Support Hub** → **Developer Tools**. Set **`packageVersion`** to the SDK release you are publishing (this branch: **26.4.0**). The **`-i`** filename reflects the API doc bundle version (here `graphiant_api_docs_v26.4.0.json`) and may stay the same across patch releases when the spec is unchanged.\n\n### Testing\n\n```bash\n# Install test dependencies\ngo mod download\n\n# Run all tests (tests requiring credentials will skip if not configured)\ngo test ./...\n\n# Run with verbose output\ngo test -v ./...\n\n# Run with race detection\ngo test -race ./...\n\n# Run with coverage\ngo test -coverprofile=coverage.out ./...\ngo tool cover -html=coverage.out\n\n# Run specific test\ngo test -v ./... -run Test_edge_summary\n```\n\n**Environment Variables for Tests:**\n\nTests that require API access will automatically use the following environment variables if set:\n\n```bash\nexport GRAPHIANT_HOST=\"https://api.graphiant.com\"  # Optional: API host (defaults to https://api.graphiant.io)\nexport GRAPHIANT_USERNAME=\"your_username\"           # Required for integration tests\nexport GRAPHIANT_PASSWORD=\"your_password\"          # Required for integration tests\n```\n\n- **`GRAPHIANT_HOST`** (optional): API host URL. If not set, defaults to `https://api.graphiant.io`. Supports formats like `https://api.test.graphiant.io` or `gcs:https://api.test.graphiant.io` (the `gcs:` prefix is automatically removed).\n- **`GRAPHIANT_USERNAME`** (required for integration tests): Your Graphiant API username\n- **`GRAPHIANT_PASSWORD`** (required for integration tests): Your Graphiant API password\n\nTests that require credentials will automatically skip if `GRAPHIANT_USERNAME` or `GRAPHIANT_PASSWORD` are not set, allowing the test suite to run successfully without credentials.\n\n**Note**: The CI/CD pipeline automatically runs tests across multiple Go versions (1.21-1.23) on every pull request and push to main/develop branches. The pipeline reads credentials from GitHub secrets/variables when available.\n\n### Project Structure\n\n```\ngraphiant-sdk-go/\n├── api_default.go              # Main API service\n├── api_custom.go               # Convenient wrapper functions\n├── client.go                   # HTTP client implementation\n├── configuration.go            # Configuration management\n├── model_*.go                  # Generated data models\n├── response.go                 # Response handling\n├── utils.go                    # Utility functions\n├── version.go                  # Version information\n├── test/                       # Test files\n│   ├── sanity_test.go          # Basic functionality tests\n│   ├── api_default_test.go     # API tests\n│   └── version_test.go         # Version tests\n├── docs/                       # Generated documentation\n│   ├── api/                    # API documentation\n│   ├── examples/               # Usage examples\n│   └── *.md                    # Model documentation\n├── go.mod                      # Go module definition\n└── README.md                   # This file\n```\n\n## 📖 API Reference\n\n### Core Classes\n\n- **`Configuration`**: Client configuration with authentication\n- **`APIClient`**: HTTP client for API requests\n- **`DefaultAPI`**: Main API interface with all endpoints\n\n### Key Models\n\n- **`V1AuthLoginPostRequest`**: Authentication request\n- **`V1EdgesSummaryGetResponse`**: Device summary response\n- **`V1DevicesDeviceIdConfigPutRequest`**: Device configuration request\n- **`V2MonitoringBgpPostRequest`**: BGP monitoring request\n- **`V2MonitoringCircuitsSummaryPostRequest`**: Circuit monitoring request\n\n### Common Endpoints\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/v1/auth/login` | POST | Authenticate and get bearer token |\n| `/v1/edges/summary` | GET | Get all device summaries |\n| `/v1/devices/{device_id}` | GET | Get device details |\n| `/v1/devices/{device_id}/config` | PUT | Update device configuration |\n| `/v2/monitoring/bgp` | POST | Get BGP monitoring data |\n| `/v2/monitoring/circuits/summary` | POST | Get circuit monitoring data |\n\n## 🔐 Security\n\n- **Authentication**: Bearer token-based authentication\n- **HTTPS**: All API communications use HTTPS\n- **Credentials**: Store credentials securely using environment variables\n- **Token Management**: Bearer tokens expire and should be refreshed as needed\n\n### Environment Variables\n\n| Variable | Purpose |\n|----------|---------|\n| **`GRAPHIANT_ACCESS_TOKEN`** | Raw bearer JWT (same as Python SDK). Use with **`AuthorizationBearerFromEnv()`** for API calls. Typical source: `graphiant login` then `source ~/.graphiant/env.sh`. |\n| **`GRAPHIANT_API_HOST`** | API base URL (e.g. `https://api.graphiant.com`). Preferred name; use with **`ConfigureHostFromEnv`**. |\n| **`GRAPHIANT_HOST`** | Alternative API base URL for tools/tests; used if **`GRAPHIANT_API_HOST`** is empty. May include a `gcs:` prefix (stripped by **`ConfigureHostFromEnv`**). |\n| **`GRAPHIANT_USERNAME`** / **`GRAPHIANT_PASSWORD`** | Used when **`GRAPHIANT_ACCESS_TOKEN`** is unset: **`AuthorizationBearerFromEnvOrLogin`** calls **`POST /v1/auth/login`**. Also used by integration tests. |\n\n```bash\n# Bearer-only automation (aligned with graphiant-sdk-python)\nexport GRAPHIANT_ACCESS_TOKEN=\"your_jwt\"\nexport GRAPHIANT_API_HOST=\"https://api.graphiant.com\"   # optional\n\n# Password / test flows\nexport GRAPHIANT_USERNAME=\"your_username\"\nexport GRAPHIANT_PASSWORD=\"your_password\"\nexport GRAPHIANT_HOST=\"https://api.graphiant.com\"      # optional; see table above\n```\n\n```go\ntoken := graphiant_sdk.AccessTokenFromEnv()\nauthHeader := graphiant_sdk.AuthorizationBearerFromEnv()\n// Or: authHeader, err := graphiant_sdk.AuthorizationBearerFromEnvOrLogin(ctx, client)\nusername := os.Getenv(\"GRAPHIANT_USERNAME\")\npassword := os.Getenv(\"GRAPHIANT_PASSWORD\")\n```\n\n**Note**: For detailed security policies, vulnerability reporting, and security best practices, see [SECURITY.md](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/SECURITY.md).\n\n## 🤝 Contributing\n\nWe welcome contributions! Please follow these steps:\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Make your changes and ensure they pass local checks:\n   ```bash\n   # Format code\n   gofmt -s -w .\n   \n   # Run linting\n   golangci-lint run\n   \n   # Run static analysis\n   go vet ./...\n   \n   # Run tests\n   go test -v -race ./...\n   ```\n4. Commit your changes with a clear message (`git commit -m 'Add amazing feature'`)\n5. Push to the branch (`git push origin feature/amazing-feature`)\n6. Open a Pull Request\n\n**Note**: All pull requests automatically run CI/CD checks (linting, testing across multiple Go versions). Ensure all checks pass before requesting review.\n\nSee [CONTRIBUTING.md](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/CONTRIBUTING.md) for detailed contribution guidelines.\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/LICENSE) file for details.\n\n## 📋 Version History\n\nFor a complete list of changes, new features, and version history, see [CHANGELOG.md](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/CHANGELOG.md).\n\nThe changelog follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format and includes:\n- All releases from v25.6.1 (initial release) to the latest version\n- Breaking changes and deprecations\n- Bug fixes and security updates\n\n## 🆘 Support\n\n- **Official Documentation**: [Graphiant SDK Go Guide](https://docs.graphiant.com/docs/graphiant-sdk-go) \u003c-\u003e [Graphiant Automation Docs](https://docs.graphiant.com/docs/automation)\n- **API Reference**: [Graphiant SDK Go API Docs](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/docs/DefaultAPI.md) \u003c-\u003e [Graphiant Portal REST API Guide](https://docs.graphiant.com/docs/graphiant-portal-rest-api)\n- **Changelog**: [CHANGELOG.md](https://github.com/Graphiant-Inc/graphiant-sdk-go/blob/main/CHANGELOG.md) - Version history and release notes\n- **Issues**: [GitHub Issues](https://github.com/Graphiant-Inc/graphiant-sdk-go/issues)\n- **Email**: support@graphiant.com\n\n## 🔗 Related Projects\n\n- [Graphiant SDK Python](https://github.com/Graphiant-Inc/graphiant-sdk-python)\n- [Graphiant Playbooks](https://github.com/Graphiant-Inc/graphiant-playbooks)\n\n---\n\n**Made with ❤️ by the Graphiant Team**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraphiant-inc%2Fgraphiant-sdk-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgraphiant-inc%2Fgraphiant-sdk-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraphiant-inc%2Fgraphiant-sdk-go/lists"}