2424
2525import raven
2626from raven .conf import defaults
27+ from raven .conf .remote import RemoteConfig
2728from raven .context import Context
2829from raven .exceptions import APIError , RateLimited
2930from raven .utils import six , json , get_versions , get_auth_header , merge_dicts
3031from raven .utils .encoding import to_unicode
3132from raven .utils .serializer import transform
3233from raven .utils .stacks import get_stack_info , iter_stack_frames , get_culprit
33- from raven .utils .urlparse import urlparse
3434from raven .transport .registry import TransportRegistry , default_transports
3535
3636__all__ = ('Client' ,)
@@ -117,7 +117,7 @@ class Client(object):
117117
118118 _registry = TransportRegistry (transports = default_transports )
119119
120- def __init__ (self , dsn = None , raise_send_errors = False , ** options ):
120+ def __init__ (self , dsn = None , raise_send_errors = False , transport = None , ** options ):
121121 global Raven
122122
123123 o = options
@@ -134,8 +134,8 @@ def __init__(self, dsn=None, raise_send_errors=False, **options):
134134 self .error_logger = logging .getLogger ('sentry.errors' )
135135 self .uncaught_logger = logging .getLogger ('sentry.errors.uncaught' )
136136
137- self .dsns = {}
138- self .set_dsn (dsn , ** options )
137+ self ._transport_cache = {}
138+ self .set_dsn (dsn , transport )
139139
140140 self .include_paths = set (o .get ('include_paths' ) or [])
141141 self .exclude_paths = set (o .get ('exclude_paths' ) or [])
@@ -174,42 +174,27 @@ def __init__(self, dsn=None, raise_send_errors=False, **options):
174174
175175 self ._context = Context ()
176176
177- def set_dsn (self , dsn = None , ** options ):
178- o = options
179-
177+ def set_dsn (self , dsn = None , transport = None ):
180178 if dsn is None and os .environ .get ('SENTRY_DSN' ):
181179 msg = "Configuring Raven from environment variable 'SENTRY_DSN'"
182180 self .logger .debug (msg )
183181 dsn = os .environ ['SENTRY_DSN' ]
184182
185- try :
186- servers , public_key , secret_key , project , transport_options = self .dsns [dsn ]
187- except KeyError :
188- if dsn :
189- # TODO: should we validate other options weren't sent?
190- urlparts = urlparse (dsn )
191- self .logger .debug (
192- "Configuring Raven for host: %s://%s:%s" % (urlparts .scheme ,
193- urlparts .netloc , urlparts .path ))
194- dsn_config = raven .load (dsn , transport_registry = self ._registry )
195- servers = dsn_config ['SENTRY_SERVERS' ]
196- project = dsn_config ['SENTRY_PROJECT' ]
197- public_key = dsn_config ['SENTRY_PUBLIC_KEY' ]
198- secret_key = dsn_config ['SENTRY_SECRET_KEY' ]
199- transport_options = dsn_config .get ('SENTRY_TRANSPORT_OPTIONS' , {})
183+ if dsn not in self ._transport_cache :
184+ if dsn is None :
185+ result = RemoteConfig (transport = transport )
200186 else :
201- servers = ()
202- project = None
203- public_key = None
204- secret_key = None
205- transport_options = {}
206- self .dsns [dsn ] = servers , public_key , secret_key , project , transport_options
207-
208- self .servers = servers
209- self .public_key = public_key
210- self .secret_key = secret_key
211- self .project = project or defaults .PROJECT
212- self .transport_options = transport_options
187+ result = RemoteConfig .from_string (
188+ dsn ,
189+ transport = transport ,
190+ transport_registry = self ._registry ,
191+ )
192+ self ._transport_cache [dsn ] = result
193+ self .remote = result
194+ else :
195+ self .remote = self ._transport_cache [dsn ]
196+
197+ self .logger .debug ("Configuring Raven for host: {0}" .format (self .remote ))
213198
214199 @classmethod
215200 def register_scheme (cls , scheme , transport_class ):
@@ -252,14 +237,6 @@ def get_ident(self, result):
252237 def get_handler (self , name ):
253238 return self .module_cache [name ](self )
254239
255- def _get_public_dsn (self ):
256- url = urlparse (self .servers [0 ])
257- netloc = url .hostname
258- if url .port :
259- netloc += ':%s' % url .port
260- path = url .path .replace ('api/%s/store/' % (self .project ,), self .project )
261- return '//%s@%s%s' % (self .public_key , netloc , path )
262-
263240 def get_public_dsn (self , scheme = None ):
264241 """
265242 Returns a public DSN which is consumable by raven-js
@@ -272,7 +249,7 @@ def get_public_dsn(self, scheme=None):
272249 """
273250 if not self .is_enabled ():
274251 return
275- url = self ._get_public_dsn ()
252+ url = self .remote . get_public_dsn ()
276253 if not scheme :
277254 return url
278255 return '%s:%s' % (scheme , url )
@@ -397,7 +374,7 @@ def build_msg(self, event_type, data=None, date=None,
397374 data ['extra' ][k ] = self .transform (v )
398375
399376 # It's important date is added **after** we serialize
400- data .setdefault ('project' , self .project )
377+ data .setdefault ('project' , self .remote . project )
401378 data .setdefault ('timestamp' , date or datetime .utcnow ())
402379 data .setdefault ('time_spent' , time_spent )
403380 data .setdefault ('event_id' , event_id )
@@ -532,7 +509,7 @@ def is_enabled(self):
532509 Return a boolean describing whether the client should attempt to send
533510 events.
534511 """
535- return bool ( self .servers )
512+ return self .remote . is_active ( )
536513
537514 def _successful_send (self ):
538515 self .state .set_success ()
@@ -590,9 +567,7 @@ def failed_send(e):
590567 self ._failed_send (e , url , self .decode (data ))
591568
592569 try :
593- parsed = urlparse (url )
594- transport = self ._registry .get_transport (
595- parsed , ** self .transport_options )
570+ transport = self .remote .get_transport ()
596571 if transport .async :
597572 transport .async_send (data , headers , self ._successful_send ,
598573 failed_send )
@@ -626,18 +601,22 @@ def send_encoded(self, message, auth_header=None, **kwargs):
626601 protocol = self .protocol_version ,
627602 timestamp = timestamp ,
628603 client = client_string ,
629- api_key = self .public_key ,
630- api_secret = self .secret_key ,
604+ api_key = self .remote . public_key ,
605+ api_secret = self .remote . secret_key ,
631606 )
632607
633- for url in self .servers :
634- headers = {
635- 'User-Agent' : client_string ,
636- 'X-Sentry-Auth' : auth_header ,
637- 'Content-Type' : 'application/octet-stream' ,
638- }
639-
640- self .send_remote (url = url , data = message , headers = headers )
608+ headers = {
609+ 'User-Agent' : client_string ,
610+ 'X-Sentry-Auth' : auth_header ,
611+ 'Content-Type' : 'application/octet-stream' ,
612+ }
613+
614+ self .send_remote (
615+ url = self .remote .store_endpoint ,
616+ data = message ,
617+ headers = headers ,
618+ ** kwargs
619+ )
641620
642621 def encode (self , data ):
643622 """
0 commit comments