Skip to content

Commit

Permalink
Fix blocks api and add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
holgern committed Mar 7, 2023
1 parent 562f418 commit c436604
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 12 deletions.
47 changes: 42 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,53 @@ mp = MempoolAPI()
```


### API documentation
### API Documentation
https://mempool.space/docs/api/rest

### Test
## Test Suite

Run unit tests with:
### Set up the test environment

Install the test-runner dependencies:
```
# after installing pytest using pip3
pytest tests
pip3 install -r requirements-test.txt
```

Then make the `pymempool` python module visible/importable to the tests by installing the local dev dir as an editable module:
```
# from the repo root
pip3 install -e .
```

### Running the test suite
Run the whole test suite:
```
# from the repo root
pytest
```

Run a specific test file:
```
pytest test/test_this_file.py
```

Run a specific test:
```
pytest test/test_this_file.py::test_this_specific_test
```

### Running tests with tox

Install tox

```
pip install tox
```

Run tests

```
tox
```

## License
Expand Down
33 changes: 26 additions & 7 deletions pymempool/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
from requests.packages import urllib3


class MempoolAPI:
Expand All @@ -19,7 +19,7 @@ def __init__(
if not request_verify:
warnings.filterwarnings('ignore', message='Unverified HTTPS request')
self.session = requests.Session()
retries = Retry(
retries = urllib3.util.retry.Retry(
total=retries, backoff_factor=0.5, status_forcelist=[502, 503, 504]
)
self.session.mount('https://', HTTPAdapter(max_retries=retries))
Expand All @@ -35,11 +35,9 @@ def __request(self, url):
)
except requests.exceptions.RequestException:
raise

try:
response.raise_for_status()
content = json.loads(response.content.decode('utf-8'))
return content

except Exception:
# check if json (with error message) is returned
try:
Expand All @@ -49,6 +47,15 @@ def __request(self, url):
except json.decoder.JSONDecodeError:
pass
raise
try:
decoded_content = response.content.decode('utf-8')
content = json.loads(decoded_content)
return content
except UnicodeDecodeError:
return response.content
except json.decoder.JSONDecodeError:
return response.content.decode('utf-8')
raise

def __send(self, url, data):
# print(url)
Expand Down Expand Up @@ -189,10 +196,22 @@ def get_blocks(self, start_height=None):
"""Returns the 10 newest blocks starting at the tip or at :start_height if
specified."""
if start_height is None:
api_url = f'{self.api_base_url}blocks'
api_url = f'{self.api_base_url}v1/blocks'
else:
start_height = int(start_height)
api_url = f'{self.api_base_url}blocks/{start_height}'
api_url = f'{self.api_base_url}v1/blocks/{start_height}'
return self.__request(api_url)

def get_blocks_bulk(self, minHeight, maxHeight=None):
"""Returns the 10 newest blocks starting at the tip or at :start_height if
specified."""
if maxHeight is None:
minHeight = int(minHeight)
api_url = f'{self.api_base_url}v1/blocks-bulk/{minHeight}'
else:
minHeight = int(minHeight)
maxHeight = int(maxHeight)
api_url = f'{self.api_base_url}v1/blocks-bulk/{minHeight}/{maxHeight}'
return self.__request(api_url)

def get_mempool_blocks_fee(self):
Expand Down
37 changes: 37 additions & 0 deletions tests/test_addresses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import unittest
from pymempool import MempoolAPI

class TestAddresses(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.address = "1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv"

def test_address(self):
api = MempoolAPI()

ret = api.get_address(self.address)
self.assertIsInstance(ret, dict)

def test_address_transactions(self):
api = MempoolAPI()

ret = api.get_address_transactions(self.address)
self.assertIsInstance(ret, list)

def test_address_transactions_chain(self):
api = MempoolAPI()

ret = api.get_address_transactions_chain(self.address)
self.assertIsInstance(ret, list)

def test_address_transactions_mempool(self):
api = MempoolAPI()

ret = api.get_address_transactions_mempool(self.address)
self.assertIsInstance(ret, list)

def test_address_transactions_utxo(self):
api = MempoolAPI()

ret = api.get_address_utxo(self.address)
self.assertIsInstance(ret, list)
86 changes: 86 additions & 0 deletions tests/test_blocks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import unittest

from pymempool import MempoolAPI


class TestBlocks(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.hash = "000000000000000015dc777b3ff2611091336355d3f0ee9766a2cf3be8e4b1ce"
cls.index = "216"
cls.height = "363366"

def test_block(self):
api = MempoolAPI()

ret = api.get_block(self.hash)
self.assertIsInstance(ret, dict)
self.assertEqual(ret["height"], int(self.height))

def test_block_header(self):
api = MempoolAPI()

ret = api.get_block_header(self.hash)
self.assertIsInstance(ret, str)

def test_block_height(self):
api = MempoolAPI()

ret = api.get_block_height(self.height)
self.assertIsInstance(ret, str)
self.assertEqual(ret, self.hash)

def test_block_raw(self):
api = MempoolAPI()

ret = api.get_block_raw(self.hash)
self.assertIsInstance(ret, bytes)

def test_block_status(self):
api = MempoolAPI()

ret = api.get_block_status(self.hash)
self.assertIsInstance(ret, dict)
self.assertEqual(ret["height"], int(self.height))

def test_block_tip_height(self):
api = MempoolAPI()

ret = api.get_block_tip_height()
self.assertIsInstance(ret, int)

def test_block_tip_hash(self):
api = MempoolAPI()

ret = api.get_block_tip_hash()
self.assertIsInstance(ret, str)

def test_block_transaction_id(self):
api = MempoolAPI()

ret = api.get_block_transaction_id(self.hash, self.index)
self.assertIsInstance(ret, str)

def test_block_transaction_ids(self):
api = MempoolAPI()

ret = api.get_block_transaction_ids(self.hash)
self.assertIsInstance(ret, list)

def test_block_transactions(self):
api = MempoolAPI()

ret = api.get_block_transactions(self.hash)
self.assertIsInstance(ret, list)

def test_blocks(self):
api = MempoolAPI()

ret = api.get_blocks(self.height)
self.assertIsInstance(ret, list)

# def test_blocks_bulk(self):
# api = MempoolAPI()
#
# ret = api.get_blocks_bulk(self.height, self.height)
# self.assertIsInstance(ret, list)
8 changes: 8 additions & 0 deletions tests/test_general.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import unittest
from pymempool import MempoolAPI

class TestGeneral(unittest.TestCase):
def test_difficulty(self):
api = MempoolAPI()
ret = api.get_difficulty_adjustment()
self.assertTrue(len(ret) > 0)

0 comments on commit c436604

Please sign in to comment.