prefix-register 0.2.2

A PostgreSQL-backed namespace prefix registry for CURIE expansion and prefix management
Documentation
"""Type stubs for prefix_register"""

__version__: str

class PrefixRegistry:
    """
    A PostgreSQL-backed namespace prefix registry for CURIE expansion.

    This class provides async methods to store and retrieve namespace prefixes,
    expand CURIEs, and manage prefix-to-URI mappings. All operations are atomic
    and thread-safe.
    """

    @staticmethod
    async def new(database_url: str, max_connections: int) -> PrefixRegistry:
        """
        Create a new prefix registry connected to PostgreSQL.

        Args:
            database_url: PostgreSQL connection string (e.g., "postgres://user:password@host:port/database")
            max_connections: Maximum number of connections in the pool (recommended: 5-20)

        Returns:
            A new PrefixRegistry instance

        Raises:
            RuntimeError: If connection to database fails

        Example:
            >>> registry = await PrefixRegistry.new("postgres://localhost/mydb", 10)
        """
        ...
    @staticmethod
    async def new_with_retry(
        database_url: str,
        max_connections: int,
        max_retries: int = 5,
        initial_delay_ms: int = 1000,
        max_delay_ms: int = 30000,
    ) -> PrefixRegistry:
        """
        Create a new prefix registry with retry logic for transient failures.

        Args:
            database_url: PostgreSQL connection string
            max_connections: Maximum number of connections in the pool
            max_retries: Maximum number of retry attempts (default: 5)
            initial_delay_ms: Initial delay in milliseconds before first retry (default: 1000)
            max_delay_ms: Maximum delay in milliseconds between retries (default: 30000)

        Returns:
            A new PrefixRegistry instance

        Raises:
            RuntimeError: If connection fails after all retries

        Example:
            >>> registry = await PrefixRegistry.new_with_retry(
            ...     "postgres://localhost/mydb", 10, 5, 1000, 30000
            ... )
        """
        ...
    async def store_prefix_if_new(self, prefix: str, uri: str) -> bool:
        """
        Store a new prefix if the URI doesn't already have one.

        Follows the "first prefix wins" rule - if a URI already has a prefix
        registered, the new prefix is ignored.

        Args:
            prefix: The namespace prefix (e.g., "foaf", "rdf")
            uri: The full namespace URI (e.g., "http://xmlns.com/foaf/0.1/")

        Returns:
            True if the prefix was stored, False if the URI already had a prefix

        Raises:
            RuntimeError: If storage fails
            ValueError: If prefix or URI is invalid

        Example:
            >>> stored = await registry.store_prefix_if_new("foaf", "http://xmlns.com/foaf/0.1/")
            >>> if stored:
            ...     print("New prefix stored")
        """
        ...
    async def store_prefixes_if_new(
        self, prefixes: list[tuple[str, str]]
    ) -> dict[str, int]:
        """
        Store multiple prefixes in batch.

        More efficient than calling store_prefix_if_new() repeatedly.

        Args:
            prefixes: List of (prefix, uri) tuples to store

        Returns:
            Dictionary with 'stored' and 'skipped' counts

        Raises:
            RuntimeError: If batch storage fails

        Example:
            >>> prefixes = [
            ...     ("foaf", "http://xmlns.com/foaf/0.1/"),
            ...     ("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"),
            ... ]
            >>> result = await registry.store_prefixes_if_new(prefixes)
            >>> print(f"Stored {result['stored']}, skipped {result['skipped']}")
        """
        ...
    async def get_uri_for_prefix(self, prefix: str) -> str | None:
        """
        Get the URI for a given prefix.

        First checks the in-memory cache, then falls back to the database.

        Args:
            prefix: The namespace prefix (e.g., "foaf")

        Returns:
            The URI if the prefix is known, None otherwise

        Raises:
            RuntimeError: If lookup fails

        Example:
            >>> uri = await registry.get_uri_for_prefix("foaf")
            >>> if uri:
            ...     print(f"foaf = {uri}")
        """
        ...
    async def get_prefix_for_uri(self, uri: str) -> str | None:
        """
        Get the prefix for a given URI.

        Args:
            uri: The full namespace URI

        Returns:
            The prefix if the URI is registered, None otherwise

        Raises:
            RuntimeError: If lookup fails

        Example:
            >>> prefix = await registry.get_prefix_for_uri("http://xmlns.com/foaf/0.1/")
            >>> if prefix:
            ...     print(f"URI has prefix: {prefix}")
        """
        ...
    async def expand_curie(self, prefix: str, local_name: str) -> str | None:
        """
        Expand a CURIE (Compact URI) to a full URI.

        Args:
            prefix: The namespace prefix (e.g., "foaf")
            local_name: The local part (e.g., "Person")

        Returns:
            The full URI (e.g., "http://xmlns.com/foaf/0.1/Person") or None if prefix unknown

        Raises:
            RuntimeError: If expansion fails

        Example:
            >>> uri = await registry.expand_curie("foaf", "Person")
            >>> if uri:
            ...     print(f"foaf:Person = {uri}")
            ...     # Output: foaf:Person = http://xmlns.com/foaf/0.1/Person
        """
        ...
    async def get_all_prefixes(self) -> dict[str, str]:
        """
        Get all registered prefixes.

        Returns:
            Dictionary mapping prefixes to URIs

        Example:
            >>> prefixes = await registry.get_all_prefixes()
            >>> for prefix, uri in prefixes.items():
            ...     print(f"{prefix}: {uri}")
        """
        ...
    async def prefix_count(self) -> int:
        """
        Get the number of registered prefixes.

        Returns:
            The number of registered prefixes

        Example:
            >>> count = await registry.prefix_count()
            >>> print(f"Registered prefixes: {count}")
        """
        ...
    async def shorten_uri(self, uri: str) -> tuple[str, str] | None:
        """
        Shorten a URI to a (prefix, local_name) tuple.

        Uses longest-match semantics: if multiple namespaces match the URI,
        the longest one wins. For example, if both "http://a/" and "http://a/b#"
        are registered, "http://a/b#foo" would match the longer namespace.

        Args:
            uri: The full URI to shorten

        Returns:
            A (prefix, local_name) tuple if a match is found, None otherwise

        Raises:
            RuntimeError: If the lookup fails

        Example:
            >>> result = await registry.shorten_uri("http://xmlns.com/foaf/0.1/Person")
            >>> if result:
            ...     prefix, local = result
            ...     print(f"{prefix}:{local}")  # Output: foaf:Person
        """
        ...
    async def shorten_uri_or_full(self, uri: str) -> str:
        """
        Shorten a URI to a CURIE string, or return the original URI if no match.

        This is a convenience method that returns a formatted string rather than
        a tuple. Uses longest-match semantics for namespace matching.

        Args:
            uri: The full URI to shorten

        Returns:
            A CURIE string like "prefix:local", or the original URI if no namespace matches

        Raises:
            RuntimeError: If the lookup fails

        Example:
            >>> result = await registry.shorten_uri_or_full("http://xmlns.com/foaf/0.1/Person")
            >>> print(result)  # "foaf:Person" or the full URI if not registered
        """
        ...
    async def shorten_uri_batch(self, uris: list[str]) -> list[tuple[str, str] | None]:
        """
        Shorten multiple URIs in batch.

        Uses longest-match semantics for each URI. More efficient than calling
        shorten_uri() repeatedly.

        Args:
            uris: List of URIs to shorten

        Returns:
            List with (prefix, local_name) for matched URIs, None for unmatched

        Raises:
            RuntimeError: If the batch lookup fails

        Example:
            >>> uris = ["http://xmlns.com/foaf/0.1/Person", "http://unknown.org/thing"]
            >>> results = await registry.shorten_uri_batch(uris)
            >>> for result in results:
            ...     if result:
            ...         print(f"{result[0]}:{result[1]}")
            ...     else:
            ...         print("No match")
        """
        ...
    async def expand_curie_batch(
        self, curies: list[tuple[str, str]]
    ) -> list[str | None]:
        """
        Expand multiple CURIEs in batch.

        More efficient than calling expand_curie() repeatedly.

        Args:
            curies: List of (prefix, local_name) tuples

        Returns:
            List with expanded URIs for known prefixes, None for unknown

        Raises:
            RuntimeError: If the batch expansion fails

        Example:
            >>> curies = [("foaf", "Person"), ("unknown", "Thing")]
            >>> results = await registry.expand_curie_batch(curies)
            >>> for result in results:
            ...     if result:
            ...         print(result)
            ...     else:
            ...         print("Unknown prefix")
        """
        ...

__all__ = ["PrefixRegistry"]