Skip to content

Commit 53fef9e

Browse files
Keep test replays in /tmp (#488)
1 parent c6c3051 commit 53fef9e

28 files changed

+252
-153
lines changed

poetry.lock

Lines changed: 136 additions & 125 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

requirements.dev.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ apscheduler==3.9.1 ; python_version >= "3.10" and python_version < "3.11"
88
argcomplete==2.0.0 ; python_version >= "3.10" and python_version < "3.11"
99
astor==0.8.1 ; python_version >= "3.10" and python_version < "3.11"
1010
async-timeout==4.0.2 ; python_version >= "3.10" and python_version < "3.11"
11-
asyncclick==8.1.3.2 ; python_version >= "3.10" and python_version < "3.11"
11+
asyncclick==8.1.3.4 ; python_version >= "3.10" and python_version < "3.11"
1212
asyncpg==0.26.0 ; python_version >= "3.10" and python_version < "3.11"
1313
attrs==21.4.0 ; python_version >= "3.10" and python_version < "3.11"
1414
babel==2.10.3 ; python_version >= "3.10" and python_version < "3.11"
1515
black==22.8.0 ; python_version >= "3.10" and python_version < "3.11"
1616
bump2version==1.0.1 ; python_version >= "3.10" and python_version < "3.11"
17-
certifi==2022.6.15.1 ; python_version >= "3.10" and python_version < "3.11"
17+
certifi==2022.9.14 ; python_version >= "3.10" and python_version < "3.11"
1818
chardet==4.0.0 ; python_version >= "3.10" and python_version < "3.11"
1919
charset-normalizer==2.1.1 ; python_version >= "3.10" and python_version < "3.11"
2020
click==8.0.4 ; python_version >= "3.10" and python_version < "3.11"
@@ -24,9 +24,9 @@ datamodel-code-generator==0.13.1 ; python_version >= "3.10" and python_version <
2424
deprecation==2.1.0 ; python_version >= "3.10" and python_version < "3.11"
2525
diff-cover==6.5.1 ; python_version >= "3.10" and python_version < "3.11"
2626
dnspython==2.2.1 ; python_version >= "3.10" and python_version < "3.11"
27-
docker==5.0.3 ; python_version >= "3.10" and python_version < "3.11"
27+
docker==6.0.0 ; python_version >= "3.10" and python_version < "3.11"
2828
docutils==0.19 ; python_version >= "3.10" and python_version < "3.11"
29-
email-validator==1.2.1 ; python_version >= "3.10" and python_version < "3.11"
29+
email-validator==1.3.0 ; python_version >= "3.10" and python_version < "3.11"
3030
entrypoints==0.4 ; python_version >= "3.10" and python_version < "3.11"
3131
execnet==1.9.0 ; python_version >= "3.10" and python_version < "3.11"
3232
flake8-bugbear==22.9.11 ; python_version >= "3.10" and python_version < "3.11"
@@ -39,7 +39,7 @@ flakeheaven==2.1.3 ; python_version >= "3.10" and python_version < "3.11"
3939
frozenlist==1.3.1 ; python_version >= "3.10" and python_version < "3.11"
4040
genson==1.2.2 ; python_version >= "3.10" and python_version < "3.11"
4141
html2text==2020.1.16 ; python_version >= "3.10" and python_version < "3.11"
42-
idna==3.3 ; python_version >= "3.10" and python_version < "3.11"
42+
idna==3.4 ; python_version >= "3.10" and python_version < "3.11"
4343
imagesize==1.4.1 ; python_version >= "3.10" and python_version < "3.11"
4444
inflect==5.6.2 ; python_version >= "3.10" and python_version < "3.11"
4545
iniconfig==1.1.1 ; python_version >= "3.10" and python_version < "3.11"
@@ -83,7 +83,7 @@ pytest==7.1.3 ; python_version >= "3.10" and python_version < "3.11"
8383
python-dotenv==0.19.2 ; python_version >= "3.10" and python_version < "3.11"
8484
pytz-deprecation-shim==0.1.0.post0 ; python_version >= "3.10" and python_version < "3.11"
8585
pytz==2022.2.1 ; python_version >= "3.10" and python_version < "3.11"
86-
pywin32==227 ; python_version >= "3.10" and python_version < "3.11" and sys_platform == "win32"
86+
pywin32==304 ; python_version >= "3.10" and python_version < "3.11" and sys_platform == "win32"
8787
pyyaml==6.0 ; python_version >= "3.10" and python_version < "3.11"
8888
requests==2.28.1 ; python_version >= "3.10" and python_version < "3.11"
8989
ruamel-yaml-clib==0.2.6 ; platform_python_implementation == "CPython" and python_version < "3.11" and python_version >= "3.10"

requirements.pytezos.txt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ argon2-cffi-bindings==21.2.0 ; python_version >= "3.10" and python_version < "3.
1010
argon2-cffi==21.3.0 ; python_version >= "3.10" and python_version < "3.11"
1111
asttokens==2.0.8 ; python_version >= "3.10" and python_version < "3.11"
1212
async-timeout==4.0.2 ; python_version >= "3.10" and python_version < "3.11"
13-
asyncclick==8.1.3.2 ; python_version >= "3.10" and python_version < "3.11"
13+
asyncclick==8.1.3.4 ; python_version >= "3.10" and python_version < "3.11"
1414
asyncpg==0.26.0 ; python_version >= "3.10" and python_version < "3.11"
1515
attrs==21.4.0 ; python_version >= "3.10" and python_version < "3.11"
1616
backcall==0.2.0 ; python_version >= "3.10" and python_version < "3.11"
@@ -21,7 +21,7 @@ bleach==5.0.1 ; python_version >= "3.10" and python_version < "3.11"
2121
bson==0.5.10 ; python_version >= "3.10" and python_version < "3.11"
2222
cached-property==1.5.2 ; python_version >= "3.10" and python_version < "3.11"
2323
cattrs==22.1.0 ; python_version >= "3.10" and python_version < "3.11"
24-
certifi==2022.6.15.1 ; python_version >= "3.10" and python_version < "3.11"
24+
certifi==2022.9.14 ; python_version >= "3.10" and python_version < "3.11"
2525
cffi==1.15.1 ; python_version >= "3.10" and python_version < "3.11"
2626
chardet==4.0.0 ; python_version >= "3.10" and python_version < "3.11"
2727
charset-normalizer==2.1.1 ; python_version >= "3.10" and python_version < "3.11"
@@ -34,19 +34,19 @@ decorator==5.1.1 ; python_version >= "3.10" and python_version < "3.11"
3434
defusedxml==0.7.1 ; python_version >= "3.10" and python_version < "3.11"
3535
deprecation==2.1.0 ; python_version >= "3.10" and python_version < "3.11"
3636
dnspython==2.2.1 ; python_version >= "3.10" and python_version < "3.11"
37-
docker==5.0.3 ; python_version >= "3.10" and python_version < "3.11"
38-
email-validator==1.2.1 ; python_version >= "3.10" and python_version < "3.11"
37+
docker==6.0.0 ; python_version >= "3.10" and python_version < "3.11"
38+
email-validator==1.3.0 ; python_version >= "3.10" and python_version < "3.11"
3939
entrypoints==0.4 ; python_version >= "3.10" and python_version < "3.11"
4040
eth-hash==0.3.3 ; python_version >= "3.10" and python_version < "3.11"
41-
eth-typing==3.1.0 ; python_version >= "3.10" and python_version < "3.11"
41+
eth-typing==3.2.0 ; python_version >= "3.10" and python_version < "3.11"
4242
eth-utils==2.0.0 ; python_version >= "3.10" and python_version < "3.11"
4343
exceptiongroup==1.0.0rc9 ; python_version >= "3.10" and python_version < "3.11"
4444
executing==1.0.0 ; python_version >= "3.10" and python_version < "3.11"
4545
fastecdsa==2.2.3 ; python_version >= "3.10" and python_version < "3.11"
46-
fastjsonschema==2.16.1 ; python_version >= "3.10" and python_version < "3.11"
46+
fastjsonschema==2.16.2 ; python_version >= "3.10" and python_version < "3.11"
4747
frozenlist==1.3.1 ; python_version >= "3.10" and python_version < "3.11"
4848
genson==1.2.2 ; python_version >= "3.10" and python_version < "3.11"
49-
idna==3.3 ; python_version >= "3.10" and python_version < "3.11"
49+
idna==3.4 ; python_version >= "3.10" and python_version < "3.11"
5050
inflect==5.6.2 ; python_version >= "3.10" and python_version < "3.11"
5151
ipykernel==6.15.3 ; python_version >= "3.10" and python_version < "3.11"
5252
ipython-genutils==0.2.0 ; python_version >= "3.10" and python_version < "3.11"
@@ -106,16 +106,16 @@ pysha3==1.0.2 ; python_version >= "3.10" and python_version < "3.11"
106106
pysignalr==0.1.2 ; python_version >= "3.10" and python_version < "3.11"
107107
pysnooper==1.1.1 ; python_version >= "3.10" and python_version < "3.11"
108108
pysodium==0.7.12 ; python_version >= "3.10" and python_version < "3.11"
109-
pytezos==3.6.1 ; python_version >= "3.10" and python_version < "3.11"
109+
pytezos==3.7.0 ; python_version >= "3.10" and python_version < "3.11"
110110
python-dateutil==2.8.2 ; python_version >= "3.10" and python_version < "3.11"
111111
python-dotenv==0.19.2 ; python_version >= "3.10" and python_version < "3.11"
112112
pytz-deprecation-shim==0.1.0.post0 ; python_version >= "3.10" and python_version < "3.11"
113113
pytz==2022.2.1 ; python_version >= "3.10" and python_version < "3.11"
114114
pytzdata==2020.1 ; python_version >= "3.10" and python_version < "3.11"
115-
pywin32==227 ; python_version >= "3.10" and python_version < "3.11" and sys_platform == "win32"
116-
pywinpty==2.0.7 ; python_version >= "3.10" and python_version < "3.11" and os_name == "nt"
115+
pywin32==304 ; python_version >= "3.10" and python_version < "3.11" and sys_platform == "win32"
116+
pywinpty==2.0.8 ; python_version >= "3.10" and python_version < "3.11" and os_name == "nt"
117117
pyyaml==6.0 ; python_version >= "3.10" and python_version < "3.11"
118-
pyzmq==23.2.1 ; python_version >= "3.10" and python_version < "3.11"
118+
pyzmq==24.0.0 ; python_version >= "3.10" and python_version < "3.11"
119119
requests==2.28.1 ; python_version >= "3.10" and python_version < "3.11"
120120
ruamel-yaml-clib==0.2.6 ; platform_python_implementation == "CPython" and python_version < "3.11" and python_version >= "3.10"
121121
ruamel-yaml==0.17.21 ; python_version >= "3.10" and python_version < "3.11"

requirements.slim.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ aiosqlite==0.17.0 ; python_version >= "3.10" and python_version < "3.11"
55
anyio==3.6.1 ; python_version >= "3.10" and python_version < "3.11"
66
apscheduler==3.9.1 ; python_version >= "3.10" and python_version < "3.11"
77
async-timeout==4.0.2 ; python_version >= "3.10" and python_version < "3.11"
8-
asyncclick==8.1.3.2 ; python_version >= "3.10" and python_version < "3.11"
8+
asyncclick==8.1.3.4 ; python_version >= "3.10" and python_version < "3.11"
99
asyncpg==0.26.0 ; python_version >= "3.10" and python_version < "3.11"
1010
attrs==21.4.0 ; python_version >= "3.10" and python_version < "3.11"
11-
certifi==2022.6.15.1 ; python_version >= "3.10" and python_version < "3.11"
11+
certifi==2022.9.14 ; python_version >= "3.10" and python_version < "3.11"
1212
charset-normalizer==2.1.1 ; python_version >= "3.10" and python_version < "3.11"
1313
colorama==0.4.5 ; python_version >= "3.10" and python_version < "3.11" and platform_system == "Windows"
1414
frozenlist==1.3.1 ; python_version >= "3.10" and python_version < "3.11"
15-
idna==3.3 ; python_version >= "3.10" and python_version < "3.11"
15+
idna==3.4 ; python_version >= "3.10" and python_version < "3.11"
1616
iso8601==1.0.2 ; python_version >= "3.10" and python_version < "3.11"
1717
msgpack==1.0.4 ; python_version >= "3.10" and python_version < "3.11"
1818
multidict==6.0.2 ; python_version >= "3.10" and python_version < "3.11"

requirements.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@ anyio==3.6.1 ; python_version >= "3.10" and python_version < "3.11"
66
apscheduler==3.9.1 ; python_version >= "3.10" and python_version < "3.11"
77
argcomplete==2.0.0 ; python_version >= "3.10" and python_version < "3.11"
88
async-timeout==4.0.2 ; python_version >= "3.10" and python_version < "3.11"
9-
asyncclick==8.1.3.2 ; python_version >= "3.10" and python_version < "3.11"
9+
asyncclick==8.1.3.4 ; python_version >= "3.10" and python_version < "3.11"
1010
asyncpg==0.26.0 ; python_version >= "3.10" and python_version < "3.11"
1111
attrs==21.4.0 ; python_version >= "3.10" and python_version < "3.11"
1212
black==22.8.0 ; python_version >= "3.10" and python_version < "3.11"
13-
certifi==2022.6.15.1 ; python_version >= "3.10" and python_version < "3.11"
13+
certifi==2022.9.14 ; python_version >= "3.10" and python_version < "3.11"
1414
chardet==4.0.0 ; python_version >= "3.10" and python_version < "3.11"
1515
charset-normalizer==2.1.1 ; python_version >= "3.10" and python_version < "3.11"
1616
click==8.0.4 ; python_version >= "3.10" and python_version < "3.11"
1717
colorama==0.4.5 ; python_version >= "3.10" and python_version < "3.11" and platform_system == "Windows"
1818
datamodel-code-generator==0.13.1 ; python_version >= "3.10" and python_version < "3.11"
1919
dnspython==2.2.1 ; python_version >= "3.10" and python_version < "3.11"
20-
email-validator==1.2.1 ; python_version >= "3.10" and python_version < "3.11"
20+
email-validator==1.3.0 ; python_version >= "3.10" and python_version < "3.11"
2121
frozenlist==1.3.1 ; python_version >= "3.10" and python_version < "3.11"
2222
genson==1.2.2 ; python_version >= "3.10" and python_version < "3.11"
23-
idna==3.3 ; python_version >= "3.10" and python_version < "3.11"
23+
idna==3.4 ; python_version >= "3.10" and python_version < "3.11"
2424
inflect==5.6.2 ; python_version >= "3.10" and python_version < "3.11"
2525
iso8601==1.0.2 ; python_version >= "3.10" and python_version < "3.11"
2626
isort==5.10.1 ; python_version >= "3.10" and python_version < "3.11"

src/dipdup/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ class HTTPConfig:
175175
:param connection_limit: Number of simultaneous connections
176176
:param connection_timeout: Connection timeout in seconds
177177
:param batch_size: Number of items fetched in a single paginated request (for some APIs)
178+
:param replay_path: Development-only option to replay HTTP requests from a file
178179
"""
179180

180181
retry_count: Optional[int] = None
@@ -185,6 +186,7 @@ class HTTPConfig:
185186
connection_limit: Optional[int] = None # default 100
186187
connection_timeout: Optional[int] = None # default 60
187188
batch_size: Optional[int] = None
189+
replay_path: Optional[str] = None
188190

189191
def merge(self, other: Optional['HTTPConfig']) -> 'HTTPConfig':
190192
"""Set missing values from other config"""

src/dipdup/http.py

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
import hashlib
23
import logging
34
import platform
45
from contextlib import suppress
@@ -13,11 +14,13 @@
1314
import aiohttp
1415
import orjson
1516
from aiolimiter import AsyncLimiter
17+
from genericpath import isfile
1618

1719
from dipdup import __version__
1820
from dipdup.config import HTTPConfig
1921
from dipdup.exceptions import InvalidRequestError
2022
from dipdup.prometheus import Metrics
23+
from dipdup.utils import touch
2124

2225
safe_exceptions = (
2326
aiohttp.ClientConnectionError,
@@ -115,7 +118,13 @@ def _session(self) -> aiohttp.ClientSession:
115118
return self.__session
116119

117120
# TODO: Move to separate method to cover SignalR negotiations too
118-
async def _retry_request(self, method: str, url: str, weight: int = 1, **kwargs):
121+
async def _retry_request(
122+
self,
123+
method: str,
124+
url: str,
125+
weight: int = 1,
126+
**kwargs,
127+
):
119128
"""Retry a request in case of failure sleeping according to config"""
120129
attempt = 1
121130
retry_sleep = self._config.retry_sleep or 0
@@ -158,7 +167,13 @@ async def _retry_request(self, method: str, url: str, weight: int = 1, **kwargs)
158167
multiplier = 1 if ratelimit_sleep else self._config.retry_multiplier or 1
159168
retry_sleep *= multiplier
160169

161-
async def _request(self, method: str, url: str, weight: int = 1, **kwargs):
170+
async def _request(
171+
self,
172+
method: str,
173+
url: str,
174+
weight: int = 1,
175+
**kwargs,
176+
):
162177
"""Wrapped aiohttp call with preconfigured headers and ratelimiting"""
163178
if not url.startswith(self._url):
164179
url = self._url + '/' + url.lstrip('/')
@@ -187,6 +202,31 @@ async def _request(self, method: str, url: str, weight: int = 1, **kwargs):
187202
return await response.json()
188203
return await response.read()
189204

205+
async def _replay_request(
206+
self,
207+
method: str,
208+
url: str,
209+
weight: int = 1,
210+
**kwargs,
211+
):
212+
request_hash = hashlib.sha256(
213+
f'{self._url} {method} {url} {kwargs}'.encode(),
214+
).hexdigest()
215+
if not self._config.replay_path:
216+
raise Exception
217+
replay_path = self._config.replay_path.rstrip('/') + '/' + request_hash
218+
219+
if isfile(replay_path):
220+
with open(replay_path, 'rb') as file:
221+
return orjson.loads(file.read())
222+
else:
223+
response = await self._retry_request(method, url, weight, **kwargs)
224+
if response:
225+
touch(replay_path)
226+
with open(replay_path, 'wb') as file:
227+
file.write(orjson.dumps(response))
228+
return response
229+
190230
async def request(
191231
self,
192232
method: str,
@@ -195,7 +235,10 @@ async def request(
195235
**kwargs,
196236
) -> Any:
197237
"""Performs an HTTP request."""
198-
return await self._retry_request(method, url, weight, **kwargs)
238+
if self._config.replay_path:
239+
return await self._replay_request(method, url, weight, **kwargs)
240+
else:
241+
return await self._retry_request(method, url, weight, **kwargs)
199242

200243
def set_user_agent(self, *args: str) -> None:
201244
"""Add list of arguments to User-Agent header"""

tests/integration_tests/hic_et_nunc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ datasources:
1717
tzkt_mainnet:
1818
kind: tzkt
1919
url: ${TZKT_URL:-https://api.tzkt.io}
20+
http:
21+
replay_path: /tmp/dipdup/replays
2022

2123
indexes:
2224
hen_mainnet:

tests/integration_tests/quipuswap.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ datasources:
2323
tzkt_mainnet:
2424
kind: tzkt
2525
url: https://api.tzkt.io
26+
http:
27+
replay_path: /tmp/dipdup/replays
2628

2729
templates:
2830
quipuswap_fa12:

tests/integration_tests/registrydao.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ datasources:
1414
tzkt:
1515
kind: tzkt
1616
url: ${TZKT_URL:-https://api.tzkt.io}
17+
http:
18+
replay_path: /tmp/dipdup/replays
1719

1820
templates:
1921

0 commit comments

Comments
 (0)