---
title: "Connect with pyTigerGraph"
component: "savanna"
version: "main"
module: "get-started"
html_url: "/savanna/main/get-started/connect-pytigergraph.html"
---

[View as HTML](/savanna/main/get-started/connect-pytigergraph.html)

# Connect with pyTigerGraph

pyTigerGraph connects Python applications to your TigerGraph database, so your code can manage graphs, explore schemas, query graph data, load data, and perform database operations through one client.

This page explains what pyTigerGraph is and gets you from install to a successful call against your Savanna workspace.

## What is pyTigerGraph?

[pyTigerGraph](https://pypi.org/project/pyTigerGraph/) is TigerGraph's Python client. It wraps the REST++ and GSQL APIs: you create a `TigerGraphConnection`, pass the workspace and a database secret, and call methods on that object. Your script is the client. There is no server to install or keep running.

The method reference lives in the [pyTigerGraph documentation](https://www.tigergraph.com/docs/pytigergraph/current/intro/). This page covers the part that is specific to Savanna: which host to use, which credential to pass, and how to confirm the connection.

## What you can do

From your own code, you can:

* **Design and evolve graphs.** Create graphs, read schemas, and change vertex and edge types as the model changes.
* **Read and write graph data.** Fetch vertices and edges, traverse neighbors, and upsert data from the application.
* **Query the graph.** Run an installed query and take the result back into Python. You can also send GSQL when the application authors queries.
* **Load data.** Create and run loading jobs, and read job status from the same connection.
* **Work with vectors.** Manage vector attributes, upsert embeddings, and run similarity search. The optional `gds` extra streams vertices and edges into PyTorch Geometric, DGL, or Pandas. See the [GDS documentation](https://www.tigergraph.com/docs/pytigergraph/current/gds/).

You choose the call. The client sends it to the workspace you configured and returns the result.

## Before you start

* A running Savanna [workspace](../workgroup-workspace/workspaces/workspace.md) with an attached database. If you do not have one yet, [build a graph in the console](first-graph-ui.md) first.
* A database secret for that database. See [Create a database secret](../administration/settings/how2-create-database-secret.md).
* Python and `pip` on the machine that will run the script.
* Your IP on the workgroup allowlist, when the workgroup has one. See [Configure network access](../workgroup-workspace/workgroups/how2-config-network-access.md).

## Install

```bash
pip install pyTigerGraph
```

For an asynchronous service, the package also provides `AsyncTigerGraphConnection` with the same connection arguments. The examples below use the synchronous client.

## Configure your connection

A Savanna connection takes the workspace URL, the graph name, and a database secret.

| Argument | Required | What to use |
| --- | --- | --- |
| `host` | Yes | Your Savanna workspace URL, including `https://`. Open **Workspaces**, select the workspace, and copy its URL. A Savanna host looks like `<https://<workspace-id>.i.tgcloud.io>`. |
| `gsqlSecret` | Yes | A database secret for that workspace's database. See [Create a database secret](../administration/settings/how2-create-database-secret.md). |
| `graphname` | Yes | The graph this connection uses. Create the graph in [Design Schema](../graph-development/design-schema/index.md) if you do not have one yet. |

Savanna serves REST++ and GSQL on HTTPS port `443`. When the host contains `tgcloud`, pyTigerGraph selects that port for you. Leave `restppPort` and `gsPort` at their defaults.

## Connect

Read the three values from environment variables and open the connection:

```python
import os
from pyTigerGraph import TigerGraphConnection

conn = TigerGraphConnection(
    host=os.environ["TG_HOST"],
    graphname=os.environ["TG_GRAPHNAME"],
    gsqlSecret=os.environ["TG_SECRET"],
)

print(conn.echo())
print(conn.getVertexTypes())
```

`echo()` returns a response when the workspace host answers.`getVertexTypes()` returns the vertex type names when the secret can read the graph. A list of names means the connection is working.

> [!NOTE]
> Store the database secret outside your code. It stays valid until you delete or revoke it. The calls below run on the connected database and can change or delete graph data.

## Use common functions

Every example below uses names from your graph. Create the schema, query, or loading job first, read its names back with pyTigerGraph, and pass those names into the next call. These are the common calls. For the complete method list, parameters, and return values, use the [pyTigerGraph documentation](https://www.tigergraph.com/docs/pytigergraph/current/intro/).

### Read the schema

[Build a graph](first-graph-ui.md) or use [Design Schema](../graph-development/design-schema/index.md) before these calls.`getSchema()` returns that schema.`getVertexTypes()` and `getEdgeTypes()` return the type names used by every later example.`getVertexCount()` and `getEdgeCount()` count the types you pass in.

Parameter and return details: [Schema functions](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/schema), [Vertex functions](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/vertex), and [Edge functions](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/edge).

```python
schema = conn.getSchema()
vertex_types = conn.getVertexTypes()
edge_types = conn.getEdgeTypes()

vertex_type = vertex_types[0]
attributes = conn.getVertexAttrs(vertex_type)

print(vertex_type)
print(attributes)
print(conn.getVertexCount(vertex_type))
```

`getVertexAttrs()` returns `(attribute_name, attribute_type)` pairs. Use those attribute names in `select`, `where`, and upsert dictionaries.

### Read vertices and edges

Load data before reading it. See [Load data](../graph-development/load-data/index.md).`getVerticesById()` reads one vertex by the primary ID you loaded.`getVertices()` filters one vertex type by attributes from `getVertexAttrs()`.`getEdges()` reads edges that start at that vertex. The edge type must be one of the names from `getEdgeTypes()`, and its endpoints must match `getEdgeSourceVertexType()` and `getEdgeTargetVertexType()`.

```python
vertex_type = conn.getVertexTypes()[0]
attribute_name = conn.getVertexAttrs(vertex_type)[0][0]

one_vertex = conn.getVerticesById(vertex_type, "YOUR_PRIMARY_ID")

matching_vertices = conn.getVertices(
    vertex_type,
    select=attribute_name,
    where=f'{attribute_name}="YOUR_VALUE"',
)

edge_type = conn.getEdgeTypes()[0]
neighbors = conn.getEdges(
    sourceVertexType=vertex_type,
    sourceVertexId="YOUR_PRIMARY_ID",
    edgeType=edge_type,
)
```

Replace `YOUR_PRIMARY_ID` and `YOUR_VALUE` with a vertex and attribute value that exist in this graph. For a pandas result, use `getVertexDataFrame()` or `getEdgesDataFrame()`. Full signatures: [Vertex functions](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/vertex) and [Edge functions](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/edge).

### Add or update vertices and edges

An upsert creates a record that does not exist and updates one that does. The vertex type, edge type, and attribute names must already exist in the schema from the previous section. Create any missing type in [Design Schema](../graph-development/design-schema/index.md) before calling these methods.

```python
vertex_type = conn.getVertexTypes()[0]
attribute_name = conn.getVertexAttrs(vertex_type)[0][0]

conn.upsertVertex(vertex_type, "YOUR_PRIMARY_ID", {attribute_name: "YOUR_VALUE"})

edge_type = conn.getEdgeTypes()[0]
source_type = conn.getEdgeSourceVertexType(edge_type)
target_type = conn.getEdgeTargetVertexType(edge_type)
# If either call returns a set, choose the endpoint type your vertices use.

conn.upsertEdge(
    sourceVertexType=source_type,
    sourceVertexId="YOUR_SOURCE_ID",
    edgeType=edge_type,
    targetVertexType=target_type,
    targetVertexId="YOUR_TARGET_ID",
    vertexMustExist=True,
)
```

`vertexMustExist=True` writes the edge only when both endpoint vertices already exist.`upsertVertices()`, `upsertEdges()`, `upsertVertexDataFrame()`, and `upsertEdgeDataFrame()` apply the same rules to a batch or a pandas `DataFrame`. Column names must match the attribute names from `getVertexAttrs()` or `getEdgeAttrs()`. See [Vertex functions](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/vertex) and [Edge functions](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/edge).

### Run an installed query

1. Write the query in the [GSQL Editor](../graph-development/gsql-editor/index.md). See [edit and run a query](../graph-development/gsql-editor/how2-edit-gsql-query.md) and the [GSQL query language](https://www.tigergraph.com/docs/gsql-ref/4.3/querying/).
2. Install the query from the Query List. `runInstalledQuery()` can call only an installed query.
3. Read the installed name with `getInstalledQueries()`.
4. Read its parameter names with `getQueryMetadata()`, then pass those names in `params`.

```python
print(conn.getInstalledQueries())
print(conn.getQueryMetadata("YOUR_INSTALLED_QUERY"))

result = conn.runInstalledQuery(
    "YOUR_INSTALLED_QUERY",
    params={"YOUR_PARAMETER": "YOUR_VALUE"},
)
print(result)
```

Copy `YOUR_INSTALLED_QUERY` from `getInstalledQueries()`, and copy `YOUR_PARAMETER` from `getQueryMetadata()`. Argument formats for strings, sets, and vertex parameters are in [Query functions](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/query).

### Run a loading job

1. Define the vertex and edge types in [Design Schema](../graph-development/design-schema/index.md).
2. Create the loading job in [Load data](../graph-development/load-data/index.md), including its file variable (`DEFINE FILENAME`).
3. Confirm the job name with `getLoadingJobs()`. The `fileTag` argument is that file variable, not the local filename.

```python
jobs = conn.getLoadingJobs()
print(jobs)

result = conn.runLoadingJobWithFile(
    filePath="YOUR_LOCAL_FILE.csv",
    fileTag="YOUR_DEFINE_FILENAME",
    jobName="YOUR_LOADING_JOB",
    sep=",",
)
print(result)
```

`runLoadingJobWithData()` accepts the file contents as a string.`runLoadingJobWithDataFrame()` accepts a pandas `DataFrame` whose columns follow the job's mapping.`getLoadingJobStatus()` checks a job run. Remove the header row before loading. A `USING HEADER="true"` clause in the job does not replace that step. Signatures: [Loading job functions](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/loading).

### Run a GSQL statement

Use `gsql()` for a statement that has no dedicated method, such as showing the queries you created in the GSQL Editor. The connection's graph is the default graph. GSQL syntax is in the [GSQL query language](https://www.tigergraph.com/docs/gsql-ref/4.3/querying/), and the method contract is in [GSQL interface](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/gsql).

```python
print(conn.gsql(f"USE GRAPH {conn.graphname} SHOW QUERY ALL"))
```

For application calls, prefer the method that matches the operation: `getSchema()` to read the schema, `runInstalledQuery()` to run an installed query, and `runLoadingJobWithFile()` to run a loading job.

## Troubleshooting

### Invalid URL scheme

`host` needs `http://` or `https://`. For Savanna, use `<https://<workspace-id>.i.tgcloud.io>`. A hostname alone raises `Invalid URL scheme`.

### Authentication failed

Create the secret in Savanna for the same workspace, and pass the full value as `gsqlSecret`. A control-plane API key authenticates the [Savanna REST API](../rest-api/index.md) and will not authenticate this connection. See [Create a database secret](../administration/settings/how2-create-database-secret.md).

### Connection error

Check that:

* The workspace status is active
* `host` is that workspace's URL, including `https://`
* `gsqlSecret` is a database secret for that workspace
* `graphname` matches a graph in that database
* Your IP is on the workgroup allowlist when one is enabled

See [About workspaces](../workgroup-workspace/workspaces/workspace.md) and [Configure network access](../workgroup-workspace/workgroups/how2-config-network-access.md).

## Feedback and contributions

Found a bug or unexpected behavior in the client? Open an issue in the [pyTigerGraph GitHub repository](https://github.com/tigergraph/pyTigerGraph). If you have a fix, submit a pull request.

## Related

* Complete method reference: [pyTigerGraph documentation](https://www.tigergraph.com/docs/pytigergraph/current/intro/)  
   * [Connection](https://www.tigergraph.com/docs/pytigergraph/current/getting-started/connection)  
   * [Schema](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/schema), [vertices](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/vertex), and [edges](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/edge)  
   * [Queries](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/query), [loading jobs](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/loading), and [GSQL](https://www.tigergraph.com/docs/pytigergraph/current/core-functions/gsql)
* Work with the same database from an AI tool: [Connect AI tools with MCP](connect-agent-mcp.md)
* Generated curl, Python, and JavaScript in the console: [Connect via APIs](../workgroup-workspace/workspaces/connect-via-api.md)
* The endpoints the client calls: [Data-plane APIs](../rest-api/data-plane-apis.md)
* Load data in the console: [Load data](../graph-development/load-data/index.md)
* Write queries in the console: [GSQL Editor](../graph-development/gsql-editor/index.md)
