Google Cloud Talent API client library for job search and talent management
—
Query autocompletion and suggestion functionality for building intelligent search interfaces with support for job titles, companies, and location-based suggestions. The completion service provides real-time query suggestions to improve user search experience and help users discover relevant job opportunities.
Provides intelligent autocompletion suggestions for job search queries based on job titles, company names, skills, and locations within the tenant's job dataset.
def complete_query(self, tenant: str, query: str, page_size: int = None,
language_codes: List[str] = None, company: str = None,
scope: CompletionScope = None, type_: CompletionType = None) -> CompleteQueryResponse:
"""
Returns autocomplete suggestions for job search queries.
Parameters:
- tenant (str): Tenant resource name for scoped suggestions
- query (str): Partial query string to complete (required, max 255 chars)
- page_size (int): Maximum number of suggestions to return (max 100, default 10)
- language_codes (List[str]): Preferred languages for suggestions (ISO 639-1 codes)
- company (str): Company resource name to scope suggestions
- scope (CompletionScope): Scope of completion suggestions
- type_ (CompletionType): Type of completion to perform
Returns:
CompleteQueryResponse: Completion suggestions with metadata
Raises:
- InvalidArgument: Invalid query string or parameters
- PermissionDenied: Insufficient permissions for completion requests
"""Usage Example:
from google.cloud.talent import CompletionClient, CompletionScope, CompletionType
client = CompletionClient()
# Basic query completion
response = client.complete_query(
tenant="projects/my-project/tenants/my-tenant",
query="software eng",
page_size=10
)
for completion in response.completion_results:
print(f"Suggestion: {completion.suggestion}")
print(f"Type: {completion.type_}")Controls the scope of suggestions to provide targeted autocompletion.
class CompletionScope(Enum):
"""Scope options for completion suggestions."""
COMPLETION_SCOPE_UNSPECIFIED = 0
TENANT = 1 # Suggestions from tenant's job data
PUBLIC = 2 # Suggestions from public job market dataSpecifies the type of completion to perform for different use cases.
class CompletionType(Enum):
"""Types of completion suggestions."""
COMPLETION_TYPE_UNSPECIFIED = 0
JOB_TITLE = 1 # Job title completions
COMPANY_NAME = 2 # Company name completions
COMBINED = 3 # Combined job title and company suggestionsUsage Examples:
# Job title specific completions
title_response = client.complete_query(
tenant="projects/my-project/tenants/my-tenant",
query="data sci",
type_=CompletionType.JOB_TITLE,
page_size=15
)
# Company name completions
company_response = client.complete_query(
tenant="projects/my-project/tenants/my-tenant",
query="goog",
type_=CompletionType.COMPANY_NAME,
page_size=10
)
# Combined suggestions for general search
combined_response = client.complete_query(
tenant="projects/my-project/tenants/my-tenant",
query="python",
type_=CompletionType.COMBINED,
scope=CompletionScope.TENANT,
page_size=20
)Request completions in specific languages for internationalized applications.
# Multi-language completion support
multilingual_response = client.complete_query(
tenant="projects/my-project/tenants/my-tenant",
query="desarrollador", # Spanish for "developer"
language_codes=["es", "en"], # Spanish and English
page_size=10
)
# English-only completions
english_response = client.complete_query(
tenant="projects/my-project/tenants/my-tenant",
query="engineer",
language_codes=["en"],
page_size=15
)Scope completions to specific companies for targeted job searches.
# Completions scoped to specific company
company_scoped_response = client.complete_query(
tenant="projects/my-project/tenants/my-tenant",
query="software",
company="projects/my-project/tenants/my-tenant/companies/google",
page_size=10
)
for completion in company_scoped_response.completion_results:
print(f"Job at Google: {completion.suggestion}")class CompleteQueryResponse:
"""Response containing completion suggestions and metadata."""
completion_results: List[CompletionResult] = None # List of suggestions
metadata: ResponseMetadata = None # Response metadata
class CompletionResult:
"""Individual completion suggestion with metadata."""
suggestion: str = None # Completed query suggestion
type_: CompletionType = None # Type of suggestion
image_uri: str = None # Associated image (for company suggestions)Response Processing:
response = client.complete_query(
tenant="projects/my-project/tenants/my-tenant",
query="java dev",
type_=CompletionType.COMBINED
)
print(f"Found {len(response.completion_results)} suggestions:")
for result in response.completion_results:
print(f" {result.suggestion} ({result.type_})")
if result.image_uri:
print(f" Logo: {result.image_uri}")class CompleteQueryRequest:
tenant: str = None # Tenant resource name (required)
query: str = None # Partial query to complete (required, max 255 chars)
language_codes: List[str] = None # Preferred languages (ISO 639-1)
page_size: int = None # Max suggestions to return (max 100, default 10)
company: str = None # Company resource name for scoping
scope: CompletionScope = None # Completion scope
type_: CompletionType = None # Completion typeImplement debounced autocompletion for responsive search interfaces.
import asyncio
import time
from typing import List, Optional
class SearchAutocompletion:
def __init__(self, tenant_name: str, debounce_ms: int = 300):
self.tenant_name = tenant_name
self.client = CompletionClient()
self.debounce_ms = debounce_ms
self.last_query_time = 0
self.current_task = None
async def get_suggestions(self, query: str, max_suggestions: int = 10) -> List[str]:
"""Get suggestions with debouncing for real-time search."""
if len(query.strip()) < 2:
return []
# Cancel previous request if still pending
if self.current_task and not self.current_task.done():
self.current_task.cancel()
# Debounce rapid queries
self.last_query_time = time.time()
await asyncio.sleep(self.debounce_ms / 1000.0)
# Check if a newer query was made during debounce period
if time.time() - self.last_query_time < (self.debounce_ms / 1000.0):
return []
# Make completion request
self.current_task = asyncio.create_task(
self._fetch_completions(query, max_suggestions)
)
try:
return await self.current_task
except asyncio.CancelledError:
return []
async def _fetch_completions(self, query: str, max_suggestions: int) -> List[str]:
"""Fetch completions from API."""
try:
response = self.client.complete_query(
tenant=self.tenant_name,
query=query,
type_=CompletionType.COMBINED,
page_size=max_suggestions
)
return [result.suggestion for result in response.completion_results]
except Exception as e:
print(f"Completion request failed: {e}")
return []
# Usage in web application
autocomplete = SearchAutocompletion("projects/my-project/tenants/my-tenant")
# In request handler
async def handle_autocomplete_request(query: str):
suggestions = await autocomplete.get_suggestions(query)
return {"suggestions": suggestions}Implement caching for frequently requested completions to improve performance.
import time
from typing import Dict, Tuple, List
from dataclasses import dataclass
@dataclass
class CachedCompletion:
suggestions: List[str]
timestamp: float
ttl_seconds: int = 300 # 5 minutes default TTL
class CompletionCache:
def __init__(self, tenant_name: str, cache_ttl: int = 300):
self.tenant_name = tenant_name
self.client = CompletionClient()
self.cache: Dict[str, CachedCompletion] = {}
self.default_ttl = cache_ttl
def get_completions(self, query: str, max_suggestions: int = 10) -> List[str]:
"""Get completions with caching."""
cache_key = f"{query.lower()}:{max_suggestions}"
# Check cache first
if cache_key in self.cache:
cached = self.cache[cache_key]
if time.time() - cached.timestamp < cached.ttl_seconds:
return cached.suggestions
else:
del self.cache[cache_key] # Remove expired entry
# Fetch from API
try:
response = self.client.complete_query(
tenant=self.tenant_name,
query=query,
type_=CompletionType.COMBINED,
page_size=max_suggestions
)
suggestions = [result.suggestion for result in response.completion_results]
# Cache the results
self.cache[cache_key] = CachedCompletion(
suggestions=suggestions,
timestamp=time.time(),
ttl_seconds=self.default_ttl
)
return suggestions
except Exception as e:
print(f"Completion request failed: {e}")
return []
def clear_cache(self):
"""Clear all cached completions."""
self.cache.clear()
def clear_expired(self):
"""Remove expired cache entries."""
current_time = time.time()
expired_keys = [
key for key, cached in self.cache.items()
if current_time - cached.timestamp >= cached.ttl_seconds
]
for key in expired_keys:
del self.cache[key]
# Usage
completion_cache = CompletionCache("projects/my-project/tenants/my-tenant")
def get_search_suggestions(query: str) -> List[str]:
return completion_cache.get_completions(query, max_suggestions=15)JavaScript/TypeScript integration for web applications.
class TalentAutocompletion {
constructor(tenantPath, apiEndpoint) {
this.tenantPath = tenantPath;
this.apiEndpoint = apiEndpoint;
this.debounceTimer = null;
this.currentController = null;
}
async getSuggestions(query, options = {}) {
// Clear previous debounce timer
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
}
// Cancel previous request
if (this.currentController) {
this.currentController.abort();
}
return new Promise((resolve, reject) => {
this.debounceTimer = setTimeout(async () => {
try {
this.currentController = new AbortController();
const params = new URLSearchParams({
tenant: this.tenantPath,
query: query,
page_size: options.maxSuggestions || 10,
type: options.type || 'COMBINED'
});
if (options.languageCodes) {
params.append('language_codes', options.languageCodes.join(','));
}
const response = await fetch(
`${this.apiEndpoint}/completion?${params}`,
{
signal: this.currentController.signal,
headers: {
'Authorization': `Bearer ${await this.getAuthToken()}`
}
}
);
if (!response.ok) {
throw new Error(`Completion request failed: ${response.status}`);
}
const data = await response.json();
resolve(data.completion_results || []);
} catch (error) {
if (error.name !== 'AbortError') {
reject(error);
}
}
}, options.debounceMs || 300);
});
}
async getAuthToken() {
// Implement your authentication token retrieval
return localStorage.getItem('auth_token');
}
}
// Usage in React component
const useJobSearchAutocompletion = (tenantPath) => {
const [suggestions, setSuggestions] = useState([]);
const [loading, setLoading] = useState(false);
const autocompletion = useRef(
new TalentAutocompletion(tenantPath, '/api/talent')
).current;
const getSuggestions = useCallback(async (query) => {
if (query.length < 2) {
setSuggestions([]);
return;
}
setLoading(true);
try {
const results = await autocompletion.getSuggestions(query, {
maxSuggestions: 10,
type: 'COMBINED'
});
setSuggestions(results.map(r => r.suggestion));
} catch (error) {
console.error('Autocompletion failed:', error);
setSuggestions([]);
} finally {
setLoading(false);
}
}, [autocompletion]);
return { suggestions, loading, getSuggestions };
};Completion operations can raise several types of exceptions:
from google.api_core import exceptions
def safe_get_completions(client: CompletionClient, tenant: str, query: str) -> List[str]:
"""Safely get completions with comprehensive error handling."""
try:
response = client.complete_query(tenant=tenant, query=query)
return [result.suggestion for result in response.completion_results]
except exceptions.InvalidArgument as e:
print(f"Invalid completion query: {e}")
return [] # Return empty list for invalid queries
except exceptions.PermissionDenied as e:
print(f"Completion access denied: {e}")
return [] # Return empty list if no permission
except exceptions.ResourceExhausted as e:
print(f"Completion quota exceeded: {e}")
return [] # Return empty list if quota exceeded
except exceptions.DeadlineExceeded as e:
print(f"Completion request timeout: {e}")
return [] # Return empty list on timeout
except Exception as e:
print(f"Unexpected completion error: {e}")
return [] # Never break user experience for completion failuresCommon error scenarios:
# Optimize completion requests for performance
def optimized_completion_request(query: str) -> CompleteQueryRequest:
return CompleteQueryRequest(
tenant="projects/my-project/tenants/my-tenant",
query=query,
page_size=8, # Smaller page size for faster response
type_=CompletionType.COMBINED, # Most useful for general search
scope=CompletionScope.TENANT # Faster than public scope
)import time
from collections import defaultdict
class CompletionAnalytics:
def __init__(self):
self.request_counts = defaultdict(int)
self.response_times = []
self.error_counts = defaultdict(int)
def track_request(self, query: str, response_time: float, success: bool, error_type: str = None):
"""Track completion request metrics."""
self.request_counts[query] += 1
self.response_times.append(response_time)
if not success and error_type:
self.error_counts[error_type] += 1
def get_metrics(self):
"""Get completion performance metrics."""
if not self.response_times:
return {}
return {
'total_requests': sum(self.request_counts.values()),
'unique_queries': len(self.request_counts),
'avg_response_time': sum(self.response_times) / len(self.response_times),
'error_rate': sum(self.error_counts.values()) / sum(self.request_counts.values()),
'most_common_queries': sorted(
self.request_counts.items(),
key=lambda x: x[1],
reverse=True
)[:10]
}Install with Tessl CLI
npx tessl i tessl/pypi-google-cloud-talent