text: import logging
  from authlib.deprecate import deprecate
  from authlib.common.security import generate_token
  from authlib.oauth2.rfc6749 import InvalidScopeError
  from authlib.oauth2.rfc6749.grants.authorization_code import (
      validate_code_authorization_request
  )
  from .implicit import OpenIDImplicitGrant
  from .util import is_openid_scope, validate_nonce
  
  log = logging.getLogger(__name__)
  
  
  class OpenIDHybridGrant(OpenIDImplicitGrant):
      #: Generated "code" length
      AUTHORIZATION_CODE_LENGTH = 48
  
      RESPONSE_TYPES = {'code id_token', 'code token', 'code id_token token'}
      GRANT_TYPE = 'code'
      DEFAULT_RESPONSE_MODE = 'fragment'
  
      def generate_authorization_code(self):
          """"The method to generate "code" value for authorization code data.
          Developers may rewrite this method, or customize the code length with::
  
              class MyAuthorizationCodeGrant(AuthorizationCodeGrant):
                  AUTHORIZATION_CODE_LENGTH = 32  # default is 48
          """
          return generate_token(self.AUTHORIZATION_CODE_LENGTH)
  
      def save_authorization_code(self, code, request):
          """Save authorization_code for later use. Developers MUST implement
          it in subclass. Here is an example::
  
              def save_authorization_code(self, code, request):
                  client = request.client
                  item = AuthorizationCode(
                      code=code,
                      client_id=client.client_id,
                      redirect_uri=request.redirect_uri,
                      scope=request.scope,
                      nonce=request.data.get('nonce'),
                      user_id=request.user.id,
                  )
                  item.save()
          """
          raise NotImplementedError()
  
      def validate_authorization_request(self):
          if not is_openid_scope(self.request.scope):
              raise InvalidScopeError(
                  'Missing "openid" scope',
                  redirect_uri=self.request.redirect_uri,
                  redirect_fragment=True,
              )
          self.register_hook(
              'after_validate_authorization_request',
              lambda grant: validate_nonce(
                  grant.request, grant.exists_nonce, required=True)
          )
          return validate_code_authorization_request(self)
  
      def create_granted_params(self, grant_user):
          self.request.user = grant_user
          client = self.request.client
  
          if hasattr(self, 'create_authorization_code'):  # pragma: no cover
              deprecate('Use "generate_authorization_code" instead', '1.0')
              code = self.create_authorization_code(client, grant_user, self.request)
          else:
              code = self.generate_authorization_code()
              self.save_authorization_code(code, self.request)
  
          params = [('code', code)]
          token = self.generate_token(
              grant_type='implicit',
              user=grant_user,
              scope=self.request.scope,
              include_refresh_token=False
          )
  
          response_types = self.request.response_type.split()
          if 'token' in response_types:
              log.debug('Grant token %r to %r', token, client)
              self.server.save_token(token, self.request)
              if 'id_token' in response_types:
                  token = self.process_implicit_token(token, code)
          else:
              # response_type is "code id_token"
              token = {
                  'expires_in': token['expires_in'],
                  'scope': token['scope']
              }
              token = self.process_implicit_token(token, code)
  
          params.extend([(k, token[k]) for k in token])
          return params
  