44from copy import deepcopy
55from typing import Any , Generator , Optional , Union
66
7+
78from scrapy import Spider , signals
89from scrapy .crawler import Crawler
910from scrapy .exceptions import NotConfigured
1516from twisted .internet .defer import Deferred , inlineCallbacks
1617from zyte_api import AsyncZyteAPI , RequestError
1718from zyte_api .apikey import NoApiKey
18- from zyte_api .constants import API_URL
1919
2020from ._params import _ParamParser
2121from .responses import ZyteAPIResponse , ZyteAPITextResponse , _process_response
2222from .utils import (
2323 _AUTOTHROTTLE_DONT_ADJUST_DELAY_SUPPORT ,
24+ _X402_SUPPORT ,
2425 USER_AGENT ,
2526 _build_from_crawler ,
2627)
@@ -95,7 +96,7 @@ def __init__(
9596 # https://github.com/scrapy-plugins/scrapy-zyte-api/issues/58
9697 crawler .zyte_api_client = client # type: ignore[attr-defined]
9798 self ._client : AsyncZyteAPI = crawler .zyte_api_client # type: ignore[attr-defined]
98- logger . info ( "Using a Zyte API key starting with %r" , self ._client . api_key [: 7 ] )
99+ self ._log_auth ( )
99100 verify_installed_reactor (
100101 "twisted.internet.asyncioreactor.AsyncioSelectorReactor"
101102 )
@@ -133,6 +134,21 @@ def __init__(
133134 def from_crawler (cls , crawler ):
134135 return cls (crawler .settings , crawler )
135136
137+ def _log_auth (self ):
138+ if _X402_SUPPORT :
139+ auth_type = (
140+ "a Zyte API key"
141+ if self ._client .auth .type == "zyte"
142+ else "an Ethereum private key"
143+ )
144+ logger .info (
145+ f"Using { auth_type } starting with { self ._client .auth .key [:7 ]!r} "
146+ )
147+ else :
148+ logger .info (
149+ f"Using a Zyte API key starting with { self ._client .api_key [:7 ]!r} "
150+ )
151+
136152 async def engine_started (self ):
137153 self ._session = self ._client .session (trust_env = self ._trust_env )
138154 if not self ._cookies_enabled :
@@ -153,27 +169,26 @@ async def engine_started(self):
153169
154170 @staticmethod
155171 def _build_client (settings ):
172+ kwargs = {}
173+ if api_key := settings .get ("ZYTE_API_KEY" ):
174+ kwargs ["api_key" ] = api_key
175+ if _X402_SUPPORT and (eth_key := settings .get ("ZYTE_API_ETH_KEY" )):
176+ kwargs ["eth_key" ] = eth_key
177+ if api_url := settings .get ("ZYTE_API_URL" ):
178+ kwargs ["api_url" ] = api_url
156179 try :
157180 return AsyncZyteAPI (
158- # To allow users to have a key defined in Scrapy settings and
159- # in a environment variable, and be able to cause the
160- # environment variable to be used instead of the setting by
161- # overriding the setting on the command-line to be an empty
162- # string, we do not support setting empty string keys through
163- # settings.
164- api_key = settings .get ("ZYTE_API_KEY" ) or None ,
165- api_url = settings .get ("ZYTE_API_URL" ) or API_URL ,
166181 n_conn = settings .getint ("CONCURRENT_REQUESTS" ),
167- user_agent = settings .get ("_ZYTE_API_USER_AGENT" , default = USER_AGENT ),
182+ user_agent = settings .get ("_ZYTE_API_USER_AGENT" , USER_AGENT ),
183+ ** kwargs ,
168184 )
169185 except NoApiKey :
170- logger .warning (
171- "'ZYTE_API_KEY' must be set in the spider settings or env var "
172- "in order for ScrapyZyteAPIDownloadHandler to work."
173- )
174- raise NotConfigured (
175- "Your Zyte API key is not set. Set ZYTE_API_KEY to your API key."
186+ message = (
187+ "No authentication data provided. See "
188+ "https://scrapy-zyte-api.readthedocs.io/en/latest/setup.html#auth"
176189 )
190+ logger .warning (message )
191+ raise NotConfigured (message )
177192
178193 def _create_handler (self , path : Any ) -> Any :
179194 dhcls = load_object (path )
0 commit comments