9
9
__location__ = os .path .realpath (os .path .join (os .getcwd (), os .path .dirname (__file__ )))
10
10
11
11
12
- class JSONRPCError (Exception ):
13
- pass
14
-
15
-
16
12
@dataclass
17
13
class RPCMethod :
18
14
name : str
@@ -43,11 +39,26 @@ class DiscoveryResult:
43
39
supported : bool | None = None
44
40
error_message : str | None = None
45
41
42
+ def to_string (self ) -> str :
43
+ if self .supported is True :
44
+ return f"{ self .method } , ✔"
45
+ elif self .supported is False :
46
+ return f"{ self .method } , ✖"
47
+ else :
48
+ return f"{ self .method } , { self .error_message } "
49
+
46
50
47
51
class RPCDiscovery :
48
52
METHODS_FILE = Path (os .path .join (__location__ , "methods.json" ))
49
53
CLIENTS_FILE = Path (os .path .join (__location__ , "clients.json" ))
50
54
55
+ def __init__ (self , endpoint : str , clients : list [str ]):
56
+ self .endpoint = endpoint
57
+ self .clients = clients
58
+
59
+ self .methods = self .get_methods_list (clients )
60
+ self .http = httpx .Client ()
61
+
51
62
@staticmethod
52
63
def _parse_methods () -> list [RPCMethod ]:
53
64
methods = []
@@ -69,12 +80,13 @@ def _parse_clients() -> list[RPCClient]:
69
80
return clients
70
81
71
82
@classmethod
72
- def _get_methods_list (cls , clients : list [str ]) -> list [str ]:
83
+ def get_methods_list (cls , clients : list [str ]) -> list [str ]:
73
84
methods = []
74
85
for method in cls ._parse_methods ():
75
86
for client in clients :
76
87
if client in method .supported_clients :
77
- methods .append (method .name )
88
+ if method .name not in methods :
89
+ methods .append (method .name )
78
90
return methods
79
91
80
92
@classmethod
@@ -86,38 +98,47 @@ def get_clients(cls) -> list[RPCClient]:
86
98
return cls ._parse_clients ()
87
99
88
100
@classmethod
89
- def discover_methods (cls , endpoint : str , clients : list [str ]) -> list [DiscoveryResult ]:
90
- result : list [DiscoveryResult ] = []
91
- http = httpx .Client (base_url = endpoint )
92
-
93
- method_list = cls ._get_methods_list (clients )
94
-
95
- for method in method_list :
96
- data = {
97
- "id" : 1 ,
98
- "jsonrpc" : "2.0" ,
99
- "method" : method ,
100
- "params" : [],
101
+ def check_response (cls , method : str , response : httpx .Response ) -> DiscoveryResult :
102
+ keywords = ["not supported" , "unsupported" ]
103
+
104
+ if response .status_code not in [200 , 400 ]:
105
+ return DiscoveryResult (method , None , f"HTTP error { response .status_code } " )
106
+ try :
107
+ response_json = response .json ()
108
+ if "error" in response_json :
109
+ error_code = response_json ["error" ]["code" ]
110
+ if error_code in [- 32600 , - 32604 ]:
111
+ for keyword in keywords :
112
+ if keyword in response_json ["error" ]["message" ].lower ():
113
+ return DiscoveryResult (method , False )
114
+ if error_code == - 32601 :
115
+ return DiscoveryResult (method , False )
116
+ if error_code == - 32602 :
117
+ return DiscoveryResult (method , True )
118
+ return DiscoveryResult (
119
+ method ,
120
+ None ,
121
+ f"Unable to determine. Unknown error { response_json ['error' ]['code' ]} : "
122
+ f"{ response_json ['error' ]['message' ]} " ,
123
+ )
124
+ return DiscoveryResult (method , True )
125
+ except ValueError :
126
+ return DiscoveryResult (method , None , f"Value error { response .json ()} " )
127
+
128
+ def discover_method (self , method : str ) -> DiscoveryResult :
129
+ data = {
130
+ "id" : 1 ,
131
+ "jsonrpc" : "2.0" ,
132
+ "method" : method ,
133
+ "params" : [],
134
+ }
135
+ try :
136
+ headers = {
137
+ "User-Agent" : "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) "
138
+ "AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148"
101
139
}
102
- response = http .post (endpoint , json = data )
103
- if response .status_code != 200 :
104
- print (f"HTTP Error { response .status_code } with method { method } " )
105
- else :
106
- response_json = response .json ()
107
- if "error" in response_json :
108
- if response_json ["error" ]["code" ] == - 32602 :
109
- result .append (DiscoveryResult (method , True ))
110
- elif response_json ["error" ]["code" ] == - 32601 :
111
- result .append (DiscoveryResult (method , False ))
112
- else :
113
- result .append (
114
- DiscoveryResult (
115
- method ,
116
- None ,
117
- f"Unable to determine. Unknown error { response_json ['error' ]['code' ]} : "
118
- f"{ response_json ['error' ]['message' ]} " ,
119
- )
120
- )
121
- else :
122
- result .append (DiscoveryResult (method , True ))
123
- return result
140
+ response = self .http .post (self .endpoint , json = data , headers = headers )
141
+ return self .check_response (method , response )
142
+
143
+ except httpx .TimeoutException as e :
144
+ return DiscoveryResult (method , None , f"HTTP Timeout Exception: { e } " )
0 commit comments