text: from typing import (Any, Union, Type)  # noqa: F401
  
  from eth_keys.datatypes import (
      BaseSignature,
      LazyBackend,
      NonRecoverableSignature,
      PublicKey,
      PrivateKey,
      Signature,
  )
  from eth_keys.exceptions import (
      ValidationError,
  )
  from eth_keys.validation import (
      validate_message_hash,
      validate_compressed_public_key_bytes,
      validate_uncompressed_public_key_bytes,
  )
  
  
  # These must be aliased due to a scoping issue in mypy
  # https://github.com/python/mypy/issues/1775
  _PublicKey = PublicKey
  _PrivateKey = PrivateKey
  _Signature = Signature
  _NonRecoverableSignature = NonRecoverableSignature
  
  
  class KeyAPI(LazyBackend):
      #
      # datatype shortcuts
      #
      PublicKey = PublicKey  # type: Type[_PublicKey]
      PrivateKey = PrivateKey  # type: Type[_PrivateKey]
      Signature = Signature  # type: Type[_Signature]
      NonRecoverableSignature = NonRecoverableSignature  # type: Type[_NonRecoverableSignature]
  
      #
      # Proxy method calls to the backends
      #
      def ecdsa_sign(self,
                     message_hash: bytes,
                     private_key: _PrivateKey) -> _Signature:
          validate_message_hash(message_hash)
          if not isinstance(private_key, PrivateKey):
              raise ValidationError(
                  "The `private_key` must be an instance of `eth_keys.datatypes.PrivateKey`"
              )
          signature = self.backend.ecdsa_sign(message_hash, private_key)
          if not isinstance(signature, Signature):
              raise ValidationError(
                  "Backend returned an invalid signature.  Return value must be "
                  "an instance of `eth_keys.datatypes.Signature`"
              )
          return signature
  
      def ecdsa_sign_non_recoverable(self,
                                     message_hash: bytes,
                                     private_key: _PrivateKey) -> _NonRecoverableSignature:
          validate_message_hash(message_hash)
          if not isinstance(private_key, PrivateKey):
              raise ValidationError(
                  "The `private_key` must be an instance of `eth_keys.datatypes.PrivateKey`"
              )
          signature = self.backend.ecdsa_sign_non_recoverable(message_hash, private_key)
          if not isinstance(signature, NonRecoverableSignature):
              raise ValidationError(
                  "Backend returned an invalid signature.  Return value must be "
                  "an instance of `eth_keys.datatypes.Signature`"
              )
          return signature
  
      def ecdsa_verify(self,
                       message_hash: bytes,
                       signature: BaseSignature,
                       public_key: _PublicKey) -> bool:
          validate_message_hash(message_hash)
          if not isinstance(public_key, PublicKey):
              raise ValidationError(
                  "The `public_key` must be an instance of `eth_keys.datatypes.PublicKey`"
              )
          if not isinstance(signature, BaseSignature):
              raise ValidationError(
                  "The `signature` must be an instance of `eth_keys.datatypes.BaseSignature`"
              )
          return self.backend.ecdsa_verify(message_hash, signature, public_key)
  
      def ecdsa_recover(self,
                        message_hash: bytes,
                        signature: _Signature) -> _PublicKey:
          validate_message_hash(message_hash)
          if not isinstance(signature, Signature):
              raise ValidationError(
                  "The `signature` must be an instance of `eth_keys.datatypes.Signature`"
              )
          public_key = self.backend.ecdsa_recover(message_hash, signature)
          if not isinstance(public_key, _PublicKey):
              raise ValidationError(
                  "Backend returned an invalid public_key.  Return value must be "
                  "an instance of `eth_keys.datatypes.PublicKey`"
              )
          return public_key
  
      def private_key_to_public_key(self, private_key: _PrivateKey) -> _PublicKey:
          if not isinstance(private_key, PrivateKey):
              raise ValidationError(
                  "The `private_key` must be an instance of `eth_keys.datatypes.PrivateKey`"
              )
          public_key = self.backend.private_key_to_public_key(private_key)
          if not isinstance(public_key, PublicKey):
              raise ValidationError(
                  "Backend returned an invalid public_key.  Return value must be "
                  "an instance of `eth_keys.datatypes.PublicKey`"
              )
          return public_key
  
  
  # This creates an easy to import backend which will lazily fetch whatever
  # backend has been configured at runtime (as opposed to import or instantiation time).
  lazy_key_api = KeyAPI(backend=None)
  