PageRenderTime 81ms CodeModel.GetById 22ms app.highlight 46ms RepoModel.GetById 1ms app.codeStats 0ms

/boto-2.5.2/boto/__init__.py

#
Python | 698 lines | 567 code | 29 blank | 102 comment | 16 complexity | 0563aedaaf955f6cdaf678b042077a01 MD5 | raw file
  1# Copyright (c) 2006-2012 Mitch Garnaat http://garnaat.org/
  2# Copyright (c) 2010-2011, Eucalyptus Systems, Inc.
  3# Copyright (c) 2011, Nexenta Systems Inc.
  4# Copyright (c) 2012 Amazon.com, Inc. or its affiliates.
  5# All rights reserved.
  6#
  7# Permission is hereby granted, free of charge, to any person obtaining a
  8# copy of this software and associated documentation files (the
  9# "Software"), to deal in the Software without restriction, including
 10# without limitation the rights to use, copy, modify, merge, publish, dis-
 11# tribute, sublicense, and/or sell copies of the Software, and to permit
 12# persons to whom the Software is furnished to do so, subject to the fol-
 13# lowing conditions:
 14#
 15# The above copyright notice and this permission notice shall be included
 16# in all copies or substantial portions of the Software.
 17#
 18# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 19# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
 20# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
 21# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 22# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 24# IN THE SOFTWARE.
 25#
 26from boto.pyami.config import Config, BotoConfigLocations
 27from boto.storage_uri import BucketStorageUri, FileStorageUri
 28import boto.plugin
 29import os
 30import re
 31import sys
 32import logging
 33import logging.config
 34import urlparse
 35from boto.exception import InvalidUriError
 36
 37__version__ = '2.5.2'
 38Version = __version__  # for backware compatibility
 39
 40UserAgent = 'Boto/%s (%s)' % (__version__, sys.platform)
 41config = Config()
 42
 43
 44def init_logging():
 45    for file in BotoConfigLocations:
 46        try:
 47            logging.config.fileConfig(os.path.expanduser(file))
 48        except:
 49            pass
 50
 51
 52class NullHandler(logging.Handler):
 53    def emit(self, record):
 54        pass
 55
 56log = logging.getLogger('boto')
 57log.addHandler(NullHandler())
 58init_logging()
 59
 60# convenience function to set logging to a particular file
 61
 62
 63def set_file_logger(name, filepath, level=logging.INFO, format_string=None):
 64    global log
 65    if not format_string:
 66        format_string = "%(asctime)s %(name)s [%(levelname)s]:%(message)s"
 67    logger = logging.getLogger(name)
 68    logger.setLevel(level)
 69    fh = logging.FileHandler(filepath)
 70    fh.setLevel(level)
 71    formatter = logging.Formatter(format_string)
 72    fh.setFormatter(formatter)
 73    logger.addHandler(fh)
 74    log = logger
 75
 76
 77def set_stream_logger(name, level=logging.DEBUG, format_string=None):
 78    global log
 79    if not format_string:
 80        format_string = "%(asctime)s %(name)s [%(levelname)s]:%(message)s"
 81    logger = logging.getLogger(name)
 82    logger.setLevel(level)
 83    fh = logging.StreamHandler()
 84    fh.setLevel(level)
 85    formatter = logging.Formatter(format_string)
 86    fh.setFormatter(formatter)
 87    logger.addHandler(fh)
 88    log = logger
 89
 90
 91def connect_sqs(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
 92    """
 93    :type aws_access_key_id: string
 94    :param aws_access_key_id: Your AWS Access Key ID
 95
 96    :type aws_secret_access_key: string
 97    :param aws_secret_access_key: Your AWS Secret Access Key
 98
 99    :rtype: :class:`boto.sqs.connection.SQSConnection`
100    :return: A connection to Amazon's SQS
101    """
102    from boto.sqs.connection import SQSConnection
103    return SQSConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
104
105
106def connect_s3(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
107    """
108    :type aws_access_key_id: string
109    :param aws_access_key_id: Your AWS Access Key ID
110
111    :type aws_secret_access_key: string
112    :param aws_secret_access_key: Your AWS Secret Access Key
113
114    :rtype: :class:`boto.s3.connection.S3Connection`
115    :return: A connection to Amazon's S3
116    """
117    from boto.s3.connection import S3Connection
118    return S3Connection(aws_access_key_id, aws_secret_access_key, **kwargs)
119
120
121def connect_gs(gs_access_key_id=None, gs_secret_access_key=None, **kwargs):
122    """
123    @type gs_access_key_id: string
124    @param gs_access_key_id: Your Google Cloud Storage Access Key ID
125
126    @type gs_secret_access_key: string
127    @param gs_secret_access_key: Your Google Cloud Storage Secret Access Key
128
129    @rtype: L{GSConnection<boto.gs.connection.GSConnection>}
130    @return: A connection to Google's Storage service
131    """
132    from boto.gs.connection import GSConnection
133    return GSConnection(gs_access_key_id, gs_secret_access_key, **kwargs)
134
135
136def connect_ec2(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
137    """
138    :type aws_access_key_id: string
139    :param aws_access_key_id: Your AWS Access Key ID
140
141    :type aws_secret_access_key: string
142    :param aws_secret_access_key: Your AWS Secret Access Key
143
144    :rtype: :class:`boto.ec2.connection.EC2Connection`
145    :return: A connection to Amazon's EC2
146    """
147    from boto.ec2.connection import EC2Connection
148    return EC2Connection(aws_access_key_id, aws_secret_access_key, **kwargs)
149
150
151def connect_elb(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
152    """
153    :type aws_access_key_id: string
154    :param aws_access_key_id: Your AWS Access Key ID
155
156    :type aws_secret_access_key: string
157    :param aws_secret_access_key: Your AWS Secret Access Key
158
159    :rtype: :class:`boto.ec2.elb.ELBConnection`
160    :return: A connection to Amazon's Load Balancing Service
161    """
162    from boto.ec2.elb import ELBConnection
163    return ELBConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
164
165
166def connect_autoscale(aws_access_key_id=None, aws_secret_access_key=None,
167                      **kwargs):
168    """
169    :type aws_access_key_id: string
170    :param aws_access_key_id: Your AWS Access Key ID
171
172    :type aws_secret_access_key: string
173    :param aws_secret_access_key: Your AWS Secret Access Key
174
175    :rtype: :class:`boto.ec2.autoscale.AutoScaleConnection`
176    :return: A connection to Amazon's Auto Scaling Service
177    """
178    from boto.ec2.autoscale import AutoScaleConnection
179    return AutoScaleConnection(aws_access_key_id, aws_secret_access_key,
180                               **kwargs)
181
182
183def connect_cloudwatch(aws_access_key_id=None, aws_secret_access_key=None,
184                       **kwargs):
185    """
186    :type aws_access_key_id: string
187    :param aws_access_key_id: Your AWS Access Key ID
188
189    :type aws_secret_access_key: string
190    :param aws_secret_access_key: Your AWS Secret Access Key
191
192    :rtype: :class:`boto.ec2.cloudwatch.CloudWatchConnection`
193    :return: A connection to Amazon's EC2 Monitoring service
194    """
195    from boto.ec2.cloudwatch import CloudWatchConnection
196    return CloudWatchConnection(aws_access_key_id, aws_secret_access_key,
197                                **kwargs)
198
199
200def connect_sdb(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
201    """
202    :type aws_access_key_id: string
203    :param aws_access_key_id: Your AWS Access Key ID
204
205    :type aws_secret_access_key: string
206    :param aws_secret_access_key: Your AWS Secret Access Key
207
208    :rtype: :class:`boto.sdb.connection.SDBConnection`
209    :return: A connection to Amazon's SDB
210    """
211    from boto.sdb.connection import SDBConnection
212    return SDBConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
213
214
215def connect_fps(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
216    """
217    :type aws_access_key_id: string
218    :param aws_access_key_id: Your AWS Access Key ID
219
220    :type aws_secret_access_key: string
221    :param aws_secret_access_key: Your AWS Secret Access Key
222
223    :rtype: :class:`boto.fps.connection.FPSConnection`
224    :return: A connection to FPS
225    """
226    from boto.fps.connection import FPSConnection
227    return FPSConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
228
229
230def connect_mturk(aws_access_key_id=None, aws_secret_access_key=None,
231                  **kwargs):
232    """
233    :type aws_access_key_id: string
234    :param aws_access_key_id: Your AWS Access Key ID
235
236    :type aws_secret_access_key: string
237    :param aws_secret_access_key: Your AWS Secret Access Key
238
239    :rtype: :class:`boto.mturk.connection.MTurkConnection`
240    :return: A connection to MTurk
241    """
242    from boto.mturk.connection import MTurkConnection
243    return MTurkConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
244
245
246def connect_cloudfront(aws_access_key_id=None, aws_secret_access_key=None,
247                       **kwargs):
248    """
249    :type aws_access_key_id: string
250    :param aws_access_key_id: Your AWS Access Key ID
251
252    :type aws_secret_access_key: string
253    :param aws_secret_access_key: Your AWS Secret Access Key
254
255    :rtype: :class:`boto.fps.connection.FPSConnection`
256    :return: A connection to FPS
257    """
258    from boto.cloudfront import CloudFrontConnection
259    return CloudFrontConnection(aws_access_key_id, aws_secret_access_key,
260                                **kwargs)
261
262
263def connect_vpc(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
264    """
265    :type aws_access_key_id: string
266    :param aws_access_key_id: Your AWS Access Key ID
267
268    :type aws_secret_access_key: string
269    :param aws_secret_access_key: Your AWS Secret Access Key
270
271    :rtype: :class:`boto.vpc.VPCConnection`
272    :return: A connection to VPC
273    """
274    from boto.vpc import VPCConnection
275    return VPCConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
276
277
278def connect_rds(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
279    """
280    :type aws_access_key_id: string
281    :param aws_access_key_id: Your AWS Access Key ID
282
283    :type aws_secret_access_key: string
284    :param aws_secret_access_key: Your AWS Secret Access Key
285
286    :rtype: :class:`boto.rds.RDSConnection`
287    :return: A connection to RDS
288    """
289    from boto.rds import RDSConnection
290    return RDSConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
291
292
293def connect_emr(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
294    """
295    :type aws_access_key_id: string
296    :param aws_access_key_id: Your AWS Access Key ID
297
298    :type aws_secret_access_key: string
299    :param aws_secret_access_key: Your AWS Secret Access Key
300
301    :rtype: :class:`boto.emr.EmrConnection`
302    :return: A connection to Elastic mapreduce
303    """
304    from boto.emr import EmrConnection
305    return EmrConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
306
307
308def connect_sns(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
309    """
310    :type aws_access_key_id: string
311    :param aws_access_key_id: Your AWS Access Key ID
312
313    :type aws_secret_access_key: string
314    :param aws_secret_access_key: Your AWS Secret Access Key
315
316    :rtype: :class:`boto.sns.SNSConnection`
317    :return: A connection to Amazon's SNS
318    """
319    from boto.sns import SNSConnection
320    return SNSConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
321
322
323def connect_iam(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
324    """
325    :type aws_access_key_id: string
326    :param aws_access_key_id: Your AWS Access Key ID
327
328    :type aws_secret_access_key: string
329    :param aws_secret_access_key: Your AWS Secret Access Key
330
331    :rtype: :class:`boto.iam.IAMConnection`
332    :return: A connection to Amazon's IAM
333    """
334    from boto.iam import IAMConnection
335    return IAMConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
336
337
338def connect_route53(aws_access_key_id=None, aws_secret_access_key=None,
339                    **kwargs):
340    """
341    :type aws_access_key_id: string
342    :param aws_access_key_id: Your AWS Access Key ID
343
344    :type aws_secret_access_key: string
345    :param aws_secret_access_key: Your AWS Secret Access Key
346
347    :rtype: :class:`boto.dns.Route53Connection`
348    :return: A connection to Amazon's Route53 DNS Service
349    """
350    from boto.route53 import Route53Connection
351    return Route53Connection(aws_access_key_id, aws_secret_access_key,
352                             **kwargs)
353
354
355def connect_cloudformation(aws_access_key_id=None, aws_secret_access_key=None,
356                           **kwargs):
357    """
358    :type aws_access_key_id: string
359    :param aws_access_key_id: Your AWS Access Key ID
360
361    :type aws_secret_access_key: string
362    :param aws_secret_access_key: Your AWS Secret Access Key
363
364    :rtype: :class:`boto.cloudformation.CloudFormationConnection`
365    :return: A connection to Amazon's CloudFormation Service
366    """
367    from boto.cloudformation import CloudFormationConnection
368    return CloudFormationConnection(aws_access_key_id, aws_secret_access_key,
369                                    **kwargs)
370
371
372def connect_euca(host=None, aws_access_key_id=None, aws_secret_access_key=None,
373                 port=8773, path='/services/Eucalyptus', is_secure=False,
374                 **kwargs):
375    """
376    Connect to a Eucalyptus service.
377
378    :type host: string
379    :param host: the host name or ip address of the Eucalyptus server
380
381    :type aws_access_key_id: string
382    :param aws_access_key_id: Your AWS Access Key ID
383
384    :type aws_secret_access_key: string
385    :param aws_secret_access_key: Your AWS Secret Access Key
386
387    :rtype: :class:`boto.ec2.connection.EC2Connection`
388    :return: A connection to Eucalyptus server
389    """
390    from boto.ec2 import EC2Connection
391    from boto.ec2.regioninfo import RegionInfo
392
393    # Check for values in boto config, if not supplied as args
394    if not aws_access_key_id:
395        aws_access_key_id = config.get('Credentials',
396                                       'euca_access_key_id',
397                                       None)
398    if not aws_secret_access_key:
399        aws_secret_access_key = config.get('Credentials',
400                                           'euca_secret_access_key',
401                                           None)
402    if not host:
403        host = config.get('Boto', 'eucalyptus_host', None)
404
405    reg = RegionInfo(name='eucalyptus', endpoint=host)
406    return EC2Connection(aws_access_key_id, aws_secret_access_key,
407                         region=reg, port=port, path=path,
408                         is_secure=is_secure, **kwargs)
409
410
411def connect_ec2_endpoint(url, aws_access_key_id=None,
412                         aws_secret_access_key=None,
413                         **kwargs):
414    """
415    Connect to an EC2 Api endpoint.  Additional arguments are passed
416    through to connect_ec2.
417
418    :type url: string
419    :param url: A url for the ec2 api endpoint to connect to
420
421    :type aws_access_key_id: string
422    :param aws_access_key_id: Your AWS Access Key ID
423
424    :type aws_secret_access_key: string
425    :param aws_secret_access_key: Your AWS Secret Access Key
426
427    :rtype: :class:`boto.ec2.connection.EC2Connection`
428    :return: A connection to Eucalyptus server
429    """
430    from boto.ec2.regioninfo import RegionInfo
431
432    purl = urlparse.urlparse(url)
433    kwargs['port'] = purl.port
434    kwargs['host'] = purl.hostname
435    kwargs['path'] = purl.path
436    if not 'is_secure' in kwargs:
437        kwargs['is_secure'] = (purl.scheme == "https")
438
439    kwargs['region'] = RegionInfo(name=purl.hostname,
440                                  endpoint=purl.hostname)
441    kwargs['aws_access_key_id'] = aws_access_key_id
442    kwargs['aws_secret_access_key'] = aws_secret_access_key
443
444    return(connect_ec2(**kwargs))
445
446
447def connect_walrus(host=None, aws_access_key_id=None,
448                   aws_secret_access_key=None,
449                   port=8773, path='/services/Walrus', is_secure=False,
450                   **kwargs):
451    """
452    Connect to a Walrus service.
453
454    :type host: string
455    :param host: the host name or ip address of the Walrus server
456
457    :type aws_access_key_id: string
458    :param aws_access_key_id: Your AWS Access Key ID
459
460    :type aws_secret_access_key: string
461    :param aws_secret_access_key: Your AWS Secret Access Key
462
463    :rtype: :class:`boto.s3.connection.S3Connection`
464    :return: A connection to Walrus
465    """
466    from boto.s3.connection import S3Connection
467    from boto.s3.connection import OrdinaryCallingFormat
468
469    # Check for values in boto config, if not supplied as args
470    if not aws_access_key_id:
471        aws_access_key_id = config.get('Credentials',
472                                       'euca_access_key_id',
473                                       None)
474    if not aws_secret_access_key:
475        aws_secret_access_key = config.get('Credentials',
476                                           'euca_secret_access_key',
477                                           None)
478    if not host:
479        host = config.get('Boto', 'walrus_host', None)
480
481    return S3Connection(aws_access_key_id, aws_secret_access_key,
482                        host=host, port=port, path=path,
483                        calling_format=OrdinaryCallingFormat(),
484                        is_secure=is_secure, **kwargs)
485
486
487def connect_ses(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
488    """
489    :type aws_access_key_id: string
490    :param aws_access_key_id: Your AWS Access Key ID
491
492    :type aws_secret_access_key: string
493    :param aws_secret_access_key: Your AWS Secret Access Key
494
495    :rtype: :class:`boto.ses.SESConnection`
496    :return: A connection to Amazon's SES
497    """
498    from boto.ses import SESConnection
499    return SESConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
500
501
502def connect_sts(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
503    """
504    :type aws_access_key_id: string
505    :param aws_access_key_id: Your AWS Access Key ID
506
507    :type aws_secret_access_key: string
508    :param aws_secret_access_key: Your AWS Secret Access Key
509
510    :rtype: :class:`boto.sts.STSConnection`
511    :return: A connection to Amazon's STS
512    """
513    from boto.sts import STSConnection
514    return STSConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
515
516
517def connect_ia(ia_access_key_id=None, ia_secret_access_key=None,
518               is_secure=False, **kwargs):
519    """
520    Connect to the Internet Archive via their S3-like API.
521
522    :type ia_access_key_id: string
523    :param ia_access_key_id: Your IA Access Key ID.  This will also look
524        in your boto config file for an entry in the Credentials
525        section called "ia_access_key_id"
526
527    :type ia_secret_access_key: string
528    :param ia_secret_access_key: Your IA Secret Access Key.  This will also
529        look in your boto config file for an entry in the Credentials
530        section called "ia_secret_access_key"
531
532    :rtype: :class:`boto.s3.connection.S3Connection`
533    :return: A connection to the Internet Archive
534    """
535    from boto.s3.connection import S3Connection
536    from boto.s3.connection import OrdinaryCallingFormat
537
538    access_key = config.get('Credentials', 'ia_access_key_id',
539                            ia_access_key_id)
540    secret_key = config.get('Credentials', 'ia_secret_access_key',
541                            ia_secret_access_key)
542
543    return S3Connection(access_key, secret_key,
544                        host='s3.us.archive.org',
545                        calling_format=OrdinaryCallingFormat(),
546                        is_secure=is_secure, **kwargs)
547
548
549def connect_dynamodb(aws_access_key_id=None,
550                     aws_secret_access_key=None,
551                     **kwargs):
552    """
553    :type aws_access_key_id: string
554    :param aws_access_key_id: Your AWS Access Key ID
555
556    :type aws_secret_access_key: string
557    :param aws_secret_access_key: Your AWS Secret Access Key
558
559    :rtype: :class:`boto.dynamodb.layer2.Layer2`
560    :return: A connection to the Layer2 interface for DynamoDB.
561    """
562    from boto.dynamodb.layer2 import Layer2
563    return Layer2(aws_access_key_id, aws_secret_access_key, **kwargs)
564
565
566def connect_swf(aws_access_key_id=None,
567                aws_secret_access_key=None,
568                **kwargs):
569    """
570    :type aws_access_key_id: string
571    :param aws_access_key_id: Your AWS Access Key ID
572
573    :type aws_secret_access_key: string
574    :param aws_secret_access_key: Your AWS Secret Access Key
575
576    :rtype: :class:`boto.swf.layer1.Layer1`
577    :return: A connection to the Layer1 interface for SWF.
578    """
579    from boto.swf.layer1 import Layer1
580    return Layer1(aws_access_key_id, aws_secret_access_key, **kwargs)
581
582
583def connect_cloudsearch(aws_access_key_id=None,
584                        aws_secret_access_key=None,
585                        **kwargs):
586    """
587    :type aws_access_key_id: string
588    :param aws_access_key_id: Your AWS Access Key ID
589
590    :type aws_secret_access_key: string
591    :param aws_secret_access_key: Your AWS Secret Access Key
592
593    :rtype: :class:`boto.ec2.autoscale.CloudSearchConnection`
594    :return: A connection to Amazon's CloudSearch service
595    """
596    from boto.cloudsearch.layer2 import Layer2
597    return Layer2(aws_access_key_id, aws_secret_access_key,
598                  **kwargs)
599
600
601def storage_uri(uri_str, default_scheme='file', debug=0, validate=True,
602                bucket_storage_uri_class=BucketStorageUri,
603                suppress_consec_slashes=True):
604    """
605    Instantiate a StorageUri from a URI string.
606
607    :type uri_str: string
608    :param uri_str: URI naming bucket + optional object.
609    :type default_scheme: string
610    :param default_scheme: default scheme for scheme-less URIs.
611    :type debug: int
612    :param debug: debug level to pass in to boto connection (range 0..2).
613    :type validate: bool
614    :param validate: whether to check for bucket name validity.
615    :type bucket_storage_uri_class: BucketStorageUri interface.
616    :param bucket_storage_uri_class: Allows mocking for unit tests.
617    :param suppress_consec_slashes: If provided, controls whether
618        consecutive slashes will be suppressed in key paths.
619
620    We allow validate to be disabled to allow caller
621    to implement bucket-level wildcarding (outside the boto library;
622    see gsutil).
623
624    :rtype: :class:`boto.StorageUri` subclass
625    :return: StorageUri subclass for given URI.
626
627    ``uri_str`` must be one of the following formats:
628
629    * gs://bucket/name
630    * s3://bucket/name
631    * gs://bucket
632    * s3://bucket
633    * filename
634
635    The last example uses the default scheme ('file', unless overridden)
636    """
637
638    # Manually parse URI components instead of using urlparse.urlparse because
639    # what we're calling URIs don't really fit the standard syntax for URIs
640    # (the latter includes an optional host/net location part).
641    end_scheme_idx = uri_str.find('://')
642    if end_scheme_idx == -1:
643        # Check for common error: user specifies gs:bucket instead
644        # of gs://bucket. Some URI parsers allow this, but it can cause
645        # confusion for callers, so we don't.
646        if uri_str.find(':') != -1:
647            raise InvalidUriError('"%s" contains ":" instead of "://"' % uri_str)
648        scheme = default_scheme.lower()
649        path = uri_str
650    else:
651        scheme = uri_str[0:end_scheme_idx].lower()
652        path = uri_str[end_scheme_idx + 3:]
653
654    if scheme not in ['file', 's3', 'gs']:
655        raise InvalidUriError('Unrecognized scheme "%s"' % scheme)
656    if scheme == 'file':
657        # For file URIs we have no bucket name, and use the complete path
658        # (minus 'file://') as the object name.
659        is_stream = False
660        if path == '-':
661            is_stream = True
662        return FileStorageUri(path, debug, is_stream)
663    else:
664        path_parts = path.split('/', 1)
665        bucket_name = path_parts[0]
666        if (validate and bucket_name and
667            # Disallow buckets violating charset or not [3..255] chars total.
668            (not re.match('^[a-z0-9][a-z0-9\._-]{1,253}[a-z0-9]$', bucket_name)
669            # Disallow buckets with individual DNS labels longer than 63.
670             or re.search('[-_a-z0-9]{64}', bucket_name))):
671            raise InvalidUriError('Invalid bucket name in URI "%s"' % uri_str)
672        # If enabled, ensure the bucket name is valid, to avoid possibly
673        # confusing other parts of the code. (For example if we didn't
674        # catch bucket names containing ':', when a user tried to connect to
675        # the server with that name they might get a confusing error about
676        # non-integer port numbers.)
677        object_name = ''
678        if len(path_parts) > 1:
679            object_name = path_parts[1]
680        return bucket_storage_uri_class(
681            scheme, bucket_name, object_name, debug,
682            suppress_consec_slashes=suppress_consec_slashes)
683
684
685def storage_uri_for_key(key):
686    """Returns a StorageUri for the given key.
687
688    :type key: :class:`boto.s3.key.Key` or subclass
689    :param key: URI naming bucket + optional object.
690    """
691    if not isinstance(key, boto.s3.key.Key):
692        raise InvalidUriError('Requested key (%s) is not a subclass of '
693                              'boto.s3.key.Key' % str(type(key)))
694    prov_name = key.bucket.connection.provider.get_provider_name()
695    uri_str = '%s://%s/%s' % (prov_name, key.bucket.name, key.name)
696    return storage_uri(uri_str)
697
698boto.plugin.load_plugins(config)