blockapi 1.3.2__tar.gz → 1.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. {blockapi-1.3.2 → blockapi-1.4.0}/PKG-INFO +1 -1
  2. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/nft/magic_eden.py +35 -6
  3. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/nft/opensea.py +34 -7
  4. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi.egg-info/PKG-INFO +1 -1
  5. {blockapi-1.3.2 → blockapi-1.4.0}/setup.py +1 -1
  6. {blockapi-1.3.2 → blockapi-1.4.0}/LICENSE.md +0 -0
  7. {blockapi-1.3.2 → blockapi-1.4.0}/README.md +0 -0
  8. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/__init__.py +0 -0
  9. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/services.py +0 -0
  10. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/__init__.py +0 -0
  11. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/test_blockapi.py +0 -0
  12. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/test_num.py +0 -0
  13. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/test_random_user_agent.py +0 -0
  14. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/__init__.py +0 -0
  15. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/__init__.py +0 -0
  16. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/conftest.py +0 -0
  17. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/covalenth/__init__.py +0 -0
  18. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/covalenth/test_ethereum.py +0 -0
  19. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/fake_sleep_provider.py +0 -0
  20. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/nft/__init__.py +0 -0
  21. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/nft/test_magic_eden.py +0 -0
  22. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/nft/test_opensea.py +0 -0
  23. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/nft/test_simple_hash.py +0 -0
  24. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/nft/test_unisat.py +0 -0
  25. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/perpetual/__init__.py +0 -0
  26. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/perpetual/test_perpetual.py +0 -0
  27. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/synthetix/__init__.py +0 -0
  28. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/synthetix/test_synthetix.py +0 -0
  29. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/test_blockchainos.py +0 -0
  30. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/test_blockchair_btc.py +0 -0
  31. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/test_blockchair_doge.py +0 -0
  32. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/test_blockchair_ltc.py +0 -0
  33. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/test_cosmos.py +0 -0
  34. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/test_ethplorer.py +0 -0
  35. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/test_multisources.py +0 -0
  36. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/test_optimistic_etherscan.py +0 -0
  37. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/test_solana.py +0 -0
  38. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/test_subscan_polkadot.py +0 -0
  39. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/test_sui.py +0 -0
  40. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/api/test_trezor_btc.py +0 -0
  41. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/test_base.py +0 -0
  42. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/test_blockchain_api.py +0 -0
  43. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/test_blockchain_mapping.py +0 -0
  44. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/test_data.py +0 -0
  45. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/test_enumerate_classes.py +0 -0
  46. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/test_generic.py +0 -0
  47. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test/v2/test_models.py +0 -0
  48. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/test_data.py +0 -0
  49. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/utils/__init__.py +0 -0
  50. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/utils/address.py +0 -0
  51. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/utils/datetime.py +0 -0
  52. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/utils/num.py +0 -0
  53. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/utils/user_agent.py +0 -0
  54. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/__init__.py +0 -0
  55. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/__init__.py +0 -0
  56. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/blockchainos.py +0 -0
  57. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/blockchair.py +0 -0
  58. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/cosmos.py +0 -0
  59. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/__init__.py +0 -0
  60. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/arbitrum.py +0 -0
  61. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/astar.py +0 -0
  62. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/avalanche.py +0 -0
  63. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/axie.py +0 -0
  64. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/base.py +0 -0
  65. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/binance_smart_chain.py +0 -0
  66. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/ethereum.py +0 -0
  67. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/fantom.py +0 -0
  68. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/heco.py +0 -0
  69. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/iotex.py +0 -0
  70. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/klaytn.py +0 -0
  71. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/moonbeam.py +0 -0
  72. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/palm.py +0 -0
  73. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/polygon.py +0 -0
  74. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/covalenth/rsk.py +0 -0
  75. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/debank.py +0 -0
  76. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/debank_maps.py +0 -0
  77. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/ethplorer.py +0 -0
  78. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/nft/__init__.py +0 -0
  79. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/nft/simple_hash.py +0 -0
  80. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/nft/unisat.py +0 -0
  81. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/optimistic_etherscan.py +0 -0
  82. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/perpetual/__init__.py +0 -0
  83. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/perpetual/perp_abi.py +0 -0
  84. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/perpetual/perpetual.py +0 -0
  85. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/solana.py +0 -0
  86. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/subscan.py +0 -0
  87. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/sui.py +0 -0
  88. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/synthetix/__init__.py +0 -0
  89. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/synthetix/synthetix.py +0 -0
  90. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/synthetix/synthetix_abi.py +0 -0
  91. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/terra.py +0 -0
  92. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/trezor.py +0 -0
  93. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/api/web3_utils.py +0 -0
  94. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/base.py +0 -0
  95. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/blockchain_mapping.py +0 -0
  96. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/coin_mapping.py +0 -0
  97. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/coins.py +0 -0
  98. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi/v2/models.py +0 -0
  99. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi.egg-info/SOURCES.txt +0 -0
  100. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi.egg-info/dependency_links.txt +0 -0
  101. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi.egg-info/requires.txt +0 -0
  102. {blockapi-1.3.2 → blockapi-1.4.0}/blockapi.egg-info/top_level.txt +0 -0
  103. {blockapi-1.3.2 → blockapi-1.4.0}/pyproject.toml +0 -0
  104. {blockapi-1.3.2 → blockapi-1.4.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: blockapi
3
- Version: 1.3.2
3
+ Version: 1.4.0
4
4
  Summary: BlockAPI library
5
5
  Home-page: https://github.com/crypkit/blockapi
6
6
  Author: Devmons s.r.o.
@@ -46,11 +46,21 @@ class MagicEdenApi(BlockchainApi, INftProvider, INftParser):
46
46
 
47
47
  coin_map = NotImplemented
48
48
 
49
- def __init__(self, sleep_provider):
49
+ def __init__(self, sleep_provider, max_listings=500, max_offers=500):
50
50
  super().__init__()
51
-
52
51
  self._sleep_provider = sleep_provider
53
52
 
53
+ self.max_offers = max_offers
54
+ if max_listings > 15000:
55
+ logger.warning(
56
+ 'Listings cap exceeding 15000 will cause an error: '
57
+ '"offset should be non-negative integer". '
58
+ 'Setting maximum to 15000.'
59
+ )
60
+ self.max_listings = 15000
61
+ else:
62
+ self.max_listings = max_listings
63
+
54
64
  def fetch_nfts(self, address: str) -> FetchResult:
55
65
  offset = 0
56
66
  limit = 500
@@ -192,7 +202,12 @@ class MagicEdenApi(BlockchainApi, INftProvider, INftParser):
192
202
  data_len = len(results)
193
203
  offset += limit
194
204
 
195
- if data.errors or not data.data or data_len < limit or offset > 15000:
205
+ if (
206
+ data.errors
207
+ or not data.data
208
+ or data_len < limit
209
+ or len(items) >= self.max_offers
210
+ ):
196
211
  return FetchResult(
197
212
  status_code=data.status_code,
198
213
  headers=data.headers,
@@ -257,7 +272,11 @@ class MagicEdenApi(BlockchainApi, INftProvider, INftParser):
257
272
  return str(spot_price * (1 - seller_fee - takers_fee - lp_fee))
258
273
 
259
274
  def fetch_listings(
260
- self, collection: str, cursor: Optional[str] = None
275
+ self,
276
+ collection: str,
277
+ cursor: Optional[str] = None,
278
+ sort="listPrice",
279
+ sort_direction="desc",
261
280
  ) -> FetchResult:
262
281
  offset = 0
263
282
  limit = 100
@@ -266,7 +285,12 @@ class MagicEdenApi(BlockchainApi, INftProvider, INftParser):
266
285
  while True:
267
286
  self._sleep_provider.sleep(self.base_url, self.api_options.rate_limit)
268
287
  data = self.get_data(
269
- 'get_listings', slug=collection, offset=offset, limit=limit
288
+ 'get_listings',
289
+ slug=collection,
290
+ offset=offset,
291
+ limit=limit,
292
+ sort=sort,
293
+ sort_direction=sort_direction,
270
294
  )
271
295
 
272
296
  if self._should_retry(data):
@@ -277,7 +301,12 @@ class MagicEdenApi(BlockchainApi, INftProvider, INftParser):
277
301
  offset += limit
278
302
 
279
303
  # note: if offset is greater than 15000, causes response "offset should be non-negative integer"
280
- if data.errors or not data.data or len(data.data) < limit or offset > 15000:
304
+ if (
305
+ data.errors
306
+ or not data.data
307
+ or len(data.data) < limit
308
+ or len(items) > self.max_listings
309
+ ):
281
310
  return FetchResult(
282
311
  status_code=data.status_code,
283
312
  headers=data.headers,
@@ -3,7 +3,6 @@ import logging
3
3
  from decimal import Decimal
4
4
  from typing import Callable, Iterable, Optional, Tuple
5
5
 
6
- from blockapi.utils.num import raw_to_decimals
7
6
  from blockapi.v2.base import (
8
7
  ApiException,
9
8
  BlockchainApi,
@@ -98,6 +97,8 @@ class OpenSeaApi(BlockchainApi, INftProvider, INftParser):
98
97
  blockchain: Blockchain,
99
98
  sleep_provider: ISleepProvider = None,
100
99
  limit: Optional[int] = None,
100
+ max_listings=500,
101
+ max_offers=500,
101
102
  ):
102
103
  super().__init__(api_key)
103
104
 
@@ -110,6 +111,9 @@ class OpenSeaApi(BlockchainApi, INftProvider, INftParser):
110
111
  self._sleep_provider = sleep_provider or SleepProvider()
111
112
  self._limit = limit
112
113
 
114
+ self.max_listings = max_listings
115
+ self.max_offers = max_offers
116
+
113
117
  def fetch_nfts(self, address: str, cursor: Optional[str] = None) -> FetchResult:
114
118
  logger.info(f'Fetch nfts from {address}, cursor={cursor}')
115
119
  return self._coalesce(self._yield_nfts(address, cursor))
@@ -256,17 +260,32 @@ class OpenSeaApi(BlockchainApi, INftProvider, INftParser):
256
260
  self, fetch_method: Callable, key: str, cursor: Optional[str] = None
257
261
  ) -> Iterable[Tuple[FetchResult, Optional[str]]]:
258
262
  cursors = set()
263
+ page_count = 0
264
+ item_count = 0
259
265
 
260
- count = 0
261
266
  while True:
262
267
  self._sleep_provider.sleep(self.base_url, self.api_options.rate_limit)
263
- count += 1
264
- logger.debug(f'Fetching page {count} of {key} from {cursor}')
268
+ page_count += 1
269
+ logger.debug(f'Fetching page {page_count} of {key} from {cursor}')
265
270
  fetched, next_cursor = fetch_method(key, cursor)
266
271
  if self._should_retry(fetched):
267
- count -= 1
272
+ page_count -= 1
268
273
  continue
269
274
 
275
+ # Count items for dynamic limiting
276
+ item_limit = None
277
+ if fetched.data:
278
+ current_items = 0
279
+ if 'offers' in fetched.data:
280
+ current_items = len(fetched.data['offers'])
281
+ item_limit = self.max_offers
282
+ elif 'listings' in fetched.data:
283
+ current_items = len(fetched.data['listings'])
284
+ item_limit = self.max_listings
285
+ # skip `'nfts' in fetched.data`, because it doesn't have a limit
286
+
287
+ item_count += current_items
288
+
270
289
  yield fetched, next_cursor
271
290
 
272
291
  if not next_cursor:
@@ -278,13 +297,19 @@ class OpenSeaApi(BlockchainApi, INftProvider, INftParser):
278
297
 
279
298
  cursors.add(cursor)
280
299
 
281
- if self._limit and count >= self._limit:
300
+ # Check both page and item limits
301
+ if self._limit and page_count >= self._limit:
302
+ break
303
+
304
+ if item_limit and item_count >= item_limit:
282
305
  break
283
306
 
284
307
  def _fetch_offers_page(
285
308
  self, method: str, collection: str, cursor: Optional[str] = None
286
309
  ) -> tuple[FetchResult, Optional[str]]:
287
- params = dict(next=cursor) if cursor else dict()
310
+ params = {'limit': 100} # the max limit allowed is 100 items per page
311
+ if cursor:
312
+ params['next'] = cursor
288
313
 
289
314
  fetched = self.get_data(
290
315
  method,
@@ -573,9 +598,11 @@ class OpenSeaApi(BlockchainApi, INftProvider, INftParser):
573
598
  errors = []
574
599
  last = None
575
600
  last_cursor = None
601
+
576
602
  for item, cursor in fetch_results:
577
603
  last_cursor = cursor
578
604
  last = item
605
+
579
606
  if item.data:
580
607
  data.append(item.data)
581
608
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: blockapi
3
- Version: 1.3.2
3
+ Version: 1.4.0
4
4
  Summary: BlockAPI library
5
5
  Home-page: https://github.com/crypkit/blockapi
6
6
  Author: Devmons s.r.o.
@@ -6,7 +6,7 @@ with open("README.md", "r") as f:
6
6
 
7
7
  PACKAGES = find_packages(where='.')
8
8
 
9
- __version__ = "1.3.2"
9
+ __version__ = "1.4.0"
10
10
 
11
11
  setuptools.setup(
12
12
  name='blockapi',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes