11from urllib .parse import urlparse , parse_qsl
2- from typing import Tuple , Dict , Union , ItemsView
2+ from typing import Dict , Union , ItemsView , TypedDict , Optional , Sequence , Literal
33
44
5- def etcdurl_parser (url : str ) -> Tuple [bool , Dict [str , Union [str , int , ItemsView ]]]:
6- """解析etcd路径
5+ class EtcdConnParams (TypedDict , total = False ):
6+ host : str
7+ port : int
8+ user : str
9+ password : str
10+ timeout : int
11+ ca_cert : str
12+ cert_key : str
13+ cert_cert : str
14+ grpc_options : ItemsView [str , Union [str , int ]]
15+ options : Dict [str , Union [str , int ]]
16+
17+
18+ class ParserResult (TypedDict , total = False ):
19+ aio : bool
20+ conn_params : EtcdConnParams
21+ key : str
22+ is_prefix : bool
23+
24+
25+ def etcdurl_parser (url : str ) -> ParserResult :
26+ """解析etcd路径.
27+
28+ schema为`etcd`返回的`aio`字段为False,为`etcd+async`返回的`aio`字段为True,其他都为非法.
29+ url中host,port,user,password部分对应etcd中对应内容
30+ url中的path会被作为返回的`key`字段,如果其首字符为`/`则会被去掉,
31+ 当返回中有key时如果在url的参数部分设置is_prefix=true则返回的`is_prefix`会被置为True,否则置为False,
32+ `ca_cert`, `cert_key`, `cert_cert`和`timeout`也在url的参数部分设置,其他的参数则会作为grpc参数传入
33+ 其他的连接参数可以在url的参数部分设置
734
835 Args:
936 url (str): etcd的地址,注意请以`etcd://`或者`etcd+async://`开头
@@ -12,12 +39,15 @@ def etcdurl_parser(url: str) -> Tuple[bool, Dict[str, Union[str, int, ItemsView]
1239 AttributeError: schema 必须为etcd
1340
1441 Returns:
15- Dict[str, Union[str, int, Dict[str, str]]]: 初始化etcd客户端的参数数据
42+ Dict[bool, str,bool, Union[str, int, Dict[str, str]]]: 初始化etcd客户端的参数数据,分别为是否为
1643 """
17- keys = ("timeout" , "ca_cert" , "cert_key" , "cert_cert" )
18- aio = False
19- intkeys = ("timeout" ,)
20- result : Dict [str , Union [str , int , ItemsView ]] = {
44+ conn_str_params = ("ca_cert" , "cert_key" , "cert_cert" )
45+ conn_int_params = ("timeout" ,)
46+ aio : bool = False
47+ key : Optional [str ] = None
48+ is_prefix : Optional [bool ] = None
49+
50+ conn_params : EtcdConnParams = {
2151 "host" : '127.0.0.1' ,
2252 "port" : 2379 ,
2353 }
@@ -28,28 +58,57 @@ def etcdurl_parser(url: str) -> Tuple[bool, Dict[str, Union[str, int, ItemsView]
2858 if schema == "etcd+async" :
2959 aio = True
3060 if parse_result .username :
31- result .update ({"user" : parse_result .username })
61+ conn_params .update ({"user" : parse_result .username })
3262 if parse_result .password :
33- result .update ({"password" : parse_result .password })
63+ conn_params .update ({"password" : parse_result .password })
3464 if parse_result .port :
35- result .update ({"port" : parse_result .port })
65+ conn_params .update ({"port" : parse_result .port })
3666 if parse_result .hostname :
37- result .update ({"host" : parse_result .hostname })
67+ conn_params .update ({"host" : parse_result .hostname })
68+ if parse_result .path :
69+ if parse_result .path not in ("" , "/" ):
70+ if parse_result .path .startswith ("/" ):
71+ key = parse_result .path [1 :]
72+ else :
73+ key = parse_result .path
3874 if parse_result .query :
3975 sql_result = dict (parse_qsl (parse_result .query ))
4076 _grpc_options : Dict [str , Union [str , int ]] = {}
77+ if key is not None :
78+ is_prefix = False
4179 for k , v in sql_result .items ():
42- if k in keys :
43- if k in intkeys :
44- result .update ({k : int (v )})
80+ if k == "is_prefix" and key is not None :
81+ print ("444" )
82+ print (v )
83+ if v .lower () == "false" or v == "0" :
84+ is_prefix = False
4585 else :
46- result .update ({k : v })
86+ is_prefix = True
87+ elif k in conn_str_params :
88+ conn_params [k ] = v # type: ignore
89+ elif k in conn_int_params :
90+ conn_params .update ({k : int (v )}) # type: ignore
4791 else :
4892 if v .isdigit ():
4993 _grpc_options .update ({k : int (v )})
5094 else :
5195 _grpc_options .update ({k : v })
5296 if _grpc_options :
53- grpc_options = _grpc_options .items ()
54- result .update ({"grpc_options" : grpc_options })
55- return aio , result
97+ if aio :
98+ conn_params .update ({"options" : _grpc_options })
99+ else :
100+ grpc_options = _grpc_options .items ()
101+ conn_params .update ({"grpc_options" : grpc_options })
102+ result : ParserResult = {
103+ "aio" : aio ,
104+ "conn_params" : conn_params
105+ }
106+ if key is not None :
107+ result .update ({
108+ "key" : key
109+ })
110+ if is_prefix is not None :
111+ result .update ({
112+ "is_prefix" : is_prefix
113+ })
114+ return result
0 commit comments