Skip to content
Snippets Groups Projects
Commit 73626b35 authored by Vincent Texier's avatar Vincent Texier
Browse files

[enh] #140 remove asyncio and aiohttp in duniterpy

parent aaca0ee5
No related branches found
No related tags found
No related merge requests found
......@@ -18,9 +18,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from typing import Union
from aiohttp import ClientResponse
from http.client import HTTPResponse
from duniterpy.api.client import Client, RESPONSE_AIOHTTP
from duniterpy.api.client import Client, RESPONSE_HTTP
logger = logging.getLogger("duniter/blockchain")
......@@ -222,17 +222,17 @@ DIFFICULTIES_SCHEMA = {
BRANCHES_SCHEMA = {"type": "object", "properties": {"blocks": BLOCKS_SCHEMA}}
async def parameters(client: Client) -> dict:
def parameters(client: Client) -> dict:
"""
GET the blockchain parameters used by this node
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/parameters", schema=PARAMETERS_SCHEMA)
return client.get(MODULE + "/parameters", schema=PARAMETERS_SCHEMA)
async def memberships(client: Client, search: str) -> dict:
def memberships(client: Client, search: str) -> dict:
"""
GET list of Membership documents for UID/Public key
......@@ -240,12 +240,10 @@ async def memberships(client: Client, search: str) -> dict:
:param search: UID/Public key
:return:
"""
return await client.get(
MODULE + "/memberships/%s" % search, schema=MEMBERSHIPS_SCHEMA
)
return client.get(MODULE + "/memberships/%s" % search, schema=MEMBERSHIPS_SCHEMA)
async def membership(client: Client, membership_signed_raw: str) -> ClientResponse:
def membership(client: Client, membership_signed_raw: str) -> HTTPResponse:
"""
POST a Membership document
......@@ -253,26 +251,26 @@ async def membership(client: Client, membership_signed_raw: str) -> ClientRespon
:param membership_signed_raw: Membership signed raw document
:return:
"""
return await client.post(
return client.post(
MODULE + "/membership",
{"membership": membership_signed_raw},
rtype=RESPONSE_AIOHTTP,
rtype=RESPONSE_HTTP,
)
async def current(client: Client) -> dict:
def current(client: Client) -> dict:
"""
GET the last accepted block
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/current", schema=BLOCK_SCHEMA)
return client.get(MODULE + "/current", schema=BLOCK_SCHEMA)
async def block(
def block(
client: Client, number: int = 0, block_raw: str = None, signature: str = None
) -> Union[dict, ClientResponse]:
) -> Union[dict, HTTPResponse]:
"""
GET/POST a block from/to the blockchain
......@@ -284,16 +282,16 @@ async def block(
"""
# POST block
if block_raw is not None and signature is not None:
return await client.post(
return client.post(
MODULE + "/block",
{"block": block_raw, "signature": signature},
rtype=RESPONSE_AIOHTTP,
rtype=RESPONSE_HTTP,
)
# GET block
return await client.get(MODULE + "/block/%d" % number, schema=BLOCK_SCHEMA)
return client.get(MODULE + "/block/%d" % number, schema=BLOCK_SCHEMA)
async def blocks(client: Client, count: int, start: int) -> list:
def blocks(client: Client, count: int, start: int) -> list:
"""
GET list of blocks from the blockchain
......@@ -305,12 +303,10 @@ async def blocks(client: Client, count: int, start: int) -> list:
assert type(count) is int
assert type(start) is int
return await client.get(
MODULE + "/blocks/%d/%d" % (count, start), schema=BLOCKS_SCHEMA
)
return client.get(MODULE + "/blocks/%d/%d" % (count, start), schema=BLOCKS_SCHEMA)
async def hardship(client: Client, pubkey: str) -> dict:
def hardship(client: Client, pubkey: str) -> dict:
"""
GET hardship level for given member's public key for writing next block
......@@ -318,114 +314,114 @@ async def hardship(client: Client, pubkey: str) -> dict:
:param pubkey: Public key of the member
:return:
"""
return await client.get(MODULE + "/hardship/%s" % pubkey, schema=HARDSHIP_SCHEMA)
return client.get(MODULE + "/hardship/%s" % pubkey, schema=HARDSHIP_SCHEMA)
async def difficulties(client: Client) -> dict:
def difficulties(client: Client) -> dict:
"""
GET difficulties levels for members into current window for writing next block
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/difficulties", schema=DIFFICULTIES_SCHEMA)
return client.get(MODULE + "/difficulties", schema=DIFFICULTIES_SCHEMA)
async def branches(client: Client) -> list:
def branches(client: Client) -> list:
"""
GET current branches of the node (top block of each branch)
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/branches", schema=BRANCHES_SCHEMA)
return client.get(MODULE + "/branches", schema=BRANCHES_SCHEMA)
async def newcomers(client: Client) -> dict:
def newcomers(client: Client) -> dict:
"""
GET the block numbers containing newcomers
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/with/newcomers", schema=BLOCK_NUMBERS_SCHEMA)
return client.get(MODULE + "/with/newcomers", schema=BLOCK_NUMBERS_SCHEMA)
async def certifications(client: Client) -> dict:
def certifications(client: Client) -> dict:
"""
GET the block numbers containing certifications
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/with/certs", schema=BLOCK_NUMBERS_SCHEMA)
return client.get(MODULE + "/with/certs", schema=BLOCK_NUMBERS_SCHEMA)
async def joiners(client: Client) -> dict:
def joiners(client: Client) -> dict:
"""
GET the block numbers containing joiners
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/with/joiners", schema=BLOCK_NUMBERS_SCHEMA)
return client.get(MODULE + "/with/joiners", schema=BLOCK_NUMBERS_SCHEMA)
async def actives(client: Client) -> dict:
def actives(client: Client) -> dict:
"""
GET the block numbers containing actives
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/with/actives", schema=BLOCK_NUMBERS_SCHEMA)
return client.get(MODULE + "/with/actives", schema=BLOCK_NUMBERS_SCHEMA)
async def leavers(client: Client) -> dict:
def leavers(client: Client) -> dict:
"""
GET the block numbers containing leavers
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/with/leavers", schema=BLOCK_NUMBERS_SCHEMA)
return client.get(MODULE + "/with/leavers", schema=BLOCK_NUMBERS_SCHEMA)
async def revoked(client: Client) -> dict:
def revoked(client: Client) -> dict:
"""
GET the block numbers containing revoked members.
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/with/revoked", schema=BLOCK_NUMBERS_SCHEMA)
return client.get(MODULE + "/with/revoked", schema=BLOCK_NUMBERS_SCHEMA)
async def excluded(client: Client) -> dict:
def excluded(client: Client) -> dict:
"""
GET the block numbers containing excluded
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/with/excluded", schema=BLOCK_NUMBERS_SCHEMA)
return client.get(MODULE + "/with/excluded", schema=BLOCK_NUMBERS_SCHEMA)
async def ud(client: Client) -> dict:
def ud(client: Client) -> dict:
"""
GET the block numbers containing universal dividend
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/with/ud", schema=BLOCK_NUMBERS_SCHEMA)
return client.get(MODULE + "/with/ud", schema=BLOCK_NUMBERS_SCHEMA)
async def tx(client: Client) -> dict:
def tx(client: Client) -> dict:
"""
GET the block numbers containing transactions
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/with/tx", schema=BLOCK_NUMBERS_SCHEMA)
return client.get(MODULE + "/with/tx", schema=BLOCK_NUMBERS_SCHEMA)
......@@ -17,9 +17,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from aiohttp import ClientResponse
from http.client import HTTPResponse
from duniterpy.api.client import Client, RESPONSE_AIOHTTP
from duniterpy.api.client import Client, RESPONSE_HTTP
logger = logging.getLogger("duniter/network")
......@@ -85,17 +85,17 @@ WS2P_HEADS_SCHEMA = {
}
async def peering(client: Client) -> dict:
def peering(client: Client) -> dict:
"""
GET peering information about a peer
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/peering", schema=PEERING_SCHEMA)
return client.get(MODULE + "/peering", schema=PEERING_SCHEMA)
async def peers(client: Client, leaves: bool = False, leaf: str = "") -> dict:
def peers(client: Client, leaves: bool = False, leaf: str = "") -> dict:
"""
GET peering entries of every node inside the currency network
......@@ -105,17 +105,17 @@ async def peers(client: Client, leaves: bool = False, leaf: str = "") -> dict:
:return:
"""
if leaves is True:
response = await client.get(
response = client.get(
MODULE + "/peering/peers", {"leaves": "true"}, schema=PEERS_SCHEMA
)
else:
response = await client.get(
response = client.get(
MODULE + "/peering/peers", {"leaf": leaf}, schema=PEERS_SCHEMA
)
return response
async def peer(client: Client, peer_signed_raw: str) -> ClientResponse:
def peer(client: Client, peer_signed_raw: str) -> HTTPResponse:
"""
POST a Peer signed raw document
......@@ -123,16 +123,16 @@ async def peer(client: Client, peer_signed_raw: str) -> ClientResponse:
:param peer_signed_raw: Peer signed raw document
:return:
"""
return await client.post(
MODULE + "/peering/peers", {"peer": peer_signed_raw}, rtype=RESPONSE_AIOHTTP
return client.post(
MODULE + "/peering/peers", {"peer": peer_signed_raw}, rtype=RESPONSE_HTTP
)
async def ws2p_heads(client: Client) -> dict:
def ws2p_heads(client: Client) -> dict:
"""
GET ws2p heads known by the node
:param client: Client to connect to the api
:rtype: dict
"""
return await client.get(MODULE + "/ws2p/heads", schema=WS2P_HEADS_SCHEMA)
return client.get(MODULE + "/ws2p/heads", schema=WS2P_HEADS_SCHEMA)
......@@ -56,21 +56,21 @@ SANDBOXES_SCHEMA = {
}
async def summary(client: Client) -> dict:
def summary(client: Client) -> dict:
"""
GET Duniter node version and infos
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/summary", schema=SUMMARY_SCHEMA)
return client.get(MODULE + "/summary", schema=SUMMARY_SCHEMA)
async def sandboxes(client: Client) -> dict:
def sandboxes(client: Client) -> dict:
"""
GET Duniter node version and infos
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/sandboxes", schema=SANDBOXES_SCHEMA)
return client.get(MODULE + "/sandboxes", schema=SANDBOXES_SCHEMA)
......@@ -17,9 +17,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from aiohttp import ClientResponse
from http.client import HTTPResponse
from duniterpy.api.client import Client, RESPONSE_AIOHTTP
from duniterpy.api.client import Client, RESPONSE_HTTP
logger = logging.getLogger("duniter/tx")
......@@ -125,7 +125,7 @@ SOURCES_SCHEMA = {
}
async def history(client: Client, pubkey: str) -> dict:
def history(client: Client, pubkey: str) -> dict:
"""
Get transactions history of public key
......@@ -133,10 +133,10 @@ async def history(client: Client, pubkey: str) -> dict:
:param pubkey: Public key
:return:
"""
return await client.get(MODULE + "/history/%s" % pubkey, schema=HISTORY_SCHEMA)
return client.get(MODULE + "/history/%s" % pubkey, schema=HISTORY_SCHEMA)
async def process(client: Client, transaction_signed_raw: str) -> ClientResponse:
def process(client: Client, transaction_signed_raw: str) -> HTTPResponse:
"""
POST a transaction raw document
......@@ -144,14 +144,14 @@ async def process(client: Client, transaction_signed_raw: str) -> ClientResponse
:param transaction_signed_raw: Transaction signed raw document
:return:
"""
return await client.post(
return client.post(
MODULE + "/process",
{"transaction": transaction_signed_raw},
rtype=RESPONSE_AIOHTTP,
rtype=RESPONSE_HTTP,
)
async def sources(client: Client, pubkey: str) -> dict:
def sources(client: Client, pubkey: str) -> dict:
"""
GET transaction sources
......@@ -159,10 +159,10 @@ async def sources(client: Client, pubkey: str) -> dict:
:param pubkey: Public key
:return:
"""
return await client.get(MODULE + "/sources/%s" % pubkey, schema=SOURCES_SCHEMA)
return client.get(MODULE + "/sources/%s" % pubkey, schema=SOURCES_SCHEMA)
async def pending(client: Client, pubkey: str) -> dict:
def pending(client: Client, pubkey: str) -> dict:
"""
GET pending transaction history for the given pubkey
......@@ -170,12 +170,10 @@ async def pending(client: Client, pubkey: str) -> dict:
:param pubkey: Public key
:return:
"""
return await client.get(
MODULE + "/history/%s/pending" % pubkey, schema=HISTORY_SCHEMA
)
return client.get(MODULE + "/history/%s/pending" % pubkey, schema=HISTORY_SCHEMA)
async def blocks(client: Client, pubkey: str, start: int, end: int) -> dict:
def blocks(client: Client, pubkey: str, start: int, end: int) -> dict:
"""
GET public key transactions history between start and end block number
......@@ -185,13 +183,13 @@ async def blocks(client: Client, pubkey: str, start: int, end: int) -> dict:
:param end: End to block number
:return:
"""
return await client.get(
return client.get(
MODULE + "/history/%s/blocks/%s/%s" % (pubkey, start, end),
schema=HISTORY_SCHEMA,
)
async def times(client: Client, pubkey: str, start: int, end: int) -> dict:
def times(client: Client, pubkey: str, start: int, end: int) -> dict:
"""
GET public key transactions history between start and end timestamp
......@@ -201,6 +199,6 @@ async def times(client: Client, pubkey: str, start: int, end: int) -> dict:
:param end: End to timestamp
:return:
"""
return await client.get(
return client.get(
MODULE + "/history/%s/times/%s/%s" % (pubkey, start, end), schema=HISTORY_SCHEMA
)
......@@ -51,7 +51,7 @@ UD_SCHEMA = {
}
async def history(client: Client, pubkey: str) -> dict:
def history(client: Client, pubkey: str) -> dict:
"""
Get UD history of a member account
......@@ -59,4 +59,4 @@ async def history(client: Client, pubkey: str) -> dict:
:param pubkey: Public key of the member
:return:
"""
return await client.get(MODULE + "/history/%s" % pubkey, schema=UD_SCHEMA)
return client.get(MODULE + "/history/%s" % pubkey, schema=UD_SCHEMA)
......@@ -17,9 +17,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from aiohttp import ClientResponse
from http.client import HTTPResponse
from duniterpy.api.client import Client, RESPONSE_AIOHTTP
from duniterpy.api.client import Client, RESPONSE_HTTP
logger = logging.getLogger("duniter/wot")
......@@ -230,7 +230,7 @@ IDENTITY_OF_SCHEMA = {
}
async def add(client: Client, identity_signed_raw: str) -> ClientResponse:
def add(client: Client, identity_signed_raw: str) -> HTTPResponse:
"""
POST identity raw document
......@@ -238,12 +238,12 @@ async def add(client: Client, identity_signed_raw: str) -> ClientResponse:
:param identity_signed_raw: Identity raw document
:return:
"""
return await client.post(
MODULE + "/add", {"identity": identity_signed_raw}, rtype=RESPONSE_AIOHTTP
return client.post(
MODULE + "/add", {"identity": identity_signed_raw}, rtype=RESPONSE_HTTP
)
async def certify(client: Client, certification_signed_raw: str) -> ClientResponse:
def certify(client: Client, certification_signed_raw: str) -> HTTPResponse:
"""
POST certification raw document
......@@ -251,12 +251,12 @@ async def certify(client: Client, certification_signed_raw: str) -> ClientRespon
:param certification_signed_raw: Certification raw document
:return:
"""
return await client.post(
MODULE + "/certify", {"cert": certification_signed_raw}, rtype=RESPONSE_AIOHTTP
return client.post(
MODULE + "/certify", {"cert": certification_signed_raw}, rtype=RESPONSE_HTTP
)
async def revoke(client: Client, revocation_signed_raw: str) -> ClientResponse:
def revoke(client: Client, revocation_signed_raw: str) -> HTTPResponse:
"""
POST revocation document
......@@ -264,14 +264,14 @@ async def revoke(client: Client, revocation_signed_raw: str) -> ClientResponse:
:param revocation_signed_raw: Certification raw document
:return:
"""
return await client.post(
return client.post(
MODULE + "/revoke",
{"revocation": revocation_signed_raw},
rtype=RESPONSE_AIOHTTP,
rtype=RESPONSE_HTTP,
)
async def lookup(client: Client, search: str) -> dict:
def lookup(client: Client, search: str) -> dict:
"""
GET UID/Public key data
......@@ -279,10 +279,10 @@ async def lookup(client: Client, search: str) -> dict:
:param search: UID or public key
:return:
"""
return await client.get(MODULE + "/lookup/%s" % search, schema=LOOKUP_SCHEMA)
return client.get(MODULE + "/lookup/%s" % search, schema=LOOKUP_SCHEMA)
async def certifiers_of(client: Client, search: str) -> dict:
def certifiers_of(client: Client, search: str) -> dict:
"""
GET UID/Public key certifiers
......@@ -290,12 +290,12 @@ async def certifiers_of(client: Client, search: str) -> dict:
:param search: UID or public key
:return:
"""
return await client.get(
return client.get(
MODULE + "/certifiers-of/%s" % search, schema=CERTIFICATIONS_SCHEMA
)
async def certified_by(client: Client, search: str) -> dict:
def certified_by(client: Client, search: str) -> dict:
"""
GET identities certified by UID/Public key
......@@ -303,22 +303,22 @@ async def certified_by(client: Client, search: str) -> dict:
:param search: UID or public key
:return:
"""
return await client.get(
return client.get(
MODULE + "/certified-by/%s" % search, schema=CERTIFICATIONS_SCHEMA
)
async def members(client: Client) -> dict:
def members(client: Client) -> dict:
"""
GET list of all current members of the Web of Trust
:param client: Client to connect to the api
:return:
"""
return await client.get(MODULE + "/members", schema=MEMBERS_SCHEMA)
return client.get(MODULE + "/members", schema=MEMBERS_SCHEMA)
async def requirements(client: Client, search: str) -> dict:
def requirements(client: Client, search: str) -> dict:
"""
GET list of requirements for a given UID/Public key
......@@ -326,12 +326,10 @@ async def requirements(client: Client, search: str) -> dict:
:param search: UID or public key
:return:
"""
return await client.get(
MODULE + "/requirements/%s" % search, schema=REQUIREMENTS_SCHEMA
)
return client.get(MODULE + "/requirements/%s" % search, schema=REQUIREMENTS_SCHEMA)
async def requirements_of_pending(client: Client, minsig: int) -> dict:
def requirements_of_pending(client: Client, minsig: int) -> dict:
"""
GET list of requirements of all pending identities with a minimum of minsig certifications
......@@ -339,12 +337,12 @@ async def requirements_of_pending(client: Client, minsig: int) -> dict:
:param minsig: Minimum number of certifications
:return:
"""
return await client.get(
return client.get(
MODULE + "/requirements-of-pending/%d" % minsig, schema=REQUIREMENTS_SCHEMA
)
async def identity_of(client: Client, search: str) -> dict:
def identity_of(client: Client, search: str) -> dict:
"""
GET Identity data written in the blockchain
......@@ -352,6 +350,4 @@ async def identity_of(client: Client, search: str) -> dict:
:param search: UID or public key
:return:
"""
return await client.get(
MODULE + "/identity-of/%s" % search, schema=IDENTITY_OF_SCHEMA
)
return client.get(MODULE + "/identity-of/%s" % search, schema=IDENTITY_OF_SCHEMA)
......@@ -39,21 +39,21 @@ WS_PEER_SCHEMA = {
}
async def block(client: Client) -> WSConnection:
def block(client: Client) -> WSConnection:
"""
Connect to block websocket
:param client: Client to connect to the api
:return:
"""
return await client.connect_ws(MODULE + "/block")
return client.connect_ws(MODULE + "/block")
async def peer(client: Client) -> WSConnection:
def peer(client: Client) -> WSConnection:
"""
Connect to peer websocket
:param client: Client to connect to the api
:return:
"""
return await client.connect_ws(MODULE + "/peer")
return client.connect_ws(MODULE + "/peer")
......@@ -14,6 +14,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import copy
import json
import logging
from typing import Callable, Union, Any, Optional, Dict
......@@ -21,7 +22,6 @@ from urllib import request, parse
import jsonschema
from websocket import WebSocket
from aiohttp import ClientSession
from urllib3 import HTTPResponse
import duniterpy.api.endpoint as endpoint
......@@ -32,12 +32,8 @@ logger = logging.getLogger("duniter")
# Response type constants
RESPONSE_JSON = "json"
RESPONSE_TEXT = "text"
RESPONSE_AIOHTTP = "aiohttp"
RESPONSE_HTTP = "http"
# Connection type constants
CONNECTION_TYPE_AIOHTTP = 1
# jsonschema validator
ERROR_SCHEMA = {
"type": "object",
......@@ -81,11 +77,11 @@ def parse_error(text: str) -> dict:
return data
async def parse_response(response: str, schema: dict) -> Any:
def parse_response(response: str, schema: dict) -> Any:
"""
Validate and parse the BMA answer
:param response: Response of aiohttp request
:param response: Response content
:param schema: The expected response structure
:return: the json data
"""
......@@ -113,7 +109,7 @@ class WSConnection:
"""
self.connection = connection
async def send_str(self, data: str) -> None:
def send_str(self, data: str):
"""
Send a data string to the web socket connection
......@@ -124,9 +120,8 @@ class WSConnection:
raise Exception("Connection property is empty")
self.connection.send(data)
return None
async def receive_str(self, timeout: Optional[float] = None) -> str:
def receive_str(self, timeout: Optional[float] = None) -> str:
"""
Wait for a data string from the web socket connection
......@@ -139,7 +134,7 @@ class WSConnection:
self.connection.settimeout(timeout)
return self.connection.recv()
async def receive_json(self, timeout: Optional[float] = None) -> Any:
def receive_json(self, timeout: Optional[float] = None) -> Any:
"""
Wait for json data from the web socket connection
......@@ -152,7 +147,7 @@ class WSConnection:
self.connection.settimeout(timeout)
return json.loads(self.connection.recv())
async def close(self) -> None:
def close(self) -> None:
"""
Close the web socket connection
......@@ -161,12 +156,12 @@ class WSConnection:
if self.connection is None:
raise Exception("Connection property is empty")
await self.connection.close()
self.connection.close()
class API:
"""
API is a class used as an abstraction layer over the request library (AIOHTTP).
API is a class used as an abstraction layer over the http/websocket libraries.
"""
def __init__(
......@@ -212,7 +207,7 @@ class API:
return url
async def request_url(
def request_url(
self,
path: str,
method: str = "GET",
......@@ -280,16 +275,17 @@ class API:
)
# get response content
return_response = copy.copy(response)
content = response.read()
response.close()
# if schema supplied...
if schema is not None:
# validate response
await parse_response(content, schema)
parse_response(content, schema)
# return the chosen type
result = response # type: Any
result = return_response # type: Any
if rtype == RESPONSE_TEXT:
result = content
elif rtype == RESPONSE_JSON:
......@@ -297,14 +293,9 @@ class API:
return result
async def connect_ws(self, path: str) -> WSConnection:
def connect_ws(self, path: str) -> WSConnection:
"""
Connect to a websocket in order to use API parameters
In reality, aiohttp.session.ws_connect returns a aiohttp.client._WSRequestContextManager instance.
It must be used in a with statement to get the ClientWebSocketResponse instance from it (__aenter__).
At the end of the with statement, aiohttp.client._WSRequestContextManager.__aexit__ is called
and close the ClientWebSocketResponse in it.
Connect to a websocket
:param path: the url path
:return:
......@@ -316,7 +307,7 @@ class API:
proxy_split = ":".split(self.connection_handler.proxy)
if len(proxy_split) == 2:
host = proxy_split[0]
port = proxy_split[1]
port = int(proxy_split[1])
else:
host = self.connection_handler.proxy
port = 80
......@@ -335,14 +326,12 @@ class Client:
def __init__(
self,
_endpoint: Union[str, endpoint.Endpoint],
session: Optional[ClientSession] = None,
proxy: Optional[str] = None,
) -> None:
"""
Init Client instance
:param _endpoint: Endpoint string in duniter format
:param session: Aiohttp client session (optional, default None)
:param proxy: Proxy server as hostname:port (optional, default None)
"""
if isinstance(_endpoint, str):
......@@ -356,15 +345,9 @@ class Client:
"{0} endpoint in not supported".format(self.endpoint.api)
)
# if no user session...
if session is None:
# open a session
self.session = ClientSession()
else:
self.session = session
self.proxy = proxy
async def get(
def get(
self,
url_path: str,
params: Optional[dict] = None,
......@@ -383,14 +366,14 @@ class Client:
if params is None:
params = dict()
client = API(self.endpoint.conn_handler(self.session, self.proxy))
client = API(self.endpoint.conn_handler(self.proxy))
# get response
return await client.request_url(
return client.request_url(
url_path, "GET", rtype, schema, bma_errors=True, **params
)
async def post(
def post(
self,
url_path: str,
params: Optional[dict] = None,
......@@ -409,14 +392,14 @@ class Client:
if params is None:
params = dict()
client = API(self.endpoint.conn_handler(self.session, self.proxy))
client = API(self.endpoint.conn_handler(self.proxy))
# get response
return await client.request_url(
return client.request_url(
url_path, "POST", rtype, schema, bma_errors=True, **params
)
async def query(
def query(
self,
query: str,
variables: Optional[dict] = None,
......@@ -427,7 +410,6 @@ class Client:
:param query: GraphQL query string
:param variables: Variables for the query (optional, default None)
:param rtype: Response type (optional, default RESPONSE_JSON)
:param schema: Json Schema to validate response (optional, default None)
:return:
"""
......@@ -436,37 +418,29 @@ class Client:
if variables is not None:
payload["variables"] = variables
client = API(self.endpoint.conn_handler(self.session, self.proxy))
client = API(self.endpoint.conn_handler(self.proxy))
# get aiohttp response
response = await client.request_url(
# get json response
response = client.request_url(
"", "POST", rtype=RESPONSE_JSON, schema=schema, json_data=payload
)
# if schema supplied...
if schema is not None:
# validate response
await parse_response(response, schema)
parse_response(response, schema)
return response
async def connect_ws(self, path: str = "") -> WSConnection:
def connect_ws(self, path: str = "") -> WSConnection:
"""
Connect to a websocket in order to use API parameters
:param path: the url path
:return:
"""
client = API(self.endpoint.conn_handler(self.session, self.proxy))
return await client.connect_ws(path)
async def close(self):
"""
Close aiohttp session
:return:
"""
await self.session.close()
client = API(self.endpoint.conn_handler(self.proxy))
return client.connect_ws(path)
def __call__(self, _function: Callable, *args: Any, **kwargs: Any) -> Any:
"""
......
......@@ -18,8 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import re
from typing import Any, Optional, TypeVar, Type, Dict
from aiohttp import ClientSession
import duniterpy.constants as constants
from ..documents import MalformedDocumentError
......@@ -34,7 +32,6 @@ class ConnectionHandler:
server: str,
port: int,
path: str,
session: ClientSession,
proxy: Optional[str] = None,
) -> None:
"""
......@@ -45,7 +42,6 @@ class ConnectionHandler:
:param server: Server IP or domain name
:param port: Port number
:param port: Url path
:param session: Session AIOHTTP
:param proxy: Proxy (optional, default=None)
"""
self.http_scheme = http_scheme
......@@ -54,7 +50,6 @@ class ConnectionHandler:
self.port = port
self.path = path
self.proxy = proxy
self.session = session
def __str__(self) -> str:
return "connection info: %s:%d" % (self.server, self.port)
......@@ -72,9 +67,7 @@ class Endpoint:
def inline(self) -> str:
raise NotImplementedError("inline() is not implemented")
def conn_handler(
self, session: ClientSession, proxy: str = None
) -> ConnectionHandler:
def conn_handler(self, proxy: str = None) -> ConnectionHandler:
raise NotImplementedError("conn_handler is not implemented")
def __str__(self) -> str:
......@@ -121,17 +114,14 @@ class UnknownEndpoint(Endpoint):
doc += " {0}".format(p)
return doc
def conn_handler(
self, session: ClientSession, proxy: str = None
) -> ConnectionHandler:
def conn_handler(self, proxy: str = None) -> ConnectionHandler:
"""
Return connection handler from session
Return connection handler
:param session: AIOHTTP Session
:param proxy: Proxy server
:return:
"""
return ConnectionHandler("", "", "", 0, "", ClientSession())
return ConnectionHandler("", "", "", 0, "")
def __str__(self) -> str:
return "{0} {1}".format(
......@@ -205,27 +195,24 @@ class BMAEndpoint(Endpoint):
PORT=(" {0}".format(self.port) if self.port else ""),
)
def conn_handler(
self, session: ClientSession, proxy: str = None
) -> ConnectionHandler:
def conn_handler(self, proxy: str = None) -> ConnectionHandler:
"""
Return connection handler instance for the endpoint
:param session: AIOHTTP client session instance
:param proxy: Proxy url
:return:
"""
if self.server:
conn_handler = ConnectionHandler(
"http", "ws", self.server, self.port, "", session, proxy
"http", "ws", self.server, self.port, "", proxy
)
elif self.ipv6:
conn_handler = ConnectionHandler(
"http", "ws", "[{0}]".format(self.ipv6), self.port, "", session, proxy
"http", "ws", "[{0}]".format(self.ipv6), self.port, "", proxy
)
else:
conn_handler = ConnectionHandler(
"http", "ws", self.ipv4, self.port, "", session, proxy
"http", "ws", self.ipv4, self.port, "", proxy
)
return conn_handler
......@@ -310,33 +297,24 @@ class SecuredBMAEndpoint(BMAEndpoint):
]
return SecuredBMAEndpoint.API + " " + " ".join(inlined)
def conn_handler(
self, session: ClientSession, proxy: str = None
) -> ConnectionHandler:
def conn_handler(self, proxy: str = None) -> ConnectionHandler:
"""
Return connection handler instance for the endpoint
:param session: AIOHTTP client session instance
:param proxy: Proxy url
:return:
"""
if self.server:
conn_handler = ConnectionHandler(
"https", "wss", self.server, self.port, self.path, session, proxy
"https", "wss", self.server, self.port, self.path, proxy
)
elif self.ipv6:
conn_handler = ConnectionHandler(
"https",
"wss",
"[{0}]".format(self.ipv6),
self.port,
self.path,
session,
proxy,
"https", "wss", "[{0}]".format(self.ipv6), self.port, self.path, proxy
)
else:
conn_handler = ConnectionHandler(
"https", "wss", self.ipv4, self.port, self.path, session, proxy
"https", "wss", self.ipv4, self.port, self.path, proxy
)
return conn_handler
......@@ -396,13 +374,10 @@ class WS2PEndpoint(Endpoint):
]
return WS2PEndpoint.API + " " + " ".join(inlined)
def conn_handler(
self, session: ClientSession, proxy: str = None
) -> ConnectionHandler:
def conn_handler(self, proxy: str = None) -> ConnectionHandler:
"""
Return connection handler instance for the endpoint
:param session: AIOHTTP client session instance
:param proxy: Proxy url
:return:
"""
......@@ -412,13 +387,7 @@ class WS2PEndpoint(Endpoint):
http_scheme += "s"
websocket_scheme += "s"
return ConnectionHandler(
http_scheme,
websocket_scheme,
self.server,
self.port,
self.path,
session,
proxy,
http_scheme, websocket_scheme, self.server, self.port, self.path, proxy
)
def __str__(self) -> str:
......@@ -478,19 +447,14 @@ class ESCoreEndpoint(Endpoint):
inlined = [str(info) for info in (self.server, self.port) if info]
return ESCoreEndpoint.API + " " + " ".join(inlined)
def conn_handler(
self, session: ClientSession, proxy: str = None
) -> ConnectionHandler:
def conn_handler(self, proxy: str = None) -> ConnectionHandler:
"""
Return connection handler instance for the endpoint
:param session: AIOHTTP client session instance
:param proxy: Proxy url
:return:
"""
return ConnectionHandler(
"https", "wss", self.server, self.port, "", session, proxy
)
return ConnectionHandler("https", "wss", self.server, self.port, "", proxy)
def __str__(self) -> str:
return self.inline()
......@@ -544,19 +508,14 @@ class ESUserEndpoint(Endpoint):
inlined = [str(info) for info in (self.server, self.port) if info]
return ESUserEndpoint.API + " " + " ".join(inlined)
def conn_handler(
self, session: ClientSession, proxy: str = None
) -> ConnectionHandler:
def conn_handler(self, proxy: str = None) -> ConnectionHandler:
"""
Return connection handler instance for the endpoint
:param session: AIOHTTP client session instance
:param proxy: Proxy url
:return:
"""
return ConnectionHandler(
"https", "wss", self.server, self.port, "", session, proxy
)
return ConnectionHandler("https", "wss", self.server, self.port, "", proxy)
def __str__(self) -> str:
return self.inline()
......@@ -614,19 +573,14 @@ class ESSubscribtionEndpoint(Endpoint):
inlined = [str(info) for info in (self.server, self.port) if info]
return ESSubscribtionEndpoint.API + " " + " ".join(inlined)
def conn_handler(
self, session: ClientSession, proxy: str = None
) -> ConnectionHandler:
def conn_handler(self, proxy: str = None) -> ConnectionHandler:
"""
Return connection handler instance for the endpoint
:param session: AIOHTTP client session instance
:param proxy: Proxy url
:return:
"""
return ConnectionHandler(
"https", "wss", self.server, self.port, "", session, proxy
)
return ConnectionHandler("https", "wss", self.server, self.port, "", proxy)
def __str__(self) -> str:
return self.inline()
......@@ -718,13 +672,10 @@ class GVAEndpoint(Endpoint):
]
return self.API + " " + " ".join(inlined)
def conn_handler(
self, session: ClientSession, proxy: str = None
) -> ConnectionHandler:
def conn_handler(self, proxy: str = None) -> ConnectionHandler:
"""
Return connection handler instance for the endpoint
:param session: AIOHTTP client session instance
:param proxy: Proxy url
:return:
"""
......@@ -733,13 +684,7 @@ class GVAEndpoint(Endpoint):
if self.server:
conn_handler = ConnectionHandler(
scheme_http,
scheme_ws,
self.server,
self.port,
self.path,
session,
proxy,
scheme_http, scheme_ws, self.server, self.port, self.path, proxy
)
elif self.ipv6:
conn_handler = ConnectionHandler(
......@@ -748,12 +693,11 @@ class GVAEndpoint(Endpoint):
"[{0}]".format(self.ipv6),
self.port,
self.path,
session,
proxy,
)
else:
conn_handler = ConnectionHandler(
scheme_http, scheme_ws, self.ipv4, self.port, self.path, session, proxy
scheme_http, scheme_ws, self.ipv4, self.port, self.path, proxy
)
return conn_handler
......
......@@ -25,7 +25,7 @@ from duniterpy.key import SigningKey
import logging
async def handshake(ws: WSConnection, signing_key: SigningKey, currency: str):
def handshake(ws: WSConnection, signing_key: SigningKey, currency: str):
"""
Perform ws2p handshake on the web socket connection using the signing_key instance
......@@ -41,14 +41,14 @@ async def handshake(ws: WSConnection, signing_key: SigningKey, currency: str):
connect_message = connect_document.get_signed_json(signing_key)
logging.debug("Send CONNECT message")
await ws.send_str(connect_message)
ws.send_str(connect_message)
loop = True
remote_connect_document = None
# Iterate on each message received...
while loop:
data = await ws.receive_json()
data = ws.receive_json()
if "auth" in data and data["auth"] == "CONNECT":
jsonschema.validate(data, ws2p.network.WS2P_CONNECT_MESSAGE_SCHEMA)
......@@ -67,7 +67,7 @@ async def handshake(ws: WSConnection, signing_key: SigningKey, currency: str):
# Send ACK message
logging.debug("Send ACK message...")
await ws.send_str(ack_message)
ws.send_str(ack_message)
if "auth" in data and data["auth"] == "ACK":
jsonschema.validate(data, ws2p.network.WS2P_ACK_MESSAGE_SCHEMA)
......@@ -86,7 +86,7 @@ async def handshake(ws: WSConnection, signing_key: SigningKey, currency: str):
# Send OK message
logging.debug("Send OK message...")
await ws.send_str(ok_message)
ws.send_str(ok_message)
if (
remote_connect_document is not None
......@@ -113,7 +113,7 @@ async def handshake(ws: WSConnection, signing_key: SigningKey, currency: str):
break
async def generate_ws2p_endpoint(
def generate_ws2p_endpoint(
bma_endpoint: Union[str, BMAEndpoint, SecuredBMAEndpoint]
) -> WS2PEndpoint:
"""
......@@ -121,8 +121,7 @@ async def generate_ws2p_endpoint(
Take the first one found
"""
bma_client = Client(bma_endpoint)
peering = await bma_client(bma.network.peering)
await bma_client.close()
peering = bma_client(bma.network.peering)
for endpoint in peering["endpoints"]:
if endpoint.startswith("WS2P"):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment