A comprehensive Python wrapper for the Linear API with rich Pydantic models, simplified workflows, and an object-oriented design.
Central client configuration and authentication for accessing Linear's API with caching, connection management, and schema validation capabilities.
The LinearClient serves as the main entry point, handling authentication, configuration, and resource manager initialization.
class LinearClient:
def __init__(
self,
api_key: Optional[str] = None,
enable_cache: bool = True,
cache_ttl: int = 3600,
auto_unwrap_connections: bool = True,
):
"""
Initialize the Linear API client.
Args:
api_key: The Linear API key. If not provided, the LINEAR_API_KEY
environment variable will be used.
enable_cache: Whether to enable caching (default: True)
cache_ttl: Default time-to-live for cached items in seconds (default: 1 hour)
auto_unwrap_connections: Whether to automatically unwrap GraphQL connections (default: True)
Raises:
ValueError: If no API key is provided and LINEAR_API_KEY environment
variable is not set.
"""Usage examples:
from linear_api import LinearClient
# Using environment variable LINEAR_API_KEY
client = LinearClient()
# Explicit API key
client = LinearClient(api_key="your_api_key")
# Custom configuration
client = LinearClient(
api_key="your_api_key",
enable_cache=False,
cache_ttl=7200, # 2 hours
auto_unwrap_connections=False
)Low-level GraphQL API access for advanced use cases or custom queries.
def call_api(self, query: Dict[str, Any] | str) -> Dict[str, Any]:
"""
Call the Linear API with the provided query.
Args:
query: The GraphQL query or mutation to execute
Returns:
The API response data
Raises:
ValueError: If the API call fails
"""
def execute_graphql(self, query: str, variables: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""
Execute a GraphQL query with variables.
Args:
query: The GraphQL query string
variables: Optional variables for the query
Returns:
The API response data
"""Usage examples:
# Simple query
response = client.call_api({"query": "{ viewer { name email } }"})
# Query with variables
query = """
query GetIssue($id: String!) {
issue(id: $id) {
id
title
state { name }
}
}
"""
response = client.execute_graphql(query, {"id": "issue-id"})Control caching behavior for API responses to optimize performance and reduce API calls.
def clear_cache(self, cache_name: Optional[str] = None) -> None:
"""
Clear cache data.
Args:
cache_name: Optional name of specific cache to clear. If None, clears all caches.
"""Usage examples:
# Clear all caches
client.clear_cache()
# Clear specific cache
client.clear_cache("issues")
# Access cache manager directly
client.cache.disable()
client.cache.enable()
print(client.cache.stats)Manage automatic GraphQL connection unwrapping for pagination handling.
def enable_connection_unwrapping(self) -> None:
"""
Enable automatic unwrapping of GraphQL connections in all managers.
This settings improves usability by automatically handling pagination,
but may increase the number of API calls for large data sets.
"""
def disable_connection_unwrapping(self) -> None:
"""
Disable automatic unwrapping of GraphQL connections in all managers.
This setting reduces the number of API calls but requires manual
handling of pagination for large data sets.
"""Usage examples:
# Runtime control
client.enable_connection_unwrapping()
client.disable_connection_unwrapping()
# Check current managers
print(f"Issue manager unwrapping: {client.issues._auto_unwrap_connections}")Validate domain models against the GraphQL schema for development and debugging.
def validate_schema(self, model_class: type[LinearModel]) -> Dict[str, Dict[str, Any]]:
"""
Validate the domain models against the GraphQL schema.
Returns:
A dictionary mapping model names to validation results
"""Usage examples:
from linear_api import LinearIssue
# Validate specific model
validation_results = client.validate_schema(LinearIssue)
print(validation_results)
# Check for missing fields
if validation_results['missing_fields']:
print("Missing fields:", validation_results['missing_fields'])Access to specialized resource managers for different Linear entities.
# Manager Properties (read-only)
cache: CacheManager # Cache management
issues: IssueManager # Issue operations
projects: ProjectManager # Project operations
teams: TeamManager # Team operations
users: UserManager # User operationsUsage examples:
# Access managers
issue = client.issues.get("issue-id")
project = client.projects.get("project-id")
team = client.teams.get("team-id")
user = client.users.get("user-id")
# Manager operations
all_issues = client.issues.get_all()
team_projects = client.projects.get_all(team_id="team-id")
team_members = client.teams.get_members("team-id")The client provides comprehensive error handling for common scenarios:
from linear_api import LinearClient
try:
# Missing API key
client = LinearClient()
except ValueError as e:
print(f"Authentication error: {e}")
try:
# Invalid query
client.call_api({"invalid": "query"})
except ValueError as e:
print(f"API error: {e}")# High-performance configuration for read-heavy workloads
client = LinearClient(
enable_cache=True,
cache_ttl=3600, # 1 hour cache
auto_unwrap_connections=True
)
# Memory-conscious configuration
client = LinearClient(
enable_cache=True,
cache_ttl=300, # 5 minute cache
auto_unwrap_connections=False # Manual pagination
)# For large datasets, disable auto-unwrapping
client.disable_connection_unwrapping()
# Manually handle pagination when needed
issues_page = client.issues.get_by_team("team-name") # Returns first page onlyThe client supports multiple authentication methods:
export LINEAR_API_KEY="your_api_key_here"client = LinearClient() # Automatically uses environment variableclient = LinearClient(api_key="your_api_key_here")# Check if client is properly authenticated
try:
me = client.users.get_me()
print(f"Authenticated as: {me.name}")
except ValueError:
print("Authentication failed")Install with Tessl CLI
npx tessl i tessl/pypi-linear-api