---
name: network-connectivity
description: "Google Cloud Network Connectivity Python client for Network Connectivity Center hubs, spokes, route tables, and related control-plane APIs"
metadata:
  languages: "python"
  versions: "2.13.0"
  revision: 1
  updated-on: "2026-03-13"
  source: maintainer
  tags: "google,gcp,google-cloud,network-connectivity,networking,ncc,python"
---

# google-cloud-network-connectivity Python Package Guide

## What This Package Is

`google-cloud-network-connectivity` is the official Google Cloud Python client for the Network Connectivity API. For Network Connectivity Center automation, the main entry point is `google.cloud.networkconnectivity_v1.HubServiceClient`, which manages hubs, spokes, route tables, and related long-running operations.

The package also includes other v1 services such as Internal Range, Policy Based Routing, Data Transfer, and Cross Network Automation. This guide stays focused on the hub-and-spoke workflows that Google documents most directly for Network Connectivity Center.

## Version Note

This guide covers package version `2.13.0`, which PyPI lists as the latest release as of `2026-03-13`.

Google's docs are slightly uneven right now:

- the PyPI page lists `2.13.0`
- the reference docs `latest` selector and changelog selector include `2.13.0`
- some individual class pages still render `2.11.0` in the page heading

The examples below use the current GA `networkconnectivity_v1` surface and method signatures from the live reference docs.

## Install

```bash
python -m pip install "google-cloud-network-connectivity==2.13.0"
```

PyPI currently declares `Requires: Python >=3.7`.

## Authentication And Prerequisites

Before using the client:

1. Choose the Google Cloud project that owns the hub or spoke resources.
2. Enable billing for that project.
3. Enable the Network Connectivity API.
4. Configure Application Default Credentials (ADC).

Enable the API:

```bash
gcloud services enable networkconnectivity.googleapis.com
```

Local development with user ADC:

```bash
gcloud auth application-default login
export GOOGLE_CLOUD_PROJECT="your-project-id"
```

Service account key fallback:

```bash
export GOOGLE_APPLICATION_CREDENTIALS="/absolute/path/service-account.json"
export GOOGLE_CLOUD_PROJECT="your-project-id"
```

Google recommends user ADC or attached service accounts first. Use a downloaded service account key only if you cannot use those safer options.

## Client Initialization

Default client using ADC:

```python
import os

from google.cloud import networkconnectivity_v1

PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"]

client = networkconnectivity_v1.HubServiceClient()
```

Explicit service account file:

```python
from google.cloud import networkconnectivity_v1

client = networkconnectivity_v1.HubServiceClient.from_service_account_file(
    "/absolute/path/service-account.json"
)
```

Custom endpoint override:

```python
import os

from google.api_core.client_options import ClientOptions
from google.cloud import networkconnectivity_v1

client = networkconnectivity_v1.HubServiceClient(
    client_options=ClientOptions(api_endpoint=os.environ["GOOGLE_API_ENDPOINT"])
)
```

The generated client accepts `client_options.api_endpoint`, and Google's autogenerated snippets note that some deployments may require specifying regional endpoints explicitly.

## Resource Naming

Use fully qualified resource names:

- hub parent: `projects/{project_id}/locations/global`
- hub name: `projects/{project_id}/locations/global/hubs/{hub_id}`
- spoke parent for VPC spokes: `projects/{project_id}/locations/global`
- spoke parent for hybrid spokes: `projects/{project_id}/locations/{region}`
- spoke name: `projects/{project_id}/locations/{location}/spokes/{spoke_id}`

Helper methods on `HubServiceClient` are useful for names you already know:

```python
from google.cloud import networkconnectivity_v1

client = networkconnectivity_v1.HubServiceClient()

hub_name = client.hub_path("my-project", "my-hub")
spoke_name = client.spoke_path("my-project", "global", "my-vpc-spoke")
global_parent = client.common_location_path("my-project", "global")
```

For a VPC spoke, the linked network is identified by a network URI such as `projects/my-project/global/networks/my-network`.

## Core Usage

### List hubs in a project

```python
from google.cloud import networkconnectivity_v1

def list_hubs(project_id: str) -> list[networkconnectivity_v1.Hub]:
    client = networkconnectivity_v1.HubServiceClient()
    parent = client.common_location_path(project_id, "global")
    return list(client.list_hubs(parent=parent))

for hub in list_hubs("my-project"):
    print(hub.name, hub.state)
```

### Create a hub

`create_hub()` is a long-running operation. Wait for `.result()` before assuming the hub exists.

```python
from google.cloud import networkconnectivity_v1

def create_hub(project_id: str, hub_id: str) -> networkconnectivity_v1.Hub:
    client = networkconnectivity_v1.HubServiceClient()
    parent = client.common_location_path(project_id, "global")

    operation = client.create_hub(
        parent=parent,
        hub_id=hub_id,
        hub=networkconnectivity_v1.Hub(
            description="Shared connectivity hub",
            labels={"env": "dev"},
        ),
    )
    return operation.result(timeout=300)

hub = create_hub("my-project", "my-hub")
print(hub.name)
```

### Get and update a hub

`update_hub()` only documents updates to the hub description and labels. Pass an explicit field mask.

```python
from google.cloud import networkconnectivity_v1
from google.protobuf.field_mask_pb2 import FieldMask

client = networkconnectivity_v1.HubServiceClient()
hub_name = client.hub_path("my-project", "my-hub")

hub = client.get_hub(name=hub_name)
print(hub.description)

operation = client.update_hub(
    hub=networkconnectivity_v1.Hub(
        name=hub_name,
        description="Production connectivity hub",
        labels={"env": "prod", "team": "networking"},
    ),
    update_mask=FieldMask(paths=["description", "labels"]),
)

updated_hub = operation.result(timeout=300)
print(updated_hub.labels)
```

### Create a VPC spoke

VPC spokes are global. A spoke must reference a hub and set exactly one linked backing resource. For a VPC spoke, that backing resource is `linked_vpc_network`.

```python
from google.cloud import networkconnectivity_v1

def create_vpc_spoke(
    spoke_project_id: str,
    hub_project_id: str,
    hub_id: str,
    spoke_id: str,
    network_name: str,
) -> networkconnectivity_v1.Spoke:
    client = networkconnectivity_v1.HubServiceClient()
    parent = client.common_location_path(spoke_project_id, "global")
    hub_name = client.hub_path(hub_project_id, hub_id)

    operation = client.create_spoke(
        parent=parent,
        spoke_id=spoke_id,
        spoke=networkconnectivity_v1.Spoke(
            hub=hub_name,
            description="Attach a VPC network to the hub",
            linked_vpc_network=networkconnectivity_v1.LinkedVpcNetwork(
                uri=f"projects/{spoke_project_id}/global/networks/{network_name}"
            ),
        ),
    )
    return operation.result(timeout=300)

spoke = create_vpc_spoke(
    spoke_project_id="my-project",
    hub_project_id="my-project",
    hub_id="my-hub",
    spoke_id="my-vpc-spoke",
    network_name="prod-network",
)
print(spoke.name, spoke.state)
```

### List and inspect spokes

For VPC spokes, list under `global`. For regional spoke types such as VPN, VLAN attachment, or router appliance spokes, list under the resource's region.

```python
from google.cloud import networkconnectivity_v1

client = networkconnectivity_v1.HubServiceClient()

for spoke in client.list_spokes(
    parent=client.common_location_path("my-project", "global")
):
    print(spoke.name, spoke.spoke_type, spoke.state)

spoke_name = client.spoke_path("my-project", "global", "my-vpc-spoke")
spoke = client.get_spoke(name=spoke_name)
print(spoke.hub)
print(spoke.linked_vpc_network.uri)
```

### List all spokes attached to a hub

Use `list_hub_spokes()` when you need the hub-centric view across projects, including spokes that were proposed but not yet accepted.

```python
from google.cloud import networkconnectivity_v1

client = networkconnectivity_v1.HubServiceClient()
hub_name = client.hub_path("hub-project", "shared-hub")

for item in client.list_hub_spokes(name=hub_name):
    print(item)
```

### Accept a proposed spoke from another project

When the spoke project and the hub project differ, the hub administrator must accept the proposal before the spoke becomes active.

```python
from google.cloud import networkconnectivity_v1

client = networkconnectivity_v1.HubServiceClient()

hub_name = client.hub_path("hub-project", "shared-hub")
spoke_uri = client.spoke_path("spoke-project", "global", "proposed-vpc-spoke")

operation = client.accept_hub_spoke(
    name=hub_name,
    spoke_uri=spoke_uri,
)

response = operation.result(timeout=300)
print(response)
```

### Delete a spoke and hub

Deletes are also long-running operations.

```python
from google.cloud import networkconnectivity_v1

client = networkconnectivity_v1.HubServiceClient()

spoke_name = client.spoke_path("my-project", "global", "my-vpc-spoke")
client.delete_spoke(name=spoke_name).result(timeout=300)

hub_name = client.hub_path("my-project", "my-hub")
client.delete_hub(name=hub_name).result(timeout=300)
```

## Important Pitfalls

- Hubs are global resources. Product docs also call out that VPC spokes are global, while hybrid spokes must be created in the same region as the underlying VPN tunnel, VLAN attachment, or router appliance resource.
- `create_spoke()` requires exactly one linked backing resource. The current client docs explicitly list `linked_vpn_tunnels`, `linked_interconnect_attachments`, `linked_router_appliance_instances`, or `linked_vpc_network`.
- Do not ignore the operation objects returned by create, update, accept, reject, and delete methods. Call `.result()` and set a timeout that matches your environment.
- Use `update_mask` for updates. The hub update method is documented for description and label changes; omitting the mask can overwrite more than you intend.
- Cross-project VPC spoke workflows are not fully automatic. A proposed spoke can exist before the hub administrator accepts it, so `list_hub_spokes()` and `accept_hub_spoke()` matter in real automation.
- The docs site is not perfectly version-aligned for this package right now. If you depend on a field that looks new, verify it against the installed wheel and the current reference page for that class or method.
