    def _new_spawner(self, server_name, spawner_class=None, **kwargs):
        """Create a new spawner"""
        if spawner_class is None:
            spawner_class = self.spawner_class
        self.log.debug("Creating %s for %s:%s", spawner_class, self.name, server_name)

        orm_spawner = self.orm_spawners.get(server_name)
        if orm_spawner is None:
            orm_spawner = self._new_orm_spawner(server_name)
        if server_name == '' and self.state:
            # migrate user.state to spawner.state
            orm_spawner.state = self.state
            self.state = None

        # use fully quoted name for client_id because it will be used in cookie-name
        # self.escaped_name may contain @ which is legal in URLs but not cookie keys
        client_id = f'jupyterhub-user-{quote(self.name)}'
        if server_name:
            client_id = f'{client_id}-{quote(server_name)}'

        trusted_alt_names = []
        trusted_alt_names.extend(self.settings.get('trusted_alt_names', []))
        if self.settings.get('subdomain_host'):
            trusted_alt_names.append('DNS:' + self.domain)

        spawn_kwargs = dict(
            user=self,
            orm_spawner=orm_spawner,
            hub=self.settings.get('hub'),
            authenticator=self.authenticator,
            config=self.settings.get('config'),
            proxy_spec=url_path_join(
                self.proxy_spec, url_escape_path(server_name), '/'
            ),
            _deprecated_db_session=self.db,
            oauth_client_id=client_id,
            cookie_options=self.settings.get('cookie_options', {}),
            cookie_host_prefix_enabled=self.settings.get(
                "cookie_host_prefix_enabled", False
            ),
            trusted_alt_names=trusted_alt_names,
            user_options=orm_spawner.user_options or {},
        )

        if self.settings.get('internal_ssl'):
            ssl_kwargs = dict(
                internal_ssl=self.settings.get('internal_ssl'),
                internal_trust_bundles=self.settings.get('internal_trust_bundles'),
                internal_certs_location=self.settings.get('internal_certs_location'),
            )
            spawn_kwargs.update(ssl_kwargs)

        # public URLs
        if self.settings.get("public_url"):
            public_url = self.settings["public_url"]
            hub = self.settings.get('hub')
            if hub is None:
                # only in mock tests
                hub_path = "/hub/"
            else:
                hub_path = hub.base_url
            spawn_kwargs["public_hub_url"] = urlunparse(
                public_url._replace(path=hub_path)
            )
        spawn_kwargs["public_url"] = self.public_url(server_name)

        # update with kwargs. Mainly for testing.
        spawn_kwargs.update(kwargs)
        spawner = spawner_class(**spawn_kwargs)
        spawner.load_state(orm_spawner.state or {})
        return spawner
Create a new spawner
jupyterhub/user.py