Repository: ethereum/web3.py

Issue:
BeaconAPI timed out within 10 seconds, unable to set timeout time
*OSX
* Python: 3.11.2

```
pip freeze
aiohttp==3.8.4
aiosignal==1.3.1
async-timeout==4.0.2
attrs==22.2.0
bitarray==2.7.3
certifi==2022.12.7
charset-normalizer==3.1.0
cytoolz==0.12.1
docutils==0.19
eth-abi==4.0.0
eth-account==0.8.0
eth-hash==0.5.1
eth-keyfile==0.6.1
eth-keys==0.4.0
eth-rlp==0.3.0
eth-typing==3.3.0
eth-utils==2.1.0
frozenlist==1.3.3
hexbytes==0.3.0
idna==3.4
jsonschema==4.17.3
lru-dict==1.1.8
multidict==6.0.4
parsimonious==0.9.0
protobuf==4.22.3
pycryptodome==3.17
pyrsistent==0.19.3
ranger-fm==1.9.3
regex==2023.3.23
requests==2.28.2
rlp==3.0.0
six==1.16.0
toolz==0.12.0
urllib3==1.26.15
web3==6.2.0
websockets==11.0.1
yarl==1.8.2
```


### What was wrong?
BeaconAPI timed out within 10 seconds, unable to set timeout time
```
clHttpProvider = HTTPProvider(clEndpoint,request_kwargs={'timeout': 60})
elHttpProvider = HTTPProvider(elEndpoint,request_kwargs={'timeout': 60})

w3 = Web3(elHttpProvider)
print(w3.is_connected())


beacon = Beacon(clEndpoint)
# Beacon()


validators = beacon.get_validators()
print(validators)

```

error: timeout



### How can it be fixed?
The timeout should be able to be set like an httpProvider





Discussion:

Resolving patch:
diff --git a/web3/beacon/api_endpoints.py b/web3/beacon/api_endpoints.py
--- a/web3/beacon/api_endpoints.py
+++ b/web3/beacon/api_endpoints.py
@@ -1,6 +1,8 @@
 # [ BEACON endpoints ]
 
 GET_GENESIS = "/eth/v1/beacon/genesis"
+
+# states
 GET_HASH_ROOT = "/eth/v1/beacon/states/{0}/root"
 GET_FORK_DATA = "/eth/v1/beacon/states/{0}/fork"
 GET_FINALITY_CHECKPOINT = "/eth/v1/beacon/states/{0}/finality_checkpoints"
@@ -8,15 +10,35 @@
 GET_VALIDATOR = "/eth/v1/beacon/states/{0}/validators/{1}"
 GET_VALIDATOR_BALANCES = "/eth/v1/beacon/states/{0}/validator_balances"
 GET_EPOCH_COMMITTEES = "/eth/v1/beacon/states/{0}/committees"
+GET_EPOCH_SYNC_COMMITTEES = "/eth/v1/beacon/states/{0}/sync_committees"
+GET_EPOCH_RANDAO = "/eth/v1/beacon/states/{0}/randao"
+
+# headers
 GET_BLOCK_HEADERS = "/eth/v1/beacon/headers"
 GET_BLOCK_HEADER = "/eth/v1/beacon/headers/{0}"
+
+# blocks
 GET_BLOCK = "/eth/v2/beacon/blocks/{0}"
 GET_BLOCK_ROOT = "/eth/v1/beacon/blocks/{0}/root"
 GET_BLOCK_ATTESTATIONS = "/eth/v1/beacon/blocks/{0}/attestations"
+GET_BLINDED_BLOCKS = "/eth/v1/beacon/blinded_blocks/{0}"
+
+# rewards
+GET_REWARDS = "/eth/v1/beacon/rewards/blocks/{0}"
+
+# light client
+GET_LIGHT_CLIENT_BOOTSTRAP_STRUCTURE = "/eth/v1/beacon/light_client/bootstrap/{0}"
+GET_LIGHT_CLIENT_UPDATES = "/eth/v1/beacon/light_client/updates"
+GET_LIGHT_CLIENT_FINALITY_UPDATE = "/eth/v1/beacon/light_client/finality_update"
+GET_LIGHT_CLIENT_OPTIMISTIC_UPDATE = "/eth/v1/beacon/light_client/optimistic_update"
+
+# pool
 GET_ATTESTATIONS = "/eth/v1/beacon/pool/attestations"
 GET_ATTESTER_SLASHINGS = "/eth/v1/beacon/pool/attester_slashings"
 GET_PROPOSER_SLASHINGS = "/eth/v1/beacon/pool/proposer_slashings"
 GET_VOLUNTARY_EXITS = "/eth/v1/beacon/pool/voluntary_exits"
+GET_BLS_TO_EXECUTION_CHANGES = "/eth/v1/beacon/pool/bls_to_execution_changes"
+
 
 # [ CONFIG endpoints ]
 
diff --git a/web3/beacon/async_beacon.py b/web3/beacon/async_beacon.py
--- a/web3/beacon/async_beacon.py
+++ b/web3/beacon/async_beacon.py
@@ -5,6 +5,7 @@
 
 from eth_typing import (
     URI,
+    HexStr,
 )
 
 from web3._utils.request import (
@@ -16,23 +17,32 @@
     GET_ATTESTER_SLASHINGS,
     GET_BEACON_HEADS,
     GET_BEACON_STATE,
+    GET_BLINDED_BLOCKS,
     GET_BLOCK,
     GET_BLOCK_ATTESTATIONS,
     GET_BLOCK_HEADER,
     GET_BLOCK_HEADERS,
     GET_BLOCK_ROOT,
+    GET_BLS_TO_EXECUTION_CHANGES,
     GET_DEPOSIT_CONTRACT,
     GET_EPOCH_COMMITTEES,
+    GET_EPOCH_RANDAO,
+    GET_EPOCH_SYNC_COMMITTEES,
     GET_FINALITY_CHECKPOINT,
     GET_FORK_DATA,
     GET_FORK_SCHEDULE,
     GET_GENESIS,
     GET_HASH_ROOT,
     GET_HEALTH,
+    GET_LIGHT_CLIENT_BOOTSTRAP_STRUCTURE,
+    GET_LIGHT_CLIENT_FINALITY_UPDATE,
+    GET_LIGHT_CLIENT_OPTIMISTIC_UPDATE,
+    GET_LIGHT_CLIENT_UPDATES,
     GET_NODE_IDENTITY,
     GET_PEER,
     GET_PEERS,
     GET_PROPOSER_SLASHINGS,
+    GET_REWARDS,
     GET_SPEC,
     GET_SYNCING,
     GET_VALIDATOR,
@@ -49,15 +59,19 @@ class AsyncBeacon:
     def __init__(
         self,
         base_url: str,
+        request_timeout: float = 10.0,
     ) -> None:
         self.base_url = base_url
+        self.request_timeout = request_timeout
 
     async def _async_make_get_request(self, endpoint_uri: str) -> Dict[str, Any]:
         uri = URI(self.base_url + endpoint_uri)
-        return await async_json_make_get_request(uri)
+        return await async_json_make_get_request(uri, timeout=self.request_timeout)
 
     # [ BEACON endpoints ]
 
+    # states
+
     async def get_genesis(self) -> Dict[str, Any]:
         return await self._async_make_get_request(GET_GENESIS)
 
@@ -90,12 +104,24 @@ async def get_validator_balances(self, state_id: str = "head") -> Dict[str, Any]
     async def get_epoch_committees(self, state_id: str = "head") -> Dict[str, Any]:
         return await self._async_make_get_request(GET_EPOCH_COMMITTEES.format(state_id))
 
+    async def get_epoch_sync_committees(self, state_id: str = "head") -> Dict[str, Any]:
+        return await self._async_make_get_request(
+            GET_EPOCH_SYNC_COMMITTEES.format(state_id)
+        )
+
+    async def get_epoch_randao(self, state_id: str = "head") -> Dict[str, Any]:
+        return await self._async_make_get_request(GET_EPOCH_RANDAO.format(state_id))
+
+    # headers
+
     async def get_block_headers(self) -> Dict[str, Any]:
         return await self._async_make_get_request(GET_BLOCK_HEADERS)
 
     async def get_block_header(self, block_id: str) -> Dict[str, Any]:
         return await self._async_make_get_request(GET_BLOCK_HEADER.format(block_id))
 
+    # block
+
     async def get_block(self, block_id: str) -> Dict[str, Any]:
         return await self._async_make_get_request(GET_BLOCK.format(block_id))
 
@@ -107,6 +133,34 @@ async def get_block_attestations(self, block_id: str) -> Dict[str, Any]:
             GET_BLOCK_ATTESTATIONS.format(block_id)
         )
 
+    async def get_blinded_blocks(self, block_id: str) -> Dict[str, Any]:
+        return await self._async_make_get_request(GET_BLINDED_BLOCKS.format(block_id))
+
+    # rewards
+
+    async def get_rewards(self, block_id: str) -> Dict[str, Any]:
+        return await self._async_make_get_request(GET_REWARDS.format(block_id))
+
+    # light client (untested but follows spec)
+
+    async def get_light_client_bootstrap_structure(
+        self, block_root: HexStr
+    ) -> Dict[str, Any]:
+        return await self._async_make_get_request(
+            GET_LIGHT_CLIENT_BOOTSTRAP_STRUCTURE.format(block_root)
+        )
+
+    async def get_light_client_updates(self) -> Dict[str, Any]:
+        return await self._async_make_get_request(GET_LIGHT_CLIENT_UPDATES)
+
+    async def get_light_client_finality_update(self) -> Dict[str, Any]:
+        return await self._async_make_get_request(GET_LIGHT_CLIENT_FINALITY_UPDATE)
+
+    async def get_light_client_optimistic_update(self) -> Dict[str, Any]:
+        return await self._async_make_get_request(GET_LIGHT_CLIENT_OPTIMISTIC_UPDATE)
+
+    # pool
+
     async def get_attestations(self) -> Dict[str, Any]:
         return await self._async_make_get_request(GET_ATTESTATIONS)
 
@@ -119,6 +173,9 @@ async def get_proposer_slashings(self) -> Dict[str, Any]:
     async def get_voluntary_exits(self) -> Dict[str, Any]:
         return await self._async_make_get_request(GET_VOLUNTARY_EXITS)
 
+    async def get_bls_to_execution_changes(self) -> Dict[str, Any]:
+        return await self._async_make_get_request(GET_BLS_TO_EXECUTION_CHANGES)
+
     # [ CONFIG endpoints ]
 
     async def get_fork_schedule(self) -> Dict[str, Any]:
diff --git a/web3/beacon/main.py b/web3/beacon/main.py
--- a/web3/beacon/main.py
+++ b/web3/beacon/main.py
@@ -5,6 +5,7 @@
 
 from eth_typing import (
     URI,
+    HexStr,
 )
 
 from web3._utils.request import (
@@ -16,23 +17,32 @@
     GET_ATTESTER_SLASHINGS,
     GET_BEACON_HEADS,
     GET_BEACON_STATE,
+    GET_BLINDED_BLOCKS,
     GET_BLOCK,
     GET_BLOCK_ATTESTATIONS,
     GET_BLOCK_HEADER,
     GET_BLOCK_HEADERS,
     GET_BLOCK_ROOT,
+    GET_BLS_TO_EXECUTION_CHANGES,
     GET_DEPOSIT_CONTRACT,
     GET_EPOCH_COMMITTEES,
+    GET_EPOCH_RANDAO,
+    GET_EPOCH_SYNC_COMMITTEES,
     GET_FINALITY_CHECKPOINT,
     GET_FORK_DATA,
     GET_FORK_SCHEDULE,
     GET_GENESIS,
     GET_HASH_ROOT,
     GET_HEALTH,
+    GET_LIGHT_CLIENT_BOOTSTRAP_STRUCTURE,
+    GET_LIGHT_CLIENT_FINALITY_UPDATE,
+    GET_LIGHT_CLIENT_OPTIMISTIC_UPDATE,
+    GET_LIGHT_CLIENT_UPDATES,
     GET_NODE_IDENTITY,
     GET_PEER,
     GET_PEERS,
     GET_PROPOSER_SLASHINGS,
+    GET_REWARDS,
     GET_SPEC,
     GET_SYNCING,
     GET_VALIDATOR,
@@ -47,15 +57,19 @@ class Beacon:
     def __init__(
         self,
         base_url: str,
+        request_timeout: float = 10.0,
     ) -> None:
         self.base_url = base_url
+        self.request_timeout = request_timeout
 
     def _make_get_request(self, endpoint_url: str) -> Dict[str, Any]:
         uri = URI(self.base_url + endpoint_url)
-        return json_make_get_request(uri)
+        return json_make_get_request(uri, timeout=self.request_timeout)
 
     # [ BEACON endpoints ]
 
+    # states
+
     def get_genesis(self) -> Dict[str, Any]:
         return self._make_get_request(GET_GENESIS)
 
@@ -82,12 +96,22 @@ def get_validator_balances(self, state_id: str = "head") -> Dict[str, Any]:
     def get_epoch_committees(self, state_id: str = "head") -> Dict[str, Any]:
         return self._make_get_request(GET_EPOCH_COMMITTEES.format(state_id))
 
+    def get_epoch_sync_committees(self, state_id: str = "head") -> Dict[str, Any]:
+        return self._make_get_request(GET_EPOCH_SYNC_COMMITTEES.format(state_id))
+
+    def get_epoch_randao(self, state_id: str = "head") -> Dict[str, Any]:
+        return self._make_get_request(GET_EPOCH_RANDAO.format(state_id))
+
+    # headers
+
     def get_block_headers(self) -> Dict[str, Any]:
         return self._make_get_request(GET_BLOCK_HEADERS)
 
     def get_block_header(self, block_id: str) -> Dict[str, Any]:
         return self._make_get_request(GET_BLOCK_HEADER.format(block_id))
 
+    # blocks
+
     def get_block(self, block_id: str) -> Dict[str, Any]:
         return self._make_get_request(GET_BLOCK.format(block_id))
 
@@ -97,6 +121,34 @@ def get_block_root(self, block_id: str) -> Dict[str, Any]:
     def get_block_attestations(self, block_id: str) -> Dict[str, Any]:
         return self._make_get_request(GET_BLOCK_ATTESTATIONS.format(block_id))
 
+    def get_blinded_blocks(self, block_id: str) -> Dict[str, Any]:
+        return self._make_get_request(GET_BLINDED_BLOCKS.format(block_id))
+
+    # rewards
+
+    def get_rewards(self, block_id: str) -> Dict[str, Any]:
+        return self._make_get_request(GET_REWARDS.format(block_id))
+
+    # light client (untested but follows spec)
+
+    def get_light_client_bootstrap_structure(
+        self, block_root: HexStr
+    ) -> Dict[str, Any]:
+        return self._make_get_request(
+            GET_LIGHT_CLIENT_BOOTSTRAP_STRUCTURE.format(block_root)
+        )
+
+    def get_light_client_updates(self) -> Dict[str, Any]:
+        return self._make_get_request(GET_LIGHT_CLIENT_UPDATES)
+
+    def get_light_client_finality_update(self) -> Dict[str, Any]:
+        return self._make_get_request(GET_LIGHT_CLIENT_FINALITY_UPDATE)
+
+    def get_light_client_optimistic_update(self) -> Dict[str, Any]:
+        return self._make_get_request(GET_LIGHT_CLIENT_OPTIMISTIC_UPDATE)
+
+    # pool
+
     def get_attestations(self) -> Dict[str, Any]:
         return self._make_get_request(GET_ATTESTATIONS)
 
@@ -109,6 +161,9 @@ def get_proposer_slashings(self) -> Dict[str, Any]:
     def get_voluntary_exits(self) -> Dict[str, Any]:
         return self._make_get_request(GET_VOLUNTARY_EXITS)
 
+    def get_bls_to_execution_changes(self) -> Dict[str, Any]:
+        return self._make_get_request(GET_BLS_TO_EXECUTION_CHANGES)
+
     # [ CONFIG endpoints ]
 
     def get_fork_schedule(self) -> Dict[str, Any]:


Test patch:
diff --git a/tests/beacon/test_async_beacon.py b/tests/beacon/test_async_beacon.py
--- a/tests/beacon/test_async_beacon.py
+++ b/tests/beacon/test_async_beacon.py
@@ -3,6 +3,8 @@
     randint,
 )
 
+import pytest_asyncio
+
 from web3._utils.request import (
     _async_session_cache,
 )
@@ -10,6 +12,9 @@
     AsyncBeacon,
 )
 
+# tested against lighthouse which uses port 5052 by default
+BASE_URL = "http://localhost:5052"
+
 
 def _assert_valid_response(response):
     # assert valid response according to Beacon API spec
@@ -19,16 +24,32 @@ def _assert_valid_response(response):
 
 @pytest.fixture
 def async_beacon():
-    # tested against lighthouse which uses port 5052 by default
-    return AsyncBeacon(base_url="http://127.0.0.1:5052")
+    return AsyncBeacon(base_url=BASE_URL)
 
 
-@pytest.fixture(autouse=True)
-def _cleanup():
+@pytest_asyncio.fixture(autouse=True)
+async def _cleanup():
     yield
+    [await session.close() for _, session in _async_session_cache.items()]
     _async_session_cache.clear()
 
 
+# sanity check to make sure the positive test cases are valid
+@pytest.mark.asyncio
+async def test_async_cl_beacon_raises_exception_on_invalid_url(async_beacon):
+    with pytest.raises(ValueError):
+        await async_beacon._async_make_get_request(
+            BASE_URL + "/eth/v1/beacon/nonexistent"
+        )
+
+
+@pytest.mark.asyncio
+async def test_async_beacon_user_request_timeout():
+    beacon = AsyncBeacon(base_url=BASE_URL, request_timeout=0.001)
+    with pytest.raises(TimeoutError):
+        await beacon.get_validators()
+
+
 # Beacon endpoint tests:
 
 
@@ -37,40 +58,30 @@ async def test_async_cl_beacon_get_genesis(async_beacon):
     response = await async_beacon.get_genesis()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_beacon_get_hash_root(async_beacon):
     response = await async_beacon.get_hash_root()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_beacon_get_fork_data(async_beacon):
     response = await async_beacon.get_fork_data()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_beacon_get_finality_checkpoint(async_beacon):
     response = await async_beacon.get_finality_checkpoint()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_beacon_get_validators(async_beacon):
     response = await async_beacon.get_validators()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_beacon_get_validator(async_beacon):
@@ -84,23 +95,29 @@ async def test_async_cl_beacon_get_validator(async_beacon):
     response = await async_beacon.get_validator(random_validator_pubkey)
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_beacon_get_validator_balances(async_beacon):
     response = await async_beacon.get_validator_balances()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_beacon_get_epoch_committees(async_beacon):
     response = await async_beacon.get_epoch_committees()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
+
+@pytest.mark.asyncio
+async def test_async_cl_beacon_get_epoch_sync_committees(async_beacon):
+    response = await async_beacon.get_epoch_sync_committees()
+    _assert_valid_response(response)
+
+
+@pytest.mark.asyncio
+async def test_async_cl_beacon_get_epoch_randao(async_beacon):
+    response = await async_beacon.get_epoch_randao()
+    _assert_valid_response(response)
 
 
 @pytest.mark.asyncio
@@ -108,31 +125,35 @@ async def test_async_cl_beacon_get_block_headers(async_beacon):
     response = await async_beacon.get_block_headers()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_beacon_get_block_header(async_beacon):
     response = await async_beacon.get_block_header("head")
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_beacon_get_block(async_beacon):
     response = await async_beacon.get_block("head")
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_beacon_get_block_root(async_beacon):
     response = await async_beacon.get_block_root("head")
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
+
+@pytest.mark.asyncio
+async def test_async_cl_beacon_get_blinded_blocks(async_beacon):
+    response = await async_beacon.get_blinded_blocks("head")
+    _assert_valid_response(response)
+
+
+@pytest.mark.asyncio
+async def test_async_cl_beacon_get_rewards(async_beacon):
+    response = await async_beacon.get_rewards("head")
+    _assert_valid_response(response)
 
 
 @pytest.mark.asyncio
@@ -140,39 +161,35 @@ async def test_async_cl_beacon_get_block_attestations(async_beacon):
     response = await async_beacon.get_block_attestations("head")
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_beacon_get_attestations(async_beacon):
     response = await async_beacon.get_attestations()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_beacon_get_attester_slashings(async_beacon):
     response = await async_beacon.get_attester_slashings()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_beacon_get_proposer_slashings(async_beacon):
     response = await async_beacon.get_proposer_slashings()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_beacon_get_voluntary_exits(async_beacon):
     response = await async_beacon.get_voluntary_exits()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
+
+@pytest.mark.asyncio
+async def test_async_cl_beacon_get_bls_to_execution_changes(async_beacon):
+    response = await async_beacon.get_bls_to_execution_changes()
+    _assert_valid_response(response)
 
 
 # Config endpoint tests:
@@ -183,24 +200,18 @@ async def test_async_cl_config_get_fork_schedule(async_beacon):
     response = await async_beacon.get_fork_schedule()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_config_get_spec(async_beacon):
     response = await async_beacon.get_spec()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_config_get_deposit_contract(async_beacon):
     response = await async_beacon.get_deposit_contract()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 # Debug endpoint tests:
 
@@ -210,16 +221,12 @@ async def test_async_cl_debug_get_beacon_state(async_beacon):
     response = await async_beacon.get_beacon_state()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_debug_get_beacon_heads(async_beacon):
     response = await async_beacon.get_beacon_heads()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 # Node endpoint tests:
 
@@ -229,31 +236,23 @@ async def test_async_cl_node_get_node_identity(async_beacon):
     response = await async_beacon.get_node_identity()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_node_get_peers(async_beacon):
     response = await async_beacon.get_peers()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_node_get_peer(async_beacon):
     response = await async_beacon.get_peer("")
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_node_get_health(async_beacon):
     response = await async_beacon.get_health()
-    assert response <= 206
-
-    [await session.close() for session in _async_session_cache._data.values()]
+    assert isinstance(response, int)
 
 
 @pytest.mark.asyncio
@@ -261,12 +260,8 @@ async def test_async_cl_node_get_version(async_beacon):
     response = await async_beacon.get_version()
     _assert_valid_response(response)
 
-    [await session.close() for session in _async_session_cache._data.values()]
-
 
 @pytest.mark.asyncio
 async def test_async_cl_node_get_syncing(async_beacon):
     response = await async_beacon.get_syncing()
     _assert_valid_response(response)
-
-    [await session.close() for session in _async_session_cache._data.values()]
diff --git a/tests/beacon/test_beacon.py b/tests/beacon/test_beacon.py
--- a/tests/beacon/test_beacon.py
+++ b/tests/beacon/test_beacon.py
@@ -3,6 +3,10 @@
     randint,
 )
 
+from requests import (
+    Timeout,
+)
+
 from web3._utils.request import (
     _session_cache,
 )
@@ -10,6 +14,9 @@
     Beacon,
 )
 
+# tested against lighthouse which uses port 5052 by default
+BASE_URL = "http://localhost:5052"
+
 
 def _assert_valid_response(response):
     # assert valid response according to Beacon API spec
@@ -19,8 +26,7 @@ def _assert_valid_response(response):
 
 @pytest.fixture
 def beacon():
-    # tested against lighthouse which uses port 5052 by default
-    return Beacon(base_url="http://localhost:5052")
+    return Beacon(base_url=BASE_URL)
 
 
 @pytest.fixture(autouse=True)
@@ -29,6 +35,18 @@ def _cleanup():
     _session_cache.clear()
 
 
+# sanity check to make sure the positive test cases are valid
+def test_cl_beacon_raises_exception_on_invalid_url(beacon):
+    with pytest.raises(ValueError):
+        beacon._make_get_request(BASE_URL + "/eth/v1/beacon/nonexistent")
+
+
+def test_beacon_user_defined_request_timeout():
+    beacon = Beacon(base_url=BASE_URL, request_timeout=0.001)
+    with pytest.raises(Timeout):
+        beacon.get_validators()
+
+
 # Beacon endpoint tests:
 
 
@@ -79,6 +97,16 @@ def test_cl_beacon_get_epoch_committees(beacon):
     _assert_valid_response(response)
 
 
+def test_cl_beacon_get_epoch_sync_committees(beacon):
+    response = beacon.get_epoch_sync_committees()
+    _assert_valid_response(response)
+
+
+def test_cl_beacon_get_epoch_randao(beacon):
+    response = beacon.get_epoch_randao()
+    _assert_valid_response(response)
+
+
 def test_cl_beacon_get_block_headers(beacon):
     response = beacon.get_block_headers()
     _assert_valid_response(response)
@@ -99,6 +127,16 @@ def test_cl_beacon_get_block_root(beacon):
     _assert_valid_response(response)
 
 
+def test_cl_beacon_get_blinded_blocks(beacon):
+    response = beacon.get_blinded_blocks("head")
+    _assert_valid_response(response)
+
+
+def test_cl_beacon_get_rewards(beacon):
+    response = beacon.get_rewards("head")
+    _assert_valid_response(response)
+
+
 def test_cl_beacon_get_block_attestations(beacon):
     response = beacon.get_block_attestations("head")
     _assert_valid_response(response)
@@ -124,6 +162,11 @@ def test_cl_beacon_get_voluntary_exits(beacon):
     _assert_valid_response(response)
 
 
+def test_cl_beacon_get_bls_to_execution_changes(beacon):
+    response = beacon.get_bls_to_execution_changes()
+    _assert_valid_response(response)
+
+
 # Config endpoint tests:
 
 
@@ -175,7 +218,7 @@ def test_cl_node_get_peer(beacon):
 
 def test_cl_node_get_health(beacon):
     response = beacon.get_health()
-    assert response <= 206
+    assert isinstance(response, int)
 
 
 def test_cl_node_get_version(beacon):