CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-jupyter-core

Core foundational package providing base application classes, path utilities, and configuration management for the Jupyter ecosystem.

Pending
Overview
Eval results
Files

utility-functions.mddocs/

Utility Functions

Core utility functions for directory management, deprecation warnings, async support, and platform-specific operations. These utilities are used throughout the Jupyter ecosystem to provide consistent behavior and functionality.

Capabilities

Directory Management

Utilities for creating and managing directories with proper permissions and error handling.

def ensure_dir_exists(path: str | Path, mode: int = 0o777) -> None:
    """Ensure that a directory exists.
    
    If it doesn't exist, try to create it, protecting against race conditions
    if another process is doing the same. The default permissions are 
    determined by the current umask.
    
    Args:
        path: Directory path to create
        mode: Directory permissions (default: 0o777, modified by umask)
        
    Raises:
        OSError: If directory cannot be created or path exists but is not a directory
    """

Usage Example:

from jupyter_core.utils import ensure_dir_exists
from pathlib import Path

# Ensure a config directory exists
config_dir = Path.home() / ".jupyter" / "custom"
ensure_dir_exists(config_dir, mode=0o700)  # User-only permissions

# Safe to use even if directory already exists
ensure_dir_exists(config_dir)  # No error if already exists

Deprecation Support

Utilities for generating deprecation warnings with proper stack level calculation to point to the actual calling code rather than internal frames.

def deprecation(message: str, internal: str | list[str] = "jupyter_core/") -> None:
    """Generate a deprecation warning targeting the first frame that is not 'internal'.
    
    Automatically calculates the correct stack level to ensure the warning
    points to user code rather than internal library code.
    
    Args:
        message: Deprecation warning message
        internal: String or list of strings identifying internal code paths
                 (if these appear in frame filenames, frames are considered internal)
    """

Usage Example:

from jupyter_core.utils import deprecation

def old_function():
    deprecation(
        "old_function is deprecated, use new_function instead",
        internal=["jupyter_core/", "mypackage/internal/"]
    )
    # Function implementation...

# When called by user code, warning points to user's call site
old_function()  # Warning shows this line, not internal deprecation() call

Async Utilities

Functions for managing asyncio event loops and running async code in sync contexts.

def ensure_event_loop(prefer_selector_loop: bool = False) -> asyncio.AbstractEventLoop:
    """Ensure an asyncio event loop exists and return it.
    
    Gets the current event loop, or creates a new one if none exists.
    Handles platform-specific loop selection.
    
    Args:
        prefer_selector_loop: On Windows, prefer SelectorEventLoop over default
                             (useful for Tornado compatibility)
        
    Returns:
        asyncio.AbstractEventLoop: Current or newly created event loop
    """

def run_sync(coro: Callable[..., Awaitable[T]]) -> Callable[..., T]:
    """Wraps coroutine in a function that blocks until it has executed.
    
    Allows calling async functions from sync code. Handles both cases
    where an event loop is already running (uses background thread) and
    where no loop exists (runs loop directly).
    
    Args:
        coro: Coroutine function to wrap
        
    Returns:
        Callable: Synchronous wrapper function
    """

async def ensure_async(obj: Awaitable[T] | T) -> T:
    """Convert a non-awaitable object to a coroutine if needed.
    
    Handles functions that may return either sync values or awaitables,
    ensuring consistent async handling.
    
    Args:
        obj: Object that may or may not be awaitable
        
    Returns:
        T: The result, whether it was originally sync or async
    """

Usage Example:

from jupyter_core.utils import run_sync, ensure_event_loop
import asyncio

# Wrap an async function to be callable from sync code
@run_sync
async def async_operation(data):
    await asyncio.sleep(1)
    return f"Processed: {data}"

# Can now call async function synchronously
result = async_operation("test data")
print(result)  # "Processed: test data"

# Ensure event loop exists
loop = ensure_event_loop()
print(f"Loop type: {type(loop)}")

Internal Async Classes

Internal classes that support the async utilities. These are typically not used directly but are part of the implementation.

class _TaskRunner:
    """A task runner that runs an asyncio event loop on a background thread.
    
    Used internally by run_sync() to handle cases where an event loop
    is already running in the current thread.
    """
    
    def __init__(self) -> None:
        """Initialize the task runner."""
    
    def run(self, coro) -> Any:
        """Synchronously run a coroutine on a background thread.
        
        Args:
            coro: Coroutine to execute
            
        Returns:
            Any: Result of coroutine execution
        """

Stack Inspection Utilities

Internal utilities for inspecting the call stack, used by the deprecation system.

def _get_frame(level: int) -> FrameType | None:
    """Get the frame at the given stack level.
    
    Uses sys._getframe if available (faster) or falls back to inspect.stack.
    
    Args:
        level: Stack level to retrieve (0 = current frame)
        
    Returns:
        FrameType | None: Frame object or None if level is invalid
    """

def _external_stacklevel(internal: list[str]) -> int:
    """Find the stacklevel of the first frame that doesn't contain internal strings.
    
    Used by deprecation() to calculate the correct stacklevel for warnings.
    
    Args:
        internal: List of strings that identify internal code paths
        
    Returns:
        int: Stack level of first external frame
    """

Type Support

Type variables and aliases used throughout the utility functions.

from typing import Any, Awaitable, Callable, TypeVar
from types import FrameType
from contextvars import ContextVar
import asyncio

# Type variable for generic async functions
T = TypeVar("T")

# Context variable for tracking event loops
_loop: ContextVar[asyncio.AbstractEventLoop | None]

# Internal registry for task runners  
_runner_map: dict[str, _TaskRunner]

Platform-Specific Behavior

Windows

  • Event Loop Selection: Can prefer SelectorEventLoop over default ProactorEventLoop for Tornado compatibility
  • Thread Naming: Uses descriptive thread names for background async runners
  • Frame Inspection: Handles differences in stack frame availability

Unix/Linux/macOS

  • Event Loop: Uses default event loop policy for the platform
  • Thread Safety: Proper handling of event loops across threads
  • Signal Handling: Respects platform signal handling in async contexts

Integration with Jupyter Ecosystem

These utilities are used throughout Jupyter components:

Directory Management

  • Config directories: Ensuring Jupyter config directories exist with proper permissions
  • Data directories: Creating kernel spec directories, extension directories
  • Runtime directories: Setting up directories for kernels, servers
  • Custom directories: User-defined locations for notebooks, kernels

Deprecation Warnings

  • API Changes: Warning about deprecated function signatures
  • Configuration Changes: Alerting to deprecated config options
  • Path Changes: Warning about legacy path usage patterns
  • Import Changes: Deprecating old module locations

Async Support

  • Kernel Management: Running async kernel operations from sync contexts
  • Server Integration: Supporting both sync and async server implementations
  • Widget Communication: Handling async widget comm messages
  • Extension Loading: Supporting async extension initialization

Error Handling

The utilities include robust error handling:

  • Directory Creation: Race condition protection, permission error handling
  • Stack Inspection: Fallback methods when sys._getframe unavailable
  • Event Loop Management: Cleanup on application exit, thread safety
  • Async Conversion: Handling already-awaited coroutines, runtime errors

This comprehensive error handling ensures the utilities work reliably across different Python implementations, platforms, and usage contexts.

Install with Tessl CLI

npx tessl i tessl/pypi-jupyter-core

docs

application-framework.md

command-line-tools.md

index.md

path-management.md

utility-functions.md

tile.json