Skip to content
  •  
  •  
  •  
30 changes: 30 additions & 0 deletions snippets/sdk/python-sdk-2-quickstart.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
```python
from metadata.sdk import Tables, configure
from metadata.generated.schema.api.data.createTable import CreateTableRequest
from metadata.generated.schema.entity.data.table import Column, DataType

# The host must end with /api
configure(host="http://localhost:8585/api", jwt_token="your-jwt-token")

# Create
table = Tables.create(
CreateTableRequest(
name="customers",
databaseSchema="mysql-prod.analytics.public",
columns=[Column(name="id", dataType=DataType.BIGINT)],
)
)

print(table.fullyQualifiedName.root)

# Update
table.description = "Customer master table"
table = Tables.update(table)

# Delete
Tables.delete(table.id)
```

Fields such as `name`, `id`, and `fullyQualifiedName` are wrapper objects. Use `.root` to get the plain value, for example `table.fullyQualifiedName.root`.

Call `configure()` with no arguments to read `OPENMETADATA_HOST` and `OPENMETADATA_JWT_TOKEN` from your environment.
37 changes: 37 additions & 0 deletions snippets/sdk/python-sdk-choice.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
## Which Python SDK Should I Use?

The `openmetadata-ingestion` package contains two Python clients. Both talk to the same OpenMetadata API.

| | Original client | SDK 2.0 |
|---|---|---|
| Import | `metadata.ingestion.ometa.ometa_api.OpenMetadata` | `metadata.sdk` |
| Setup | Build an `OpenMetadataConnection` and pass it to `OpenMetadata(...)` | Call `configure(host=..., jwt_token=...)` once |
| Style | Generic methods that take an entity type, such as `metadata.get_by_name(entity=Table, fqn=...)` | One class per entity, such as `Tables.retrieve_by_name(fqn)` |
| Available since | Every release | OpenMetadata 1.10.0 |

For new scripts and jobs, use SDK 2.0. It needs less setup and reads more simply. Use the original client when you need an operation that SDK 2.0 doesn't offer yet, or when you maintain existing code that already uses it.

### Using Both Clients in One Script

Both ship in the same package, so one script can use both. Set up each one separately: call `configure()` for SDK 2.0 and build an `OpenMetadata` client for the original client.

### Migrating an Existing Job

Change one call at a time:

| Original client | SDK 2.0 |
|---|---|
| `metadata.create_or_update(data=request)` | `Tables.create(request)` |
| `metadata.get_by_id(entity=Table, entity_id=id)` | `Tables.retrieve(id)` |
| `metadata.get_by_name(entity=Table, fqn=fqn)` | `Tables.retrieve_by_name(fqn)` |
| `metadata.list_all_entities(entity=Table)` | `Tables.list_all()` |
| `metadata.list_entities(entity=Table, params={...})` | `Tables.list(filters={...})` |
| `metadata.delete(entity=Table, entity_id=id)` | `Tables.delete(id)` |

`Tables.create(request)` also updates an existing table, the same as `create_or_update`.

Three details differ from what you might expect:

- In `configure(host=...)`, include `/api` at the end of the URL, the same as `hostPort` in the original client.
- When you list entities, pass query filters as `filters={"databaseSchema": "service.database.schema"}` and read the results from `.entities`.
- With the original client, set `authProvider="openmetadata"` when you authenticate with a JWT token. SDK 2.0 doesn't need an `authProvider`.
11 changes: 7 additions & 4 deletions v1.13.x/api-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,14 @@ metadata = OpenMetadata(server_config)
# List tables
tables = metadata.list_all_entities(entity=Table)
for table in tables:
print(f"{table.fullyQualifiedName}: {table.description}")
print(f"{table.fullyQualifiedName.root}: {getattr(table.description, 'root', table.description)}")
```

```java Java
import org.openmetadata.sdk.client.OpenMetadataClient;
import org.openmetadata.sdk.config.OpenMetadataConfig;
import org.openmetadata.sdk.models.ListParams;

// Configure connection
OpenMetadataConfig config = OpenMetadataConfig.builder()
.serverUrl("https://your-company.open-metadata.org/api")
Expand All @@ -99,9 +103,8 @@ OpenMetadataConfig config = OpenMetadataConfig.builder()
OpenMetadataClient client = new OpenMetadataClient(config);

// List tables
TablesApi tablesApi = client.buildClient(TablesApi.class);
TableList tables = tablesApi.listTables(null, 10, null, null, null);
for (Table table : tables.getData()) {
var tables = client.tables().list(new ListParams().setLimit(10));
for (var table : tables.getData()) {
System.out.println(table.getFullyQualifiedName());
}
```
Expand Down
18 changes: 7 additions & 11 deletions v1.13.x/api-reference/authentication.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,17 @@ tables = metadata.list_all_entities(entity=Table)
```

```java Token Example
import org.openmetadata.client.gateway.OpenMetadata;
import org.openmetadata.schema.services.connections.metadata.OpenMetadataConnection;
import org.openmetadata.schema.security.client.OpenMetadataJWTClientConfig;
import org.openmetadata.sdk.client.OpenMetadataClient;
import org.openmetadata.sdk.config.OpenMetadataConfig;

// Configure with JWT token
OpenMetadataConnection config = new OpenMetadataConnection();
config.setHostPort("https://your-company.open-metadata.org/api");
config.setAuthProvider(AuthProvider.OPENMETADATA);

OpenMetadataJWTClientConfig jwtConfig = new OpenMetadataJWTClientConfig();
jwtConfig.setJwtToken("eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...");
config.setSecurityConfig(jwtConfig);
OpenMetadataConfig config = OpenMetadataConfig.builder()
.serverUrl("https://your-company.open-metadata.org/api")
.accessToken("eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...")
.build();

// Create authenticated client
OpenMetadata client = new OpenMetadata(config);
OpenMetadataClient client = new OpenMetadataClient(config);
```

```bash Token Example
Expand Down
46 changes: 25 additions & 21 deletions v1.13.x/api-reference/data-assets/api-collections/create.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ Create a new API collection within an API service.
</ParamField>

<ParamField body="service" type="string" required>
Fully qualified name of the parent APIService (e.g., `sample_api_service`).
Fully qualified name of the parent APIService, for example `sample_api_service`.
</ParamField>

<ParamField body="endpointURL" type="string">
Base URL for the API collection (e.g., `https://petstore3.swagger.io/#/pet`).
Base URL for the API collection, for example `https://petstore3.swagger.io/#/pet`.
</ParamField>

<ParamField body="displayName" type="string">
Expand All @@ -40,7 +40,7 @@ Create a new API collection within an API service.
</ParamField>

<ParamField body="type" type="string">
Type of owner entity (e.g., `user`, `team`).
Type of owner entity, for example `user`, `team`.
</ParamField>

<ParamField body="name" type="string">
Expand All @@ -49,8 +49,8 @@ Create a new API collection within an API service.
</Expandable>
</ParamField>

<ParamField body="domain" type="string">
Fully qualified name of the domain to assign for governance purposes.
<ParamField body="domains" type="array">
Fully qualified names of the domains to assign for governance purposes.
</ParamField>

<ParamField body="tags" type="array">
Expand All @@ -62,11 +62,11 @@ Create a new API collection within an API service.
</ParamField>

<ParamField body="labelType" type="string">
Type of label (e.g., `Manual`, `Derived`, `Propagated`).
Type of label, for example `Manual`, `Derived`, `Propagated`.
</ParamField>

<ParamField body="state" type="string">
State of the tag (e.g., `Suggested`, `Confirmed`).
State of the tag, for example `Suggested`, `Confirmed`.
</ParamField>
</Expandable>
</ParamField>
Expand Down Expand Up @@ -94,19 +94,23 @@ request = CreateAPICollectionRequest(
)

api_collection = APICollections.create(request)
print(f"Created: {api_collection.fullyQualifiedName}")
print(f"Created: {api_collection.fullyQualifiedName.root}")
```

```java POST /v1/apiCollections
import static org.openmetadata.sdk.fluent.APICollections.*;

// Create using builder pattern
var apiCollection = APICollections.builder()
.name("pet")
.service("sample_api_service")
.endpointURL("https://petstore3.swagger.io/#/pet")
.description("Pet-related API endpoints")
.create();
import java.net.URI;
import org.openmetadata.schema.api.data.CreateAPICollection;
import org.openmetadata.schema.entity.data.APICollection;

// client is an initialized OpenMetadataClient.

CreateAPICollection request = new CreateAPICollection()
.withName("pet")
.withService("sample_api_service")
.withEndpointURL(URI.create("https://petstore3.swagger.io/#/pet"))
.withDescription("Pet-related API endpoints");

APICollection apiCollection = client.apiCollections().create(request);
```

```bash POST /v1/apiCollections
Expand Down Expand Up @@ -204,7 +208,7 @@ Returns the created API collection object with all specified properties and syst
</ResponseField>

<ResponseField name="serviceType" type="string">
Type of API service (e.g., Rest).
Type of API service, for example Rest.
</ResponseField>

<ResponseField name="owners" type="array" optional>
Expand All @@ -216,7 +220,7 @@ Returns the created API collection object with all specified properties and syst
</ResponseField>

<ResponseField name="type" type="string">
Type of owner entity (e.g., `user`, `team`).
Type of owner entity, for example `user`, `team`.
</ResponseField>

<ResponseField name="name" type="string">
Expand All @@ -238,11 +242,11 @@ Returns the created API collection object with all specified properties and syst
</ResponseField>

<ResponseField name="labelType" type="string">
Type of label (e.g., `Manual`, `Derived`, `Propagated`).
Type of label, for example `Manual`, `Derived`, `Propagated`.
</ResponseField>

<ResponseField name="state" type="string">
State of the tag (e.g., `Suggested`, `Confirmed`).
State of the tag, for example `Suggested`, `Confirmed`.
</ResponseField>
</Expandable>
</ResponseField>
Expand Down
34 changes: 19 additions & 15 deletions v1.13.x/api-reference/data-assets/api-collections/delete.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Delete an API collection by ID or fully qualified name. Supports soft delete (de
Use `DELETE /v1/apiCollections/name/{fqn}` to delete by fully qualified name.

<ParamField path="fqn" type="string" required>
Fully qualified name of the API collection (e.g., `sample_api_service.pet`).
Fully qualified name of the API collection, for example `sample_api_service.pet`.
</ParamField>

<ParamField query="recursive" type="boolean" default="false">
Expand Down Expand Up @@ -66,36 +66,40 @@ APICollections.delete(
hard_delete=True
)

# Delete by name
APICollections.delete_by_name("sample_api_service.pet")
# Delete by name (look up the ID first)
entity = APICollections.retrieve_by_name("sample_api_service.pet")
APICollections.delete(entity.id)

# Delete by name with options
APICollections.delete_by_name(
"sample_api_service.pet",
hard_delete=True
)
entity = APICollections.retrieve_by_name("sample_api_service.pet")
APICollections.delete(entity.id, hard_delete=True)

# Restore a soft-deleted API collection
APICollections.restore("0f7ee81c-8163-4097-8adb-45c3d6c7b14b")
```

```java DELETE /v1/apiCollections/{id}
import static org.openmetadata.sdk.fluent.APICollections.*;
import java.util.Map;
import org.openmetadata.sdk.network.HttpMethod;

// client is an initialized OpenMetadataClient.

// Soft delete
APICollections.delete("0f7ee81c-8163-4097-8adb-45c3d6c7b14b").execute();
client.apiCollections().delete("0f7ee81c-8163-4097-8adb-45c3d6c7b14b");

// Hard delete
APICollections.delete("0f7ee81c-8163-4097-8adb-45c3d6c7b14b")
.hardDelete()
.execute();
client.apiCollections().delete("0f7ee81c-8163-4097-8adb-45c3d6c7b14b", Map.of("hardDelete", "true"));

// Delete by name
APICollections.deleteByName("sample_api_service.pet")
.execute();
client.getHttpClient().execute(
HttpMethod.DELETE,
"/v1/apiCollections/name/sample_api_service.pet",
null,
Void.class
);

// Restore
APICollections.restore("0f7ee81c-8163-4097-8adb-45c3d6c7b14b");
client.apiCollections().restore("0f7ee81c-8163-4097-8adb-45c3d6c7b14b");
```

```bash DELETE /v1/apiCollections/{id}
Expand Down
49 changes: 27 additions & 22 deletions v1.13.x/api-reference/data-assets/api-collections/list.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -47,48 +47,53 @@ configure(

# List first page
collections = APICollections.list(limit=50)
for ac in collections.data:
print(f"{ac.fullyQualifiedName}")
for ac in collections.entities:
print(f"{ac.fullyQualifiedName.root}")

# List all with auto-pagination
for ac in APICollections.list_all():
print(f"{ac.fullyQualifiedName}")
print(f"{ac.fullyQualifiedName.root}")

# Filter by service
collections = APICollections.list(
service="sample_api_service",
fields=["owners", "tags", "domain"],
filters={"service": "sample_api_service"},
fields=["owners", "tags", "domains"],
limit=50
)

for ac in collections.data:
print(f"{ac.fullyQualifiedName}")
for ac in collections.entities:
print(f"{ac.fullyQualifiedName.root}")
if ac.owners:
print(f" Owners: {[o.name for o in ac.owners]}")
print(f" Owners: {[o.name for o in ac.owners.root]}")
if ac.tags:
print(f" Tags: {[t.tagFQN for t in ac.tags]}")
print(f" Tags: {[t.tagFQN.root for t in ac.tags]}")
```

```java GET /v1/apiCollections
import static org.openmetadata.sdk.fluent.APICollections.*;
import org.openmetadata.sdk.models.ListParams;
import org.openmetadata.sdk.models.ListResponse;
import org.openmetadata.schema.entity.data.APICollection;

// client is an initialized OpenMetadataClient.

// List first page
var result = APICollections.list()
.limit(50)
.execute();
ListResponse<APICollection> firstPage = client.apiCollections().list(
new ListParams().setLimit(50)
);

for (var ac : result.getData()) {
for (APICollection ac : firstPage.getData()) {
System.out.println(ac.getFullyQualifiedName());
}

// Filter by service with fields
var result = APICollections.list()
.service("sample_api_service")
.fields("owners", "tags", "domain")
.limit(50)
.execute();

for (var ac : result.getData()) {
ListResponse<APICollection> filtered = client.apiCollections().list(
new ListParams()
.setService("sample_api_service")
.setFields("owners,tags,domains")
.setLimit(50)
);

for (APICollection ac : filtered.getData()) {
System.out.println(ac.getFullyQualifiedName());
}
```
Expand Down Expand Up @@ -180,7 +185,7 @@ Returns a paginated list of API collection objects. By default, only basic field
</ResponseField>

<ResponseField name="serviceType" type="string">
Type of API service (e.g., Rest).
Type of API service, for example Rest.
</ResponseField>

<ResponseField name="owners" type="array" optional>
Expand Down
Loading
Loading