1
1
# encoding: utf-8
2
2
import hashlib
3
- import json
4
3
import logging
5
4
from copy import copy
6
5
from slimurl import URL
17
16
log = logging .getLogger (__name__ )
18
17
19
18
20
- def async_retrying (number , exceptions = (Exception ,)):
21
- def decorator (func ):
22
- @coroutine
23
- def wrap (* args , ** kwargs ):
24
- last_exc = None
25
- for i in range (number ):
26
- try :
27
- raise Return ((yield func (* args , ** kwargs )))
28
- except Return :
29
- raise
30
- except exceptions as e :
31
- log .exception ("Error on attempt: %r" , i )
32
- last_exc = e
33
-
34
- if last_exc :
35
- raise last_exc
36
- return wrap
37
- return decorator
38
-
39
-
40
19
def normalize_package_name (name ):
41
20
return name .lower ().replace ("_" , "-" ).replace ("." , "-" )
42
21
@@ -47,20 +26,19 @@ class PYPIClient(object):
47
26
THREAD_POOL = None
48
27
INDEX = None
49
28
XMLRPC = None
50
- RPC_URL = None
51
29
LOCK = None
52
30
53
31
@classmethod
54
32
def configure (cls , backend , thread_pool ):
55
33
cls .CLIENT = AsyncHTTPClient (io_loop = IOLoop .current ())
56
34
cls .BACKEND = backend
57
35
cls .THREAD_POOL = thread_pool
58
- cls .RPC_URL = copy (backend )(path = "/pypi" )
59
- cls .XMLRPC = ServerProxy (str (cls .RPC_URL ))
36
+ cls .XMLRPC = ServerProxy (
37
+ str (copy (backend )(path = "/pypi" )),
38
+ )
60
39
cls .LOCK = Lock ()
61
40
62
41
@classmethod
63
- @async_retrying (5 )
64
42
@coroutine
65
43
@Cache (HOUR , files_cache = True , ignore_self = True )
66
44
def packages (cls ):
@@ -76,7 +54,6 @@ def packages(cls):
76
54
raise Return (index )
77
55
78
56
@classmethod
79
- @async_retrying (5 )
80
57
@coroutine
81
58
@Cache (4 * HOUR , files_cache = True , ignore_self = True )
82
59
def search (cls , names , descriptions , operator = "or" ):
@@ -85,7 +62,6 @@ def search(cls, names, descriptions, operator="or"):
85
62
raise Return (result )
86
63
87
64
@classmethod
88
- @async_retrying (5 )
89
65
@coroutine
90
66
def exists (cls , name ):
91
67
try :
@@ -100,7 +76,6 @@ def exists(cls, name):
100
76
raise Return (True )
101
77
102
78
@classmethod
103
- @async_retrying (5 )
104
79
@coroutine
105
80
def find_real_name (cls , name ):
106
81
if not options .pypi_proxy :
@@ -117,7 +92,6 @@ def find_real_name(cls, name):
117
92
raise Return (real_name )
118
93
119
94
@classmethod
120
- @async_retrying (5 )
121
95
@coroutine
122
96
@Cache (4 * HOUR , files_cache = True , ignore_self = True )
123
97
def releases (cls , name ):
@@ -145,20 +119,15 @@ def releases(cls, name):
145
119
raise Return (set (res ))
146
120
147
121
@classmethod
148
- @async_retrying (5 )
149
122
@coroutine
150
123
@Cache (MONTH , files_cache = True , ignore_self = True )
151
124
def release_data (cls , name , version ):
152
- url = copy (cls .RPC_URL )
153
- url .path_append (str (name ), str (version ), 'json' )
154
- log .info ("Gathering info %s" , url )
155
-
156
- response = json .loads ((yield cls .CLIENT .fetch (str (url ))).body )
157
- info = response ['info' ]
158
- files = response ['urls' ]
125
+ info , files = yield [
126
+ cls .XMLRPC .release_data (str (name ), str (version )),
127
+ cls .XMLRPC .release_urls (str (name ), str (version ))
128
+ ]
159
129
160
130
download_url = info .get ('download_url' )
161
-
162
131
if download_url and not files :
163
132
try :
164
133
url = URL (download_url )
0 commit comments