Google Cloud Talent API client library for job search and talent management
—
Multi-tenant data isolation and management for organizations requiring separate data namespaces, enabling secure multi-customer deployments and data segregation. Tenants provide the foundational isolation layer for all Google Cloud Talent API resources.
Creates new tenant entities that serve as data isolation boundaries for companies, jobs, and all other resources within the Talent API.
def create_tenant(self, parent: str, tenant: Tenant) -> Tenant:
"""
Creates a new tenant for data isolation.
Parameters:
- parent (str): Project resource name where tenant will be created
- tenant (Tenant): Tenant object with required external_id
Returns:
Tenant: Created tenant with generated resource name
Raises:
- InvalidArgument: Missing required fields or invalid values
- AlreadyExists: Tenant with same external_id already exists
- PermissionDenied: Insufficient permissions to create tenant
"""Usage Example:
from google.cloud.talent import TenantServiceClient, Tenant
client = TenantServiceClient()
tenant = Tenant(
external_id="customer-acme-prod"
)
created_tenant = client.create_tenant(
parent="projects/my-project",
tenant=tenant
)
print(f"Created tenant: {created_tenant.name}")
print(f"External ID: {created_tenant.external_id}")Retrieves individual tenant entities by resource name with complete tenant information and metadata.
def get_tenant(self, name: str) -> Tenant:
"""
Retrieves a tenant by its resource name.
Parameters:
- name (str): Full tenant resource name
Returns:
Tenant: Complete tenant object
Raises:
- NotFound: Tenant does not exist
- PermissionDenied: Insufficient permissions to view tenant
"""Usage Example:
tenant = client.get_tenant(
name="projects/my-project/tenants/tenant-123"
)
print(f"Tenant external ID: {tenant.external_id}")Updates existing tenant profiles with field-level control using update masks to specify which tenant attributes should be modified.
def update_tenant(self, tenant: Tenant, update_mask: FieldMask = None) -> Tenant:
"""
Updates an existing tenant.
Parameters:
- tenant (Tenant): Tenant object with updated values and resource name
- update_mask (FieldMask): Specifies which fields to update
Returns:
Tenant: Updated tenant object
Raises:
- NotFound: Tenant does not exist
- InvalidArgument: Invalid field values or update mask
- PermissionDenied: Insufficient permissions to update tenant
"""Usage Example:
from google.protobuf import field_mask_pb2
# Update tenant external ID
tenant.external_id = "customer-acme-production"
update_mask = field_mask_pb2.FieldMask(paths=["external_id"])
updated_tenant = client.update_tenant(
tenant=tenant,
update_mask=update_mask
)Removes tenant entities from the system. Note that tenants with associated companies or jobs cannot be deleted until all child resources are removed first.
def delete_tenant(self, name: str) -> None:
"""
Deletes a tenant entity.
Parameters:
- name (str): Full tenant resource name
Raises:
- NotFound: Tenant does not exist
- PermissionDenied: Insufficient permissions to delete tenant
- FailedPrecondition: Tenant has associated companies or jobs that must be deleted first
"""Usage Example:
from google.api_core import exceptions
try:
client.delete_tenant(
name="projects/my-project/tenants/tenant-123"
)
print("Tenant deleted successfully")
except exceptions.FailedPrecondition:
print("Cannot delete tenant with active companies or jobs")Lists tenant entities with pagination support for efficient browsing of large tenant datasets within a project.
def list_tenants(self, parent: str, page_size: int = None,
page_token: str = None) -> ListTenantsResponse:
"""
Lists tenants with pagination.
Parameters:
- parent (str): Project resource name
- page_size (int): Maximum number of tenants to return (max 100)
- page_token (str): Token for pagination from previous response
Returns:
ListTenantsResponse: Tenants list with pagination token and metadata
Raises:
- InvalidArgument: Invalid page size
- PermissionDenied: Insufficient permissions to list tenants
"""Usage Example:
# List all tenants in a project
response = client.list_tenants(
parent="projects/my-project",
page_size=50
)
for tenant in response.tenants:
print(f"Tenant: {tenant.external_id}")
print(f" Resource name: {tenant.name}")
# Handle pagination
while response.next_page_token:
response = client.list_tenants(
parent="projects/my-project",
page_token=response.next_page_token,
page_size=50
)
for tenant in response.tenants:
print(f"Tenant: {tenant.external_id}")class Tenant:
"""
A tenant resource represents a tenant in the service, which provides
data isolation and resource management capabilities for multi-tenant
applications.
"""
name: str = None # Resource name (auto-generated)
external_id: str = None # Client-defined tenant identifier (required, max 255 chars)The Tenant entity is intentionally minimal, serving primarily as an isolation boundary. The external_id should be a meaningful identifier that maps to your application's customer or organization identifiers.
class CreateTenantRequest:
parent: str = None # Project resource name
tenant: Tenant = None # Tenant to create
class GetTenantRequest:
name: str = None # Tenant resource name
class UpdateTenantRequest:
tenant: Tenant = None # Tenant with updates
update_mask: FieldMask = None # Fields to update
class DeleteTenantRequest:
name: str = None # Tenant resource name
class ListTenantsRequest:
parent: str = None # Project resource name
page_size: int = None # Page size (max 100)
page_token: str = None # Pagination tokenclass ListTenantsResponse:
tenants: List[Tenant] = None # List of tenants
next_page_token: str = None # Pagination token for next page
metadata: ResponseMetadata = None # Response metadataTenants provide the foundational data isolation layer in the Google Cloud Talent API:
Project (GCP Project)
└── Tenant (Data isolation boundary)
├── Company (Job posting organization)
│ └── Jobs (Individual job postings)
├── Events (User interaction tracking)
└── Completion (Query suggestions)# Single project, multiple tenants for different customers
project = "projects/hr-platform-prod"
# Customer A's isolated data
tenant_a = "projects/hr-platform-prod/tenants/customer-a"
company_a1 = "projects/hr-platform-prod/tenants/customer-a/companies/acme-corp"
job_a1 = "projects/hr-platform-prod/tenants/customer-a/jobs/job-001"
# Customer B's isolated data
tenant_b = "projects/hr-platform-prod/tenants/customer-b"
company_b1 = "projects/hr-platform-prod/tenants/customer-b/companies/beta-inc"
job_b1 = "projects/hr-platform-prod/tenants/customer-b/jobs/job-001"All other Talent API services require a tenant context:
from google.cloud.talent import (
TenantServiceClient, CompanyServiceClient,
JobServiceClient, EventServiceClient
)
# Create tenant first
tenant_client = TenantServiceClient()
tenant = tenant_client.create_tenant(
parent="projects/my-project",
tenant=Tenant(external_id="customer-123")
)
# Use tenant as parent for all other resources
company_client = CompanyServiceClient()
company = company_client.create_company(
parent=tenant.name, # Tenant as parent
company=Company(display_name="Acme Corp", external_id="acme")
)
job_client = JobServiceClient()
job = job_client.create_job(
parent=tenant.name, # Tenant as parent
job=Job(company=company.name, requisition_id="job-1", title="Engineer")
)
# Events also scoped to tenant
event_client = EventServiceClient()
event_client.create_client_event(
parent=tenant.name, # Tenant as parent
client_event=ClientEvent(...)
)The client provides helper methods for constructing tenant resource paths:
# Class methods for building resource paths
@classmethod
def tenant_path(cls, project: str, tenant: str) -> str:
"""Constructs a fully-qualified tenant resource name."""
@classmethod
def project_path(cls, project: str) -> str:
"""Constructs a fully-qualified project resource name."""
@classmethod
def parse_tenant_path(cls, path: str) -> Dict[str, str]:
"""Parses a tenant path into its component parts."""Usage Example:
# Build resource paths
tenant_path = TenantServiceClient.tenant_path(
project="my-project",
tenant="tenant-123"
)
project_path = TenantServiceClient.project_path(project="my-project")
# Parse resource paths
path_components = TenantServiceClient.parse_tenant_path(tenant_path)
print(f"Project: {path_components['project']}")
print(f"Tenant: {path_components['tenant']}")Tenant management operations can raise several types of exceptions:
from google.api_core import exceptions
try:
tenant = client.create_tenant(parent=parent, tenant=tenant_data)
except exceptions.InvalidArgument as e:
# Handle validation errors
print(f"Invalid tenant data: {e}")
except exceptions.AlreadyExists as e:
# Handle duplicate external_id
print(f"Tenant already exists: {e}")
except exceptions.PermissionDenied as e:
# Handle authorization errors
print(f"Access denied: {e}")Common error scenarios:
class TalentAPIService:
def __init__(self):
self.tenant_client = TenantServiceClient()
self.company_client = CompanyServiceClient()
self.job_client = JobServiceClient()
def onboard_customer(self, customer_id: str, customer_name: str):
"""Onboard a new customer with isolated tenant."""
tenant = Tenant(external_id=f"customer-{customer_id}-prod")
tenant_response = self.tenant_client.create_tenant(
parent="projects/hr-saas-platform",
tenant=tenant
)
return tenant_response
def create_customer_company(self, customer_id: str, company_data: dict):
"""Create a company within customer's tenant."""
tenant_name = f"projects/hr-saas-platform/tenants/customer-{customer_id}-prod"
company = Company(
display_name=company_data["name"],
external_id=f"company-{company_data['id']}"
)
return self.company_client.create_company(
parent=tenant_name,
company=company
)Install with Tessl CLI
npx tessl i tessl/pypi-google-cloud-talent