Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix test.py imports

Result of first pass of manual merge from branch_master_python3k.

Actually passes SDB tests on both 2.x and 3.x.

Basic S3 operations are now working.

Simple dynamodb requests now working in both versions.
  • Loading branch information...
commit d9b1e1e3601a1a589a972b948457d48d2c063ce4 1 parent 63530ee
@gholms gholms authored garnaat committed
Showing with 608 additions and 521 deletions.
  1. +2 −2 boto/__init__.py
  2. +23 −18 boto/auth.py
  3. +122 −0 boto/compat.py
  4. +18 −24 boto/connection.py
  5. +1 −0  boto/dynamodb/layer1.py
  6. +3 −2 boto/dynamodb/types.py
  7. +2 −2 boto/ec2/autoscale/__init__.py
  8. +4 −4 boto/ec2/buyreservation.py
  9. +1 −1  boto/ec2/cloudwatch/alarm.py
  10. +1 −2  boto/ec2/connection.py
  11. +8 −8 boto/ec2/elb/loadbalancer.py
  12. +0 −9 boto/ec2/reservedinstance.py
  13. +2 −2 boto/ecs/item.py
  14. +5 −5 boto/emr/connection.py
  15. +3 −2 boto/file/key.py
  16. +4 −5 boto/fps/connection.py
  17. +3 −3 boto/gs/key.py
  18. +12 −13 boto/gs/resumable_upload_handler.py
  19. +6 −6 boto/https_connection.py
  20. +7 −7 boto/manage/cmdshell.py
  21. +5 −5 boto/manage/propget.py
  22. +17 −16 boto/manage/server.py
  23. +3 −2 boto/manage/task.py
  24. +14 −14 boto/manage/test_manage.py
  25. +4 −4 boto/manage/volume.py
  26. +0 −1  boto/mashups/server.py
  27. +2 −1  boto/mturk/connection.py
  28. +1 −4 boto/provider.py
  29. +12 −12 boto/pyami/config.py
  30. +11 −11 boto/pyami/launch_ami.py
  31. +0 −1  boto/rds/__init__.py
  32. +5 −16 boto/rds/parametergroup.py
  33. +10 −10 boto/roboto/awsqueryrequest.py
  34. +4 −3 boto/roboto/awsqueryservice.py
  35. +3 −3 boto/route53/connection.py
  36. +11 −11 boto/s3/bucket.py
  37. +8 −8 boto/s3/bucketlogging.py
  38. +7 −6 boto/s3/connection.py
  39. +11 −16 boto/s3/key.py
  40. +6 −7 boto/s3/resumable_download_handler.py
  41. +3 −5 boto/sdb/connection.py
  42. +3 −1 boto/sdb/db/blob.py
  43. +1 −1  boto/sdb/db/manager/xmlmanager.py
  44. +38 −36 boto/sdb/domain.py
  45. +1 −2  boto/services/result.py
  46. +2 −1  boto/ses/connection.py
  47. +2 −2 boto/sqs/message.py
  48. +4 −4 boto/sqs/queue.py
  49. +29 −41 boto/utils.py
  50. +2 −2 tests/autoscale/test_connection.py
  51. +22 −21 tests/cloudfront/test_signed_urls.py
  52. +2 −2 tests/db/test_lists.py
  53. +1 −1  tests/db/test_query.py
  54. +7 −7 tests/db/test_sequence.py
  55. +5 −5 tests/devpay/test_s3.py
  56. +2 −2 tests/dynamodb/test_layer1.py
  57. +5 −3 tests/dynamodb/test_layer2.py
  58. +2 −2 tests/ec2/cloudwatch/test_connection.py
  59. +3 −3 tests/ec2/test_connection.py
  60. +1 −1  tests/emr/test_emr_responses.py
  61. +8 −8 tests/mturk/cleanup_tests.py
  62. +1 −1  tests/mturk/create_hit_with_qualifications.py
  63. +2 −2 tests/mturk/selenium_support.py
  64. +3 −3 tests/s3/mock_storage_service.py
  65. +1 −1  tests/s3/test_bucket.py
  66. +9 −9 tests/s3/test_connection.py
  67. +2 −2 tests/s3/test_encryption.py
  68. +3 −3 tests/s3/test_gsconnection.py
  69. +8 −8 tests/s3/test_key.py
  70. +5 −4 tests/s3/test_mfa.py
  71. +2 −2 tests/s3/test_multidelete.py
  72. +9 −9 tests/s3/test_multipart.py
  73. +7 −9 tests/s3/test_pool.py
  74. +8 −8 tests/s3/test_resumable_downloads.py
  75. +8 −8 tests/s3/test_resumable_uploads.py
  76. +6 −6 tests/s3/test_versioning.py
  77. +3 −3 tests/sdb/test_connection.py
  78. +2 −2 tests/sqs/test_connection.py
  79. +2 −2 tests/sts/test_session_token.py
  80. +23 −23 tests/test.py
View
4 boto/__init__.py
@@ -29,8 +29,8 @@
import os, re, sys
import logging
import logging.config
-import urlparse
from boto.exception import InvalidUriError
+import boto.compat as compat
__version__ = '2.3.0'
Version = __version__ # for backware compatibility
@@ -391,7 +391,7 @@ def connect_ec2_endpoint(url, aws_access_key_id=None, aws_secret_access_key=None
"""
from boto.ec2.regioninfo import RegionInfo
- purl = urlparse.urlparse(url)
+ purl = compat.urlparse(url)
kwargs['port'] = purl.port
kwargs['host'] = purl.hostname
kwargs['path'] = purl.path
View
41 boto/auth.py
@@ -1,5 +1,6 @@
# Copyright 2010 Google Inc.
-# Copyright (c) 2011 Mitch Garnaat http://garnaat.org/
+# Copyright (c) 2012 Mitch Garnaat http://garnaat.org/
+# Copyright (c) 2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# Copyright (c) 2011, Eucalyptus Systems, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
@@ -34,7 +35,7 @@
import boto.utils
import hmac
import sys
-import urllib
+import boto.compat as compat
from email.utils import formatdate
from boto.auth_handler import AuthHandler
@@ -79,10 +80,10 @@ def __init__(self, host, config, provider):
def update_provider(self, provider):
self._provider = provider
- self._hmac = hmac.new(self._provider.secret_key, digestmod=sha)
+ sk = self._provider.secret_key.encode('utf-8')
+ self._hmac = hmac.new(sk, digestmod=sha)
if sha256:
- self._hmac_256 = hmac.new(self._provider.secret_key,
- digestmod=sha256)
+ self._hmac_256 = hmac.new(sk, digestmod=sha256)
else:
self._hmac_256 = None
@@ -97,8 +98,10 @@ def sign_string(self, string_to_sign):
hmac = self._hmac_256.copy()
else:
hmac = self._hmac.copy()
+ if not isinstance(string_to_sign, compat.binary_type):
+ string_to_sign = string_to_sign.encode('utf-8')
hmac.update(string_to_sign)
- return base64.encodestring(hmac.digest()).strip()
+ return base64.b64encode(hmac.digest()).strip().decode('utf-8')
class AnonAuthHandler(AuthHandler, HmacKeys):
"""
@@ -252,6 +255,7 @@ def add_auth(self, req, **kwargs):
req.headers['X-Amz-Security-Token'] = self._provider.security_token
string_to_sign, headers_to_sign = self.string_to_sign(req)
boto.log.debug('StringToSign:\n%s' % string_to_sign)
+ string_to_sign = string_to_sign.encode('utf-8')
hash_value = sha256(string_to_sign).digest()
b64_hmac = self.sign_string(hash_value)
s = "AWS3 AWSAccessKeyId=%s," % self._provider.access_key
@@ -279,7 +283,7 @@ def add_auth(self, http_request, **kwargs):
boto.log.debug('query_string: %s Signature: %s' % (qs, signature))
if http_request.method == 'POST':
headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
- http_request.body = qs + '&Signature=' + urllib.quote_plus(signature)
+ http_request.body = qs + '&Signature=' + compat.quote_plus(signature)
http_request.headers['Content-Length'] = str(len(http_request.body))
else:
http_request.body = ''
@@ -287,7 +291,7 @@ def add_auth(self, http_request, **kwargs):
# already be there, we need to get rid of that and rebuild it
http_request.path = http_request.path.split('?')[0]
http_request.path = (http_request.path + '?' + qs +
- '&Signature=' + urllib.quote_plus(signature))
+ '&Signature=' + compat.quote_plus(signature))
class QuerySignatureV0AuthHandler(QuerySignatureHelper, AuthHandler):
"""Provides Signature V0 Signing"""
@@ -299,13 +303,13 @@ def _calc_signature(self, params, *args):
boto.log.debug('using _calc_signature_0')
hmac = self._hmac.copy()
s = params['Action'] + params['Timestamp']
+ s = s.encode('utf-8')
hmac.update(s)
- keys = params.keys()
- keys.sort(cmp = lambda x, y: cmp(x.lower(), y.lower()))
+ keys = sorted(params, key = str.lower)
pairs = []
for key in keys:
val = boto.utils.get_utf8_value(params[key])
- pairs.append(key + '=' + urllib.quote(val))
+ pairs.append(key + '=' + compat.quote(val))
qs = '&'.join(pairs)
return (qs, base64.b64encode(hmac.digest()))
@@ -320,14 +324,15 @@ class QuerySignatureV1AuthHandler(QuerySignatureHelper, AuthHandler):
def _calc_signature(self, params, *args):
boto.log.debug('using _calc_signature_1')
hmac = self._hmac.copy()
- keys = params.keys()
- keys.sort(cmp = lambda x, y: cmp(x.lower(), y.lower()))
+ keys = sorted(params, key = str.lower)
pairs = []
for key in keys:
+ key = key.encode('utf-8')
hmac.update(key)
val = boto.utils.get_utf8_value(params[key])
+ val = val.encode('utf-8')
hmac.update(val)
- pairs.append(key + '=' + urllib.quote(val))
+ pairs.append(key + '=' + compat.quote(val))
qs = '&'.join(pairs)
return (qs, base64.b64encode(hmac.digest()))
@@ -349,17 +354,17 @@ def _calc_signature(self, params, verb, path, server_name):
params['SignatureMethod'] = 'HmacSHA1'
if self._provider.security_token:
params['SecurityToken'] = self._provider.security_token
- keys = params.keys()
- keys.sort()
+ keys = sorted(params)
pairs = []
for key in keys:
val = boto.utils.get_utf8_value(params[key])
- pairs.append(urllib.quote(key, safe='') + '=' +
- urllib.quote(val, safe='-_~'))
+ pairs.append(compat.quote(key, safe='') + '=' +
+ compat.quote(val, safe='-_~'))
qs = '&'.join(pairs)
boto.log.debug('query string: %s' % qs)
string_to_sign += qs
boto.log.debug('string_to_sign: %s' % string_to_sign)
+ string_to_sign = string_to_sign.encode('utf-8')
hmac.update(string_to_sign)
b64 = base64.b64encode(hmac.digest())
boto.log.debug('len(b64)=%d' % len(b64))
View
122 boto/compat.py
@@ -0,0 +1,122 @@
+# Copyright (c) 2012 Mitch Garnaat http://garnaat.org/
+# Copyright (c) 2012 Amazon.com, Inc. or its affiliates.
+# All Rights Reserved
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish, dis-
+# tribute, sublicense, and/or sell copies of the Software, and to permit
+# persons to whom the Software is furnished to do so, subject to the fol-
+# lowing conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+import sys
+import os
+import types
+
+# True if we are running on Python 3.
+PY3 = sys.version_info[0] == 3
+
+if PY3:
+ string_types = str,
+ integer_types = int,
+ class_types = type,
+ text_type = str
+ binary_type = bytes
+else:
+ string_types = basestring,
+ integer_types = (int, long)
+ class_types = (type, types.ClassType)
+ text_type = unicode
+ binary_type = str
+
+try:
+ import urllib.parse as urlparse
+except ImportError:
+ import urlparse
+
+try:
+ from urllib.parse import quote, quote_plus, unquote
+except ImportError:
+ from urllib import quote, quote_plus, unquote
+
+try:
+ from urllib.request import urlopen, Request, build_opener, install_opener
+except ImportError:
+ from urllib2 import urlopen, Request
+
+try:
+ from urllib.request import HTTPPasswordMgrWithDefaultRealm
+except ImportError:
+ from urllib2 import HTTPPasswordMgrWithDefaultRealm
+
+try:
+ from urllib.request import HTTPBasicAuthHandler, HTTPError
+except ImportError:
+ from urllib2 import HTTPBasicAuthHandler
+
+try:
+ from hashlib import md5
+except ImportError:
+ from md5 import md5
+
+try:
+ import http.client as httplib
+except ImportError:
+ import httplib
+
+try:
+ import configparser
+except ImportError:
+ import ConfigParser as configparser
+
+if PY3:
+ import io
+ StringIO = io.StringIO
+else:
+ import StringIO
+ StringIO = StringIO.StringIO
+
+if PY3:
+ raw_input = input
+else:
+ raw_input = raw_input
+
+try:
+ # Python 3.x
+ from email.mime.multipart import MIMEMultipart
+ from email.mime.base import MIMEBase
+ from email.mime.text import MIMEText
+ from email.utils import formatdate
+ import email.encoders as Encoders
+ unicode = str
+except ImportError:
+ # Python 2.x
+ from email.MIMEMultipart import MIMEMultipart
+ from email.MIMEBase import MIMEBase
+ from email.MIMEText import MIMEText
+ from email.utils import formatdate
+ from email import Encoders
+
+
+def on_appengine():
+ return all(key in os.environ for key in ('USER_IS_ADMIN',
+ 'CURRENT_VERSION_ID',
+ 'APPLICATION_ID'))
+
+
+def httplib_ssl_hack(port):
+ return ((on_appengine and sys.version[:3] == '2.5') or
+ sys.version.startswith('3') or
+ sys.version[:3] in ('2.6', '2.7')) and port == 443
View
42 boto/connection.py
@@ -45,19 +45,17 @@
from __future__ import with_statement
import base64
import errno
-import httplib
import os
-import Queue
import random
import re
import socket
import sys
import time
-import urllib, urlparse
import xml.sax
from . import auth
from . import auth_handler
+from . import compat
import boto
import boto.utils
import boto.handler
@@ -83,9 +81,6 @@
except ImportError:
import dummy_threading as threading
-ON_APP_ENGINE = all(key in os.environ for key in (
- 'USER_IS_ADMIN', 'CURRENT_VERSION_ID', 'APPLICATION_ID'))
-
PORTS_BY_SECURITY = { True: 443, False: 80 }
DEFAULT_CA_CERTS_FILE = os.path.join(
@@ -168,7 +163,7 @@ def _conn_ready(self, conn):
This is ugly, reading a private instance variable, but the
state we care about isn't available in any public methods.
"""
- if ON_APP_ENGINE:
+ if compat.on_appengine():
# Google App Engine implementation of HTTPConnection doesn't contain
# _HTTPConnection__response attribute. Moreover, it's not possible
# to determine if given connection is ready. Reusing connections
@@ -350,8 +345,9 @@ def __str__(self):
def authorize(self, connection, **kwargs):
for key in self.headers:
val = self.headers[key]
- if isinstance(val, unicode):
- self.headers[key] = urllib.quote_plus(val.encode('utf-8'))
+ if isinstance(val, compat.text_type):
+ self.headers[key] = compat.quote_plus(val.encode('utf-8'),
+ safe='/')
connection._auth_handler.add_auth(self, **kwargs)
@@ -429,7 +425,7 @@ def __init__(self, host, aws_access_key_id=None, aws_secret_access_key=None,
'Boto', 'ca_certificates_file', DEFAULT_CA_CERTS_FILE)
self.handle_proxy(proxy, proxy_port, proxy_user, proxy_pass)
# define exceptions from httplib that we want to catch and retry
- self.http_exceptions = (httplib.HTTPException, socket.error,
+ self.http_exceptions = (compat.httplib.HTTPException, socket.error,
socket.gaierror)
# define subclasses of the above that are not retryable.
self.http_unretryable_exceptions = []
@@ -450,7 +446,7 @@ def __init__(self, host, aws_access_key_id=None, aws_secret_access_key=None,
self.protocol = 'http'
self.host = host
self.path = path
- if isinstance(debug, (int, long)):
+ if isinstance(debug, compat.integer_types):
self.debug = debug
else:
self.debug = config.getint('Boto', 'debug', 0)
@@ -547,8 +543,7 @@ def server_name(self, port=None):
# did the same when calculating the V2 signature. In 2.6
# (and higher!)
# it no longer does that. Hence, this kludge.
- if ((ON_APP_ENGINE and sys.version[:3] == '2.5') or
- sys.version[:3] in ('2.6', '2.7')) and port == 443:
+ if compat.httplib_ssl_hack(port):
signature_host = self.host
else:
signature_host = '%s:%d' % (self.host, port)
@@ -583,8 +578,7 @@ def handle_proxy(self, proxy, proxy_port, proxy_user, proxy_pass):
self.proxy_pass = config.get_value('Boto', 'proxy_pass', None)
if not self.proxy_port and self.proxy:
- print "http_proxy environment variable does not specify " \
- "a port, using default"
+ boto.log.warning('http_proxy env variable does not specify a port')
self.proxy_port = self.port
self.use_proxy = (self.proxy != None)
@@ -613,12 +607,12 @@ def new_http_connection(self, host, is_secure):
host, ca_certs=self.ca_certificates_file,
**self.http_connection_kwargs)
else:
- connection = httplib.HTTPSConnection(host,
+ connection = compat.httplib.HTTPSConnection(host,
**self.http_connection_kwargs)
else:
boto.log.debug('establishing HTTP connection: kwargs=%s' %
self.http_connection_kwargs)
- connection = httplib.HTTPConnection(host,
+ connection = compat.httplib.HTTPConnection(host,
**self.http_connection_kwargs)
if self.debug > 1:
connection.set_debuglevel(self.debug)
@@ -646,7 +640,7 @@ def proxy_ssl(self):
for k, v in self.get_proxy_auth_header().items():
sock.sendall("%s: %s\r\n" % (k, v))
sock.sendall("\r\n")
- resp = httplib.HTTPResponse(sock, strict=True, debuglevel=self.debug)
+ resp = compat.httplib.HTTPResponse(sock, strict=True, debuglevel=self.debug)
resp.begin()
if resp.status != 200:
@@ -659,7 +653,7 @@ def proxy_ssl(self):
# We can safely close the response, it duped the original socket
resp.close()
- h = httplib.HTTPConnection(host)
+ h = compat.httplib.HTTPConnection(host)
if self.https_validate_certificates and HAVE_HTTPS_CONNECTION:
boto.log.debug("wrapping ssl socket for proxied connection; "
@@ -678,11 +672,11 @@ def proxy_ssl(self):
hostname, cert, 'hostname mismatch')
else:
# Fallback for old Python without ssl.wrap_socket
- if hasattr(httplib, 'ssl'):
- sslSock = httplib.ssl.SSLSocket(sock)
+ if hasattr(compat.httplib, 'ssl'):
+ sslSock = compat.httplib.ssl.SSLSocket(sock)
else:
sslSock = socket.ssl(sock, None, None)
- sslSock = httplib.FakeSocket(sock, sslSock)
+ sslSock = compat.httplib.FakeSocket(sock, sslSock)
# This is a bit unclean
h.sock = sslSock
@@ -693,7 +687,7 @@ def prefix_proxy_to_path(self, path, host=None):
return path
def get_proxy_auth_header(self):
- auth = base64.encodestring(self.proxy_user + ':' + self.proxy_pass)
+ auth = base64.encodebytes(self.proxy_user + ':' + self.proxy_pass)
return {'Proxy-Authorization': 'Basic %s' % auth}
def _mexe(self, request, sender=None, override_num_retries=None,
@@ -762,7 +756,7 @@ def _mexe(self, request, sender=None, override_num_retries=None,
return response
else:
scheme, request.host, request.path, \
- params, query, fragment = urlparse.urlparse(location)
+ params, query, fragment = compat.urlparse.urlparse(location)
if query:
request.path += '?' + query
msg = 'Redirecting: %s' % scheme + '://'
View
1  boto/dynamodb/layer1.py
@@ -137,6 +137,7 @@ def make_request(self, action, body='', object_hook=None):
self.instrumentation['times'].append(time.time() - start)
self.instrumentation['ids'].append(self.request_id)
response_body = response.read()
+ response_body = response_body.decode('utf-8')
boto.log.debug(response_body)
return json.loads(response_body, object_hook=object_hook)
View
5 boto/dynamodb/types.py
@@ -24,14 +24,15 @@
Some utility functions to deal with mapping Amazon DynamoDB types to
Python types and vice-versa.
"""
+import boto.compat as compat
def is_num(n):
- return isinstance(n, (int, long, float, bool))
+ return isinstance(n, (compat.integer_types, float, bool))
def is_str(n):
- return isinstance(n, basestring)
+ return isinstance(n, compat.string_types)
def convert_num(s):
View
4 boto/ec2/autoscale/__init__.py
@@ -131,9 +131,9 @@ def build_list_params(self, params, items, label):
# different from EC2 list params
for i in xrange(1, len(items)+1):
if isinstance(items[i-1], dict):
- for k, v in items[i-1].iteritems():
+ for k, v in items[i-1].items():
if isinstance(v, dict):
- for kk, vv in v.iteritems():
+ for kk, vv in v.items():
params['%s.member.%d.%s.%s' % (label, i, k, kk)] = vv
else:
params['%s.member.%d.%s' % (label, i, k)] = v
View
8 boto/ec2/buyreservation.py
@@ -66,19 +66,19 @@ def get(self, params):
obj.get(params)
offerings = obj.ec2.get_all_reserved_instances_offerings(instance_type=params['instance_type'],
availability_zone=params['zone'].name)
- print '\nThe following Reserved Instances Offerings are available:\n'
+ print('\nThe following Reserved Instances Offerings are available:\n')
for offering in offerings:
offering.describe()
prop = StringProperty(name='offering', verbose_name='Offering',
choices=offerings)
offering = propget.get(prop)
- print '\nYou have chosen this offering:'
+ print('\nYou have chosen this offering:')
offering.describe()
unit_price = float(offering.fixed_price)
total_price = unit_price * params['quantity']
- print '!!! You are about to purchase %d of these offerings for a total of $%.2f !!!' % (params['quantity'], total_price)
+ print('!!! You are about to purchase %d of these offerings for a total of $%.2f !!!' % (params['quantity'], total_price))
answer = raw_input('Are you sure you want to do this? If so, enter YES: ')
if answer.strip().lower() == 'yes':
offering.purchase(params['quantity'])
else:
- print 'Purchase cancelled'
+ print('Purchase cancelled')
View
2  boto/ec2/cloudwatch/alarm.py
@@ -61,7 +61,7 @@ class MetricAlarm(object):
'<' : 'LessThanThreshold',
'<=' : 'LessThanOrEqualToThreshold',
}
- _rev_cmp_map = dict((v, k) for (k, v) in _cmp_map.iteritems())
+ _rev_cmp_map = dict((v, k) for (k, v) in _cmp_map.items())
def __init__(self, connection=None, name=None, metric=None,
namespace=None, statistic=None, comparison=None,
View
3  boto/ec2/connection.py
@@ -2757,8 +2757,7 @@ def delete_placement_group(self, name):
# Tag methods
def build_tag_param_list(self, params, tags):
- keys = tags.keys()
- keys.sort()
+ keys = sorted(tags)
i = 1
for key in keys:
value = tags[key]
View
16 boto/ec2/elb/loadbalancer.py
@@ -26,6 +26,7 @@
from boto.ec2.elb.securitygroup import SecurityGroup
from boto.ec2.instanceinfo import InstanceInfo
from boto.resultset import ResultSet
+import boto.compat as compat
class LoadBalancer(object):
"""
@@ -137,7 +138,7 @@ def enable_zones(self, zones):
:param zones: The name of the zone(s) to add.
"""
- if isinstance(zones, str) or isinstance(zones, unicode):
+ if isinstance(zones, compat.string_types):
zones = [zones]
new_zones = self.connection.enable_availability_zones(self.name, zones)
self.availability_zones = new_zones
@@ -150,7 +151,7 @@ def disable_zones(self, zones):
:param zones: The name of the zone(s) to add.
"""
- if isinstance(zones, str) or isinstance(zones, unicode):
+ if isinstance(zones, compat.string_types):
zones = [zones]
new_zones = self.connection.disable_availability_zones(self.name, zones)
self.availability_zones = new_zones
@@ -165,7 +166,7 @@ def register_instances(self, instances):
to add to this load balancer.
"""
- if isinstance(instances, str) or isinstance(instances, unicode):
+ if isinstance(instances, compat.string_types):
instances = [instances]
new_instances = self.connection.register_instances(self.name, instances)
self.instances = new_instances
@@ -179,7 +180,7 @@ def deregister_instances(self, instances):
to remove from this load balancer.
"""
- if isinstance(instances, str) or isinstance(instances, unicode):
+ if isinstance(instances, string_types):
instances = [instances]
new_instances = self.connection.deregister_instances(self.name, instances)
self.instances = new_instances
@@ -259,7 +260,7 @@ def attach_subnets(self, subnets):
:param subnets: The name of the subnet(s) to add.
"""
- if isinstance(subnets, str) or isinstance(subnets, unicode):
+ if isinstance(subnets, compat.string_types):
subnets = [subnets]
new_subnets = self.connection.attach_lb_to_subnets(self.name, subnets)
self.subnets = new_subnets
@@ -272,7 +273,7 @@ def detach_subnets(self, subnets):
:param subnets: The name of the subnet(s) to detach.
"""
- if isinstance(subnets, str) or isinstance(subnets, unicode):
+ if isinstance(subnets, compat.string_types):
subnets = [subnets]
new_subnets = self.connection.detach_lb_to_subnets(self.name, subnets)
self.subnets = new_subnets
@@ -287,8 +288,7 @@ def apply_security_groups(self, security_groups):
:param security_groups: The name of the security group(s) to add.
"""
- if isinstance(security_groups, str) or \
- isinstance(security_groups, unicode):
+ if isinstance(security_groups, compat.string_types):
security_groups = [security_groups]
new_sgs = self.connection.apply_security_groups_to_lb(
self.name, security_groups)
View
9 boto/ec2/reservedinstance.py
@@ -59,15 +59,6 @@ def endElement(self, name, value, connection):
else:
setattr(self, name, value)
- def describe(self):
- print 'ID=%s' % self.id
- print '\tInstance Type=%s' % self.instance_type
- print '\tZone=%s' % self.availability_zone
- print '\tDuration=%s' % self.duration
- print '\tFixed Price=%s' % self.fixed_price
- print '\tUsage Price=%s' % self.usage_price
- print '\tDescription=%s' % self.description
-
def purchase(self, instance_count=1):
return self.connection.purchase_reserved_instance_offering(self.id, instance_count)
View
4 boto/ecs/item.py
@@ -22,7 +22,7 @@
import xml.sax
import cgi
-from StringIO import StringIO
+import boto.compat as compat
class ResponseGroup(xml.sax.ContentHandler):
"""A Generic "Response Group", which can
@@ -35,7 +35,7 @@ def __init__(self, connection=None, nodename=None):
self._nodename = nodename
self._nodepath = []
self._curobj = None
- self._xml = StringIO()
+ self._xml = compat.StringIO()
def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, self.__dict__)
View
10 boto/emr/connection.py
@@ -307,7 +307,7 @@ def run_jobflow(self, name, log_uri, ec2_keyname=None,
# Instance group args (for spot instances or a heterogenous cluster)
list_args = self._build_instance_group_list_args(instance_groups)
instance_params = dict(
- ('Instances.%s' % k, v) for k, v in list_args.iteritems()
+ ('Instances.%s' % k, v) for k, v in list_args.items()
)
params.update(instance_params)
@@ -336,7 +336,7 @@ def run_jobflow(self, name, log_uri, ec2_keyname=None,
params['AdditionalInfo'] = additional_info
if api_params:
- for key, value in api_params.iteritems():
+ for key, value in api_params.items():
if value is None:
params.pop(key, None)
else:
@@ -403,7 +403,7 @@ def _build_bootstrap_action_list(self, bootstrap_actions):
params = {}
for i, bootstrap_action in enumerate(bootstrap_actions):
- for key, value in bootstrap_action.iteritems():
+ for key, value in bootstrap_action.items():
params['BootstrapActions.member.%s.%s' % (i + 1, key)] = value
return params
@@ -413,7 +413,7 @@ def _build_step_list(self, steps):
params = {}
for i, step in enumerate(steps):
- for key, value in step.iteritems():
+ for key, value in step.items():
params['Steps.member.%s.%s' % (i+1, key)] = value
return params
@@ -480,6 +480,6 @@ def _build_instance_group_list_args(self, instance_groups):
params = {}
for i, instance_group in enumerate(instance_groups):
ig_dict = self._build_instance_group_args(instance_group)
- for key, value in ig_dict.iteritems():
+ for key, value in ig_dict.items():
params['InstanceGroups.member.%d.%s' % (i+1, key)] = value
return params
View
5 boto/file/key.py
@@ -22,8 +22,9 @@
# File representation of key, for use with "file://" URIs.
-import os, shutil, StringIO
+import os, shutil
import sys
+import boto.compat as compat
class Key(object):
@@ -151,7 +152,7 @@ def get_contents_as_string(self, headers=None, cb=None, num_cb=10,
:returns: The contents of the file as a string
"""
- fp = StringIO.StringIO()
+ fp = compat.StringIO()
self.get_contents_to_file(fp)
return fp.getvalue()
View
9 boto/fps/connection.py
@@ -24,7 +24,6 @@
import xml.sax
import uuid
import boto
-import boto.utils
from boto import handler
from boto.connection import AWSQueryConnection
from boto.resultset import ResultSet
@@ -150,7 +149,7 @@ def make_marketplace_registration_url(self, returnURL, pipelineName,
params['callerReference'] = str(uuid.uuid4())
parts = ''
- for k in sorted(params.keys()):
+ for k in sorted(params):
parts += "&%s=%s" % (k, urllib.quote(params[k], '~'))
canonical = '\n'.join(['GET',
@@ -162,7 +161,7 @@ def make_marketplace_registration_url(self, returnURL, pipelineName,
params["signature"] = signature
urlsuffix = ''
- for k in sorted(params.keys()):
+ for k in sorted(params):
urlsuffix += "&%s=%s" % (k, urllib.quote(params[k], '~'))
urlsuffix = urlsuffix[1:] # strip the first &
@@ -195,7 +194,7 @@ def make_url(self, returnURL, paymentReason, pipelineName,
params['callerReference'] = str(uuid.uuid4())
parts = ''
- for k in sorted(params.keys()):
+ for k in sorted(params):
parts += "&%s=%s" % (k, urllib.quote(params[k], '~'))
canonical = '\n'.join(['GET',
@@ -207,7 +206,7 @@ def make_url(self, returnURL, paymentReason, pipelineName,
params["signature"] = signature
urlsuffix = ''
- for k in sorted(params.keys()):
+ for k in sorted(params):
urlsuffix += "&%s=%s" % (k, urllib.quote(params[k], '~'))
urlsuffix = urlsuffix[1:] # strip the first &
View
6 boto/gs/key.py
@@ -20,9 +20,9 @@
# IN THE SOFTWARE.
import os
-import StringIO
from boto.exception import BotoClientError
from boto.s3.key import Key as S3Key
+import boto.compat as compat
class Key(S3Key):
@@ -348,9 +348,9 @@ def set_contents_from_string(self, s, headers=None, replace=True,
param, if present, will be used as the MD5 values
of the file. Otherwise, the checksum will be computed.
"""
- if isinstance(s, unicode):
+ if isinstance(s, compat.text_type):
s = s.encode("utf-8")
- fp = StringIO.StringIO(s)
+ fp = compat.StringIO(s)
r = self.set_contents_from_file(fp, headers, replace, cb, num_cb,
policy, md5)
fp.close()
View
25 boto/gs/resumable_upload_handler.py
@@ -21,19 +21,18 @@
import cgi
import errno
-import httplib
import os
import random
import re
import socket
import time
-import urlparse
import boto
from boto import config
from boto.connection import AWSAuthConnection
from boto.exception import InvalidUriError
from boto.exception import ResumableTransferDisposition
from boto.exception import ResumableUploadException
+import boto.compat as compat
"""
Handler for Google Cloud Storage resumable uploads. See
@@ -55,7 +54,7 @@
class ResumableUploadHandler(object):
BUFFER_SIZE = 8192
- RETRYABLE_EXCEPTIONS = (httplib.HTTPException, IOError, socket.error,
+ RETRYABLE_EXCEPTIONS = (compat.httplib.HTTPException, IOError, socket.error,
socket.gaierror)
# (start, end) response indicating server has nothing (upload protocol uses
@@ -142,7 +141,7 @@ def _set_tracker_uri(self, uri):
Raises InvalidUriError if URI is syntactically invalid.
"""
- parse_result = urlparse.urlparse(uri)
+ parse_result = compat.urlparse.urlparse(uri)
if (parse_result.scheme.lower() not in ['http', 'https'] or
not parse_result.netloc):
raise InvalidUriError('Invalid tracker URI (%s)' % uri)
@@ -233,7 +232,7 @@ def _query_server_pos(self, conn, file_length):
'Couldn\'t parse upload server state query response (%s)' %
str(resp.getheaders()), ResumableTransferDisposition.START_OVER)
if conn.debug >= 1:
- print 'Server has: Range: %d - %d.' % (server_start, server_end)
+ print('Server has: Range: %d - %d.' % (server_start, server_end))
return (server_start, server_end)
def _start_new_resumable_upload(self, key, headers=None):
@@ -244,7 +243,7 @@ def _start_new_resumable_upload(self, key, headers=None):
"""
conn = key.bucket.connection
if conn.debug >= 1:
- print 'Starting new resumable upload.'
+ print('Starting new resumable upload.')
self.server_has_bytes = 0
# Start a new resumable upload by sending a POST request with an
@@ -393,10 +392,10 @@ def _attempt_resumable_upload(self, key, fp, file_length, headers, cb,
self.server_has_bytes = server_start
key=key
if conn.debug >= 1:
- print 'Resuming transfer.'
+ print('Resuming transfer.')
except ResumableUploadException as e:
if conn.debug >= 1:
- print 'Unable to resume transfer (%s).' % e.message
+ print('Unable to resume transfer (%s).' % e.message)
self._start_new_resumable_upload(key, headers)
else:
self._start_new_resumable_upload(key, headers)
@@ -457,7 +456,7 @@ def _check_final_md5(self, key, etag):
change some of the file and not realize they have inconsistent data.
"""
if key.bucket.connection.debug >= 1:
- print 'Checking md5 against etag.'
+ print('Checking md5 against etag.')
if key.md5 != etag.strip('"\''):
# Call key.open_read() before attempting to delete the
# (incorrect-content) key, so we perform that request on a
@@ -532,7 +531,7 @@ def send_file(self, key, fp, headers, cb=None, num_cb=10):
self._remove_tracker_file()
self._check_final_md5(key, etag)
if debug >= 1:
- print 'Resumable upload complete.'
+ print('Resumable upload complete.')
return
except self.RETRYABLE_EXCEPTIONS as e:
if debug >= 1:
@@ -581,7 +580,7 @@ def send_file(self, key, fp, headers, cb=None, num_cb=10):
# Use binary exponential backoff to desynchronize client requests
sleep_time_secs = random.random() * (2**progress_less_iterations)
if debug >= 1:
- print ('Got retryable failure (%d progress-less in a row).\n'
- 'Sleeping %3.1f seconds before re-trying' %
- (progress_less_iterations, sleep_time_secs))
+ print('Got retryable failure (%d progress-less in a row).\n'
+ 'Sleeping %3.1f seconds before re-trying' %
+ (progress_less_iterations, sleep_time_secs))
time.sleep(sleep_time_secs)
View
12 boto/https_connection.py
@@ -19,14 +19,14 @@
"""Extensions to allow HTTPS requests with SSL certificate validation."""
-import httplib
+import boto.compat as compat
import re
import socket
import ssl
import boto
-class InvalidCertificateException(httplib.HTTPException):
+class InvalidCertificateException(compat.httplib.HTTPException):
"""Raised when a certificate is provided with an invalid hostname."""
def __init__(self, host, cert, reason):
@@ -36,7 +36,7 @@ def __init__(self, host, cert, reason):
host: The hostname the connection was made to.
cert: The SSL certificate (as a dictionary) the host returned.
"""
- httplib.HTTPException.__init__(self)
+ compat.httplib.HTTPException.__init__(self)
self.host = host
self.cert = cert
self.reason = reason
@@ -79,10 +79,10 @@ def ValidateCertificateHostname(cert, hostname):
return False
-class CertValidatingHTTPSConnection(httplib.HTTPConnection):
+class CertValidatingHTTPSConnection(compat.httplib.HTTPConnection):
"""An HTTPConnection that connects over SSL and validates certificates."""
- default_port = httplib.HTTPS_PORT
+ default_port = compat.httplib.HTTPS_PORT
def __init__(self, host, port=None, key_file=None, cert_file=None,
ca_certs=None, strict=None, **kwargs):
@@ -98,7 +98,7 @@ def __init__(self, host, port=None, key_file=None, cert_file=None,
strict: When true, causes BadStatusLine to be raised if the status line
can't be parsed as a valid HTTP/1.0 or 1.1 status line.
"""
- httplib.HTTPConnection.__init__(self, host, port, strict, **kwargs)
+ compat.httplib.HTTPConnection.__init__(self, host, port, strict, **kwargs)
self.key_file = key_file
self.cert_file = cert_file
self.ca_certs = ca_certs
View
14 boto/manage/cmdshell.py
@@ -24,10 +24,10 @@
import os
import time
import shutil
-import StringIO
import paramiko
import socket
import subprocess
+import boto.compat as compat
class SSHClient(object):
@@ -57,21 +57,21 @@ def connect(self):
except socket.error as err:
(value, message) = err.args
if value == 61 or value == 111:
- print 'SSH Connection refused, will retry in 5 seconds'
+ print('SSH Connection refused, will retry in 5 seconds')
time.sleep(5)
retry += 1
else:
raise
except paramiko.BadHostKeyException:
- print "%s has an entry in ~/.ssh/known_hosts and it doesn't match" % self.server.hostname
- print 'Edit that file to remove the entry and then hit return to try again'
+ print("%s has an entry in ~/.ssh/known_hosts and it doesn't match" % self.server.hostname)
+ print('Edit that file to remove the entry and then hit return to try again')
raw_input('Hit Enter when ready')
retry += 1
except EOFError:
- print 'Unexpected Error from SSH Connection, retry in 5 seconds'
+ print('Unexpected Error from SSH Connection, retry in 5 seconds')
time.sleep(5)
retry += 1
- print 'Could not establish SSH connection'
+ print('Could not establish SSH connection')
def open_sftp(self):
return self._ssh_client.open_sftp()
@@ -178,7 +178,7 @@ def shell(self):
def run(self):
boto.log.info('running:%s' % self.command)
- log_fp = StringIO.StringIO()
+ log_fp = compat.StringIO()
process = subprocess.Popen(self.command, shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while process.poll() == None:
View
10 boto/manage/propget.py
@@ -38,7 +38,7 @@ def get(prop, choices=None):
value = choices[i-1]
if isinstance(value, tuple):
value = value[0]
- print '[%d] %s' % (i, value)
+ print('[%d] %s' % (i, value))
value = raw_input('%s [%d-%d]: ' % (prompt, min, max))
try:
int_value = int(value)
@@ -47,18 +47,18 @@ def get(prop, choices=None):
value = value[1]
valid = True
except ValueError:
- print '%s is not a valid choice' % value
+ print('%s is not a valid choice' % value)
except IndexError:
- print '%s is not within the range[%d-%d]' % (min, max)
+ print('%s is not within the range[%d-%d]' % (min, max))
else:
value = raw_input('%s: ' % prompt)
try:
value = prop.validate(value)
if prop.empty(value) and prop.required:
- print 'A value is required'
+ print('A value is required')
else:
valid = True
except:
- print 'Invalid value: %s' % value
+ print('Invalid value: %s' % value)
return value
View
33 boto/manage/server.py
@@ -32,9 +32,10 @@
from boto.manage import propget
from boto.ec2.zone import Zone
from boto.ec2.keypair import KeyPair
-import os, time, StringIO
+import os, time
from contextlib import closing
from boto.exception import EC2ResponseError
+import boto.compat as compat
InstanceTypes = ['m1.small', 'm1.large', 'm1.xlarge',
'c1.medium', 'c1.xlarge',
@@ -49,7 +50,7 @@ def __init__(self, server, uname='root'):
self.ssh_client = SSHClient(server, uname=uname)
def copy_x509(self, key_file, cert_file):
- print '\tcopying cert and pk over to /mnt directory on server'
+ print('\tcopying cert and pk over to /mnt directory on server')
self.ssh_client.open_sftp()
path, name = os.path.split(key_file)
self.remote_key_file = '/mnt/%s' % name
@@ -57,7 +58,7 @@ def copy_x509(self, key_file, cert_file):
path, name = os.path.split(cert_file)
self.remote_cert_file = '/mnt/%s' % name
self.ssh_client.put_file(cert_file, self.remote_cert_file)
- print '...complete!'
+ print('...complete!')
def bundle_image(self, prefix, size, ssh_key):
command = ""
@@ -103,7 +104,7 @@ def bundle(self, bucket=None, prefix=None, key_file=None, cert_file=None,
ssh_key = self.server.get_ssh_key_file()
self.copy_x509(key_file, cert_file)
if not fp:
- fp = StringIO.StringIO()
+ fp = compat.StringIO()
fp.write('sudo mv %s /mnt/boto.cfg; ' % BotoConfigPath)
fp.write('mv ~/.ssh/authorized_keys /mnt/authorized_keys; ')
if clear_history:
@@ -115,13 +116,13 @@ def bundle(self, bucket=None, prefix=None, key_file=None, cert_file=None,
fp.write('sudo mv /mnt/boto.cfg %s; ' % BotoConfigPath)
fp.write('mv /mnt/authorized_keys ~/.ssh/authorized_keys')
command = fp.getvalue()
- print 'running the following command on the remote server:'
- print command
+ print('running the following command on the remote server:')
+ print(command)
t = self.ssh_client.run(command)
- print '\t%s' % t[0]
- print '\t%s' % t[1]
- print '...complete!'
- print 'registering image...'
+ print('\t%s' % t[0])
+ print('\t%s' % t[1])
+ print('...complete!')
+ print('registering image...')
self.image_id = self.server.ec2.register_image(name=prefix, image_location='%s/%s.manifest.xml' % (bucket, prefix))
return self.image_id
@@ -137,7 +138,7 @@ def get_ami_list(self):
def get_region(self, params):
region = params.get('region', None)
- if isinstance(region, str) or isinstance(region, unicode):
+ if isinstance(region, compat.string_types):
region = boto.ec2.get_region(region)
params['region'] = region
if not region:
@@ -189,7 +190,7 @@ def get_ami_id(self, params):
def get_group(self, params):
group = params.get('group', None)
- if isinstance(group, str) or isinstance(group, unicode):
+ if isinstance(group, compat.string_types):
group_list = self.ec2.get_all_security_groups()
for g in group_list:
if g.name == group:
@@ -202,7 +203,7 @@ def get_group(self, params):
def get_key(self, params):
keypair = params.get('keypair', None)
- if isinstance(keypair, str) or isinstance(keypair, unicode):
+ if isinstance(keypair, compat.string_types):
key_list = self.ec2.get_all_key_pairs()
for k in key_list:
if k.name == keypair:
@@ -305,7 +306,7 @@ def create(cls, config_file=None, logical_volume = None, cfg = None, **params):
# deal with possibly passed in logical volume:
if logical_volume != None:
cfg.set('EBS', 'logical_volume_name', logical_volume.name)
- cfg_fp = StringIO.StringIO()
+ cfg_fp = compat.StringIO()
cfg.write(cfg_fp)
# deal with the possibility that zone and/or keypair are strings read from the config file:
if isinstance(zone, Zone):
@@ -325,14 +326,14 @@ def create(cls, config_file=None, logical_volume = None, cfg = None, **params):
instances = reservation.instances
if elastic_ip != None and instances.__len__() > 0:
instance = instances[0]
- print 'Waiting for instance to start so we can set its elastic IP address...'
+ print('Waiting for instance to start so we can set its elastic IP address...')
# Sometimes we get a message from ec2 that says that the instance does not exist.
# Hopefully the following delay will giv eec2 enough time to get to a stable state:
time.sleep(5)
while instance.update() != 'running':
time.sleep(1)
instance.use_ip(elastic_ip)
- print 'set the elastic IP of the first instance to %s' % elastic_ip
+ print('set the elastic IP of the first instance to %s' % elastic_ip)
for instance in instances:
s = cls()
s.ec2 = ec2
View
5 boto/manage/task.py
@@ -23,7 +23,8 @@
import boto
from boto.sdb.db.property import StringProperty, DateTimeProperty, IntegerProperty
from boto.sdb.db.model import Model
-import datetime, subprocess, StringIO, time
+import boto.compat as compat
+import datetime, subprocess, time
def check_hour(val):
if val == '*':
@@ -100,7 +101,7 @@ def check(self):
def _run(self, msg, vtimeout):
boto.log.info('Task[%s] - running:%s' % (self.name, self.command))
- log_fp = StringIO.StringIO()
+ log_fp = compat.StringIO()
process = subprocess.Popen(self.command, shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
nsecs = 5
View
28 boto/manage/test_manage.py
@@ -2,33 +2,33 @@
from boto.manage.volume import Volume
import time
-print '--> Creating New Volume'
+print('--> Creating New Volume')
volume = Volume.create()
-print volume
+print(volume)
-print '--> Creating New Server'
+print('--> Creating New Server')
server_list = Server.create()
server = server_list[0]
-print server
+print(server)
-print '----> Waiting for Server to start up'
+print('----> Waiting for Server to start up')
while server.status != 'running':
- print '*'
+ print('*')
time.sleep(10)
-print '----> Server is running'
+print('----> Server is running')
-print '--> Run "df -k" on Server'
+print('--> Run "df -k" on Server')
status = server.run('df -k')
-print status[1]
+print(status[1])
-print '--> Now run volume.make_ready to make the volume ready to use on server'
+print('--> Now run volume.make_ready to make the volume ready to use on server')
volume.make_ready(server)
-print '--> Run "df -k" on Server'
+print('--> Run "df -k" on Server')
status = server.run('df -k')
-print status[1]
+print(status[1])
-print '--> Do an "ls -al" on the new filesystem'
+print('--> Do an "ls -al" on the new filesystem')
status = server.run('ls -al %s' % volume.mount_point)
-print status[1]
+print(status[1])
View
8 boto/manage/volume.py
@@ -199,7 +199,7 @@ def get_snapshots(self):
def attach(self, server=None):
if self.attachment_state == 'attached':
- print 'already attached'
+ print('already attached')
return None
if server:
self.server = server
@@ -210,7 +210,7 @@ def attach(self, server=None):
def detach(self, force=False):
state = self.attachment_state
if state == 'available' or state == None or state == 'detaching':
- print 'already detached'
+ print('already detached')
return None
ec2 = self.get_ec2_connection()
ec2.detach_volume(self.volume_id, self.server.instance_id, self.device, force)
@@ -353,9 +353,9 @@ def trim_snapshots(self, delete=False):
day=now.day, tzinfo=now.tzinfo)
# Keep the first snapshot from each day of the previous week
one_week = datetime.timedelta(days=7, seconds=60*60)
- print midnight-one_week, midnight
+ print(midnight-one_week, midnight)
previous_week = self.get_snapshot_range(snaps, midnight-one_week, midnight)
- print previous_week
+ print(previous_week)
if not previous_week:
return snaps
current_day = None
View
1  boto/mashups/server.py
@@ -23,7 +23,6 @@
High-level abstraction of an EC2 server
"""
import boto
-import boto.utils
from boto.mashups.iobject import IObject
from boto.pyami.config import Config, BotoConfigPath
from boto.mashups.interactive import interactive_shell
View
3  boto/mturk/connection.py
@@ -31,6 +31,7 @@
from boto.exception import EC2ResponseError
from boto.resultset import ResultSet
from boto.mturk.question import QuestionForm, ExternalQuestion
+import boto.compat as compat
class MTurkRequestError(EC2ResponseError):
"Error for MTurk Requests"
@@ -756,7 +757,7 @@ def get_keywords_as_string(keywords):
keywords = ', '.join(keywords)
if type(keywords) is str:
final_keywords = keywords
- elif type(keywords) is unicode:
+ elif type(keywords) is compat.text_type:
final_keywords = keywords.encode('utf-8')
elif keywords is None:
final_keywords = ""
View
5 boto/provider.py
@@ -33,6 +33,7 @@
from boto.gs.acl import CannedACLStrings as CannedGSACLStrings
from boto.s3.acl import CannedACLStrings as CannedS3ACLStrings
from boto.s3.acl import Policy
+import boto.compat as compat
HEADER_PREFIX_KEY = 'header_prefix'
METADATA_PREFIX_KEY = 'metadata_prefix'
@@ -187,10 +188,6 @@ def get_credentials(self, access_key=None, secret_key=None):
self.secret_key = os.environ[secret_key_name.upper()]
elif config.has_option('Credentials', secret_key_name):
self.secret_key = config.get('Credentials', secret_key_name)
- if isinstance(self.secret_key, unicode):
- # the secret key must be bytes and not unicode to work
- # properly with hmac.new (see http://bugs.python.org/issue5285)
- self.secret_key = str(self.secret_key)
def configure_headers(self):
header_info_map = self.HeaderInfoMap[self.name]
View
24 boto/pyami/config.py
@@ -20,10 +20,10 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
-import StringIO, os, re
+import os, re
import warnings
-import ConfigParser
import boto
+import boto.compat as compat
# If running in Google App Engine there is no "user" and
# os.path.expanduser() will fail. Attempt to detect this case and use a
@@ -55,10 +55,10 @@
BotoConfigLocations.append(expanduser(path))
-class Config(ConfigParser.SafeConfigParser):
+class Config(compat.configparser.SafeConfigParser):
def __init__(self, path=None, fp=None, do_load=True):
- ConfigParser.SafeConfigParser.__init__(self, {'working_dir' : '/mnt/pyami',
+ compat.configparser.SafeConfigParser.__init__(self, {'working_dir' : '/mnt/pyami',
'debug' : '0'})
if do_load:
if path:
@@ -76,7 +76,7 @@ def __init__(self, path=None, fp=None, do_load=True):
def load_credential_file(self, path):
"""Load a credential file as is setup like the Java utilities"""
- c_data = StringIO.StringIO()
+ c_data = compat.StringIO()
c_data.write("[Credentials]\n")
for line in open(path, "r").readlines():
c_data.write(line.replace("AWSAccessKeyId", "aws_access_key_id").replace("AWSSecretKey", "aws_secret_access_key"))
@@ -99,7 +99,7 @@ def save_option(self, path, section, option, value):
Replace any previous value. If the path doesn't exist, create it.
Also add the option the the in-memory config.
"""
- config = ConfigParser.SafeConfigParser()
+ config = compat.configparser.SafeConfigParser()
config.read(path)
if not config.has_section(section):
config.add_section(section)
@@ -143,21 +143,21 @@ def get_value(self, section, name, default=None):
def get(self, section, name, default=None):
try:
- val = ConfigParser.SafeConfigParser.get(self, section, name)
+ val = compat.configparser.SafeConfigParser.get(self, section, name)
except:
val = default
return val
def getint(self, section, name, default=0):
try:
- val = ConfigParser.SafeConfigParser.getint(self, section, name)
+ val = compat.configparser.SafeConfigParser.getint(self, section, name)
except:
val = int(default)
return val
def getfloat(self, section, name, default=0.0):
try:
- val = ConfigParser.SafeConfigParser.getfloat(self, section, name)
+ val = compat.configparser.SafeConfigParser.getfloat(self, section, name)
except:
val = float(default)
return val
@@ -180,13 +180,13 @@ def setbool(self, section, name, value):
self.set(section, name, 'false')
def dump(self):
- s = StringIO.StringIO()
+ s = compat.StringIO()
self.write(s)
- print s.getvalue()
+ print(s.getvalue())
def dump_safe(self, fp=None):
if not fp:
- fp = StringIO.StringIO()
+ fp = compat.StringIO()
for section in self.sections():
fp.write('[%s]\n' % section)
for option in self.options(section):
View
22 boto/pyami/launch_ami.py
@@ -68,7 +68,7 @@
"""
def usage():
- print usage_string
+ print(usage_string)
sys.exit()
def main():
@@ -124,14 +124,14 @@ def main():
required = ['ami']
for pname in required:
if not params.get(pname, None):
- print '%s is required' % pname
+ print('%s is required' % pname)
usage()
if params['script_name']:
# first copy the desired module file to S3 bucket
if reload:
- print 'Reloading module %s to S3' % params['script_name']
+ print('Reloading module %s to S3' % params['script_name'])
else:
- print 'Copying module %s to S3' % params['script_name']
+ print('Copying module %s to S3' % params['script_name'])
l = imp.find_module(params['script_name'])
c = boto.connect_s3()
bucket = c.get_bucket(params['script_bucket'])
@@ -155,23 +155,23 @@ def main():
r = img.run(user_data=s, key_name=params['keypair'],
security_groups=[params['group']],
max_count=params.get('num_instances', 1))
- print 'AMI: %s - %s (Started)' % (params['ami'], img.location)
- print 'Reservation %s contains the following instances:' % r.id
+ print('AMI: %s - %s (Started)' % (params['ami'], img.location))
+ print('Reservation %s contains the following instances:' % r.id)
for i in r.instances:
- print '\t%s' % i.id
+ print('\t%s' % i.id)
if wait:
running = False
while not running:
time.sleep(30)
[i.update() for i in r.instances]
status = [i.state for i in r.instances]
- print status
+ print(status)
if status.count('running') == len(r.instances):
running = True
for i in r.instances:
- print 'Instance: %s' % i.ami_launch_index
- print 'Public DNS Name: %s' % i.public_dns_name
- print 'Private DNS Name: %s' % i.private_dns_name
+ print('Instance: %s' % i.ami_launch_index)
+ print('Public DNS Name: %s' % i.public_dns_name)
+ print('Private DNS Name: %s' % i.private_dns_name)
if __name__ == "__main__":
main()
View
1  boto/rds/__init__.py
@@ -20,7 +20,6 @@
# IN THE SOFTWARE.
#
-import boto.utils
import urllib
from boto.connection import AWSQueryConnection
from boto.rds.dbinstance import DBInstance
View
21 boto/rds/parametergroup.py
@@ -19,6 +19,9 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
+import boto.compat as compat
+
+
class ParameterGroup(dict):
def __init__(self, connection=None):
@@ -133,7 +136,7 @@ def merge(self, d, i):
d[prefix+'ApplyMethod'] = self.apply_method
def _set_string_value(self, value):
- if not isinstance(value, str) or isinstance(value, unicode):
+ if not isinstance(value, compat.string_types):
raise ValueError('value must be of type str')
if self.allowed_values:
choices = self.allowed_values.split(',')
@@ -142,21 +145,7 @@ def _set_string_value(self, value):
self._value = value
def _set_integer_value(self, value):
- if isinstance(value, str) or isinstance(value, unicode):
- value = int(value)
- if isinstance(value, int) or isinstance(value, long):
- if self.allowed_values:
- min, max = self.allowed_values.split('-')
- if value < int(min) or value > int(max):
- raise ValueError('range is %s' % self.allowed_values)
- self._value = value
- else:
- raise ValueError('value must be integer')
-
- def _set_boolean_value(self, value):
- if isinstance(value, bool):
- self._value = value
- elif isinstance(value, str) or isinstance(value, unicode):
+ if isinstance(value, compat.string_types):
if value.lower() == 'true':
self._value = True
else:
View
20 boto/roboto/awsqueryrequest.py
@@ -47,10 +47,10 @@ def excepthook(typ, value, tb):
else:
debugger.post_mortem(tb)
elif debug_flag:
- print traceback.print_tb(tb)
+ print(traceback.print_tb(tb))
sys.exit(1)
else:
- print value
+ print(value)
sys.exit(1)
return excepthook
@@ -69,7 +69,7 @@ def append(self, datum):
def print_it(self):
if not self.printed:
- print self.line
+ print(self.line)
self.printed = True
class RequiredParamError(boto.exception.BotoClientError):
@@ -342,9 +342,9 @@ def add_standard_options(self):
def process_standard_options(self, options, args, d):
if hasattr(options, 'help_filters') and options.help_filters:
- print 'Available filters:'
+ print('Available filters:')
for filter in self.Filters:
- print '%s\t%s' % (filter.name, filter.doc)
+ print('%s\t%s' % (filter.name, filter.doc))
sys.exit(0)
if options.debug:
self.args['debug'] = 2
@@ -358,7 +358,7 @@ def process_standard_options(self, options, args, d):
self.args['aws_secret_access_key'] = options.secret_key
if options.version:
# TODO - Where should the version # come from?
- print 'version x.xx'
+ print('version x.xx')
exit(0)
sys.excepthook = boto_except_hook(options.debugger,
options.debug)
@@ -453,16 +453,16 @@ def do_cli(self):
response = self.main()
self.cli_formatter(response)
except RequiredParamError as e:
- print e
+ print(e)
sys.exit(1)
except self.ServiceClass.ResponseError as err:
- print 'Error(%s): %s' % (err.error_code, err.error_message)
+ print('Error(%s): %s' % (err.error_code, err.error_message))
sys.exit(1)
except boto.roboto.awsqueryservice.NoCredentialsError as err:
- print 'Unable to find credentials.'
+ print('Unable to find credentials.')
sys.exit(1)
except Exception as e:
- print e
+ print(e)
sys.exit(1)
def _generic_cli_formatter(self, fmt, data, label=''):
View
7 boto/roboto/awsqueryservice.py
@@ -1,11 +1,12 @@
import os
-import urlparse
import boto
import boto.connection
import boto.jsonresponse
import boto.exception
+import boto.compat as compat
from . import awsqueryrequest
+
class NoCredentialsError(boto.exception.BotoClientError):
def __init__(self):
@@ -77,7 +78,7 @@ def check_for_credential_file(self):
value = value.strip()
self.args['aws_secret_access_key'] = value
else:
- print 'Warning: unable to read AWS_CREDENTIAL_FILE'
+ print('Warning: unable to read AWS_CREDENTIAL_FILE')
def check_for_env_url(self):
"""
@@ -95,7 +96,7 @@ def check_for_env_url(self):
if not url and self.EnvURL in os.environ:
url = os.environ[self.EnvURL]
if url:
- rslt = urlparse.urlparse(url)
+ rslt = compat.urlparse.urlparse(url)
if 'is_secure' not in self.args:
if rslt.scheme == 'https':
self.args['is_secure'] = True
View
6 boto/route53/connection.py
@@ -24,12 +24,12 @@
import xml.sax
import time
import uuid
-import urllib
import boto
from boto.connection import AWSAuthConnection
from boto import handler
from boto.resultset import ResultSet
import boto.jsonresponse
+import boto.compat as compat
from . import exception
from . import hostedzone
@@ -67,9 +67,9 @@ def _required_auth_capability(self):
def make_request(self, action, path, headers=None, data='', params=None):
if params:
pairs = []
- for key, val in params.iteritems():
+ for key, val in params.items():
if val is None: continue
- pairs.append(key + '=' + urllib.quote(str(val)))
+ pairs.append(key + '=' + compat.quote(str(val)))
path += '?' + '&'.join(pairs)
return AWSAuthConnection.make_request(self, action, path, headers, data)
View
22 boto/s3/bucket.py
@@ -38,11 +38,11 @@
from boto.s3.bucketlistresultset import MultiPartUploadListResultSet
from boto.s3.lifecycle import Lifecycle
from boto.s3.bucketlogging import BucketLogging
+import boto.compat as compat
import boto.jsonresponse
import boto.utils
import xml.sax
import xml.sax.saxutils
-import StringIO
import urllib
import re
import base64
@@ -291,7 +291,7 @@ def _get_all(self, element_map, initial_query_string='',
k = k.replace('_', '-')
if k == 'maxkeys':
k = 'max-keys'
- if isinstance(v, unicode):
+ if isinstance(v, compat.text_type):
v = v.encode('utf-8')
if v is not None and v != '':
l.append('%s=%s' % (urllib.quote(k), urllib.quote(str(v))))
@@ -484,10 +484,10 @@ def delete_keys(self, keys, quiet=False, mfa_token=None, headers=None):
query_args = 'delete'
def delete_keys2(hdrs):
hdrs = hdrs or {}
- data = u"""<?xml version="1.0" encoding="UTF-8"?>"""
- data += u"<Delete>"
+ data = """<?xml version="1.0" encoding="UTF-8"?>"""
+ data += "<Delete>"
if quiet:
- data += u"<Quiet>true</Quiet>"
+ data += "<Quiet>true</Quiet>"
count = 0
while count < 1000:
try:
@@ -515,15 +515,15 @@ def delete_keys2(hdrs):
continue
count += 1
#key_name = key_name.decode('utf-8')
- data += u"<Object><Key>%s</Key>" % xml.sax.saxutils.escape(key_name)
+ data += "<Object><Key>%s</Key>" % xml.sax.saxutils.escape(key_name)
if version_id:
- data += u"<VersionId>%s</VersionId>" % version_id
- data += u"</Object>"
- data += u"</Delete>"
+ data += "<VersionId>%s</VersionId>" % version_id
+ data += "</Object>"
+ data += "</Delete>"
if count <= 0:
return False # no more