Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
2013-07-08 Version 0.7.0
* Added service bus management API
* Added support for list blobs delimiter (for easier hierarchical listings)
* Fixes for bugs:
#90 get_blob_metadata returns more than the metadata (also get_container_metadata and get_queue_metadata)
#87 Proxy support for *NIX systems
#86 Fix capitalization in the 'Fingerprint' tag for XML of serialization of SSH keys configuration
#83 Fixed an issue that prevented the creation of endpoints for a VM
#80 Error deserializing datetime value from Table Store
#79 Specify VirtualNetworkName when creating Virtual Machine
* Cleanup of imports
* Renamed some private functions that weren't starting with an underscore
* Removed code generator (it's now obsolete, we make changes directly in the Python sources)

Thank you to timanovsky, sebhomengo, pneumee, ogrisel, 0xc0decafe and apatard for their bug reports and fixes.

2013-03-20 Version 0.6.2
* Fixes for bugs:
#75 crash on python 2.7 x64 windows
Expand All @@ -14,5 +30,6 @@
* Added service management API
* Added ability to specify custom hosts
* Added proxy server support (HTTP CONNECT tunneling)

2012-06-06 Version 0.5.0
* Initial Release
2 changes: 2 additions & 0 deletions src/azure.pyproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
<Compile Include="azure\http\httpclient.py" />
<Compile Include="azure\http\winhttp.py" />
<Compile Include="azure\http\__init__.py" />
<Compile Include="azure\servicemanagement\servicebusmanagementservice.py" />
<Compile Include="azure\servicemanagement\servicemanagementclient.py" />
<Compile Include="azure\servicemanagement\servicemanagementservice.py" />
<Compile Include="azure\servicemanagement\__init__.py" />
<Compile Include="azure\servicebus\servicebusservice.py" />
Expand Down
15 changes: 13 additions & 2 deletions src/azure.sln
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "azure", "azure.pyproj", "{25B2C65A-0553-4452-8907-8B5B17544E68}"
EndProject
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "azuretest", "..\test\azuretest.pyproj", "{C0742A2D-4862-40E4-8A28-036EECDBC614}"
EndProject
Global
GlobalSection(TeamFoundationVersionControl) = preSolution
SccNumberOfProjects = 3
SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccTeamFoundationServer = http://tcvstf:8080/tfs/tc
SccLocalPath0 = .
SccProjectUniqueName1 = azure.pyproj
SccLocalPath1 = .
SccProjectUniqueName2 = ..\\test\\azuretest.pyproj
SccProjectName2 = ../test
SccLocalPath2 = ..\\test
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Expand Down
16 changes: 10 additions & 6 deletions src/azure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#--------------------------------------------------------------------------
import ast
import base64
import sys
import types
import urllib2

from datetime import datetime
from xml.dom import minidom
import base64
import urllib2
import ast
from xml.sax.saxutils import escape as xml_escape

#--------------------------------------------------------------------------
# constants

__author__ = 'Microsoft Corp. <ptvshelp@microsoft.com>'
__version__ = '0.7.0'

#Live ServiceClient URLs
BLOB_SERVICE_HOST_BASE = '.blob.core.windows.net'
QUEUE_SERVICE_HOST_BASE = '.queue.core.windows.net'
Expand Down Expand Up @@ -60,7 +64,7 @@
_ERROR_VALUE_SHOULD_NOT_BE_NULL = '%s should not be None.'
_ERROR_CANNOT_SERIALIZE_VALUE_TO_ENTITY = 'Cannot serialize the specified value (%s) to an entity. Please use an EntityProperty (which can specify custom types), int, str, bool, or datetime'

_USER_AGENT_STRING = 'pyazure'
_USER_AGENT_STRING = 'pyazure/' + __version__

METADATA_NS = 'http://schemas.microsoft.com/ado/2007/08/dataservices/metadata'

Expand Down Expand Up @@ -661,7 +665,7 @@ def _parse_response_for_dict(response):

return return_dict

def _parse_response_for_dict_prefix(response, prefix):
def _parse_response_for_dict_prefix(response, prefixes):
''' Extracts name-values for names starting with prefix from response header. Filter out the standard http headers.'''

if response is None:
Expand All @@ -670,7 +674,7 @@ def _parse_response_for_dict_prefix(response, prefix):
orig_dict = _parse_response_for_dict(response)
if orig_dict:
for name, value in orig_dict.iteritems():
for prefix_value in prefix:
for prefix_value in prefixes:
if name.lower().startswith(prefix_value.lower()):
return_dict[name] = value
break
Expand Down
31 changes: 27 additions & 4 deletions src/azure/http/httpclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ def __init__(self, service_instance, cert_file=None, account_name=None, account_
self.protocol = protocol
self.proxy_host = None
self.proxy_port = None
if protocol == 'http':
self.port = httplib.HTTP_PORT
else:
self.port = httplib.HTTPS_PORT

def set_proxy(self, host, port):
'''Sets the proxy server host and port for the HTTP CONNECT Tunnelling.'''
Expand All @@ -69,17 +73,36 @@ def get_connection(self, request):
if sys.platform.lower().startswith('win'):
import azure.http.winhttp
_connection = azure.http.winhttp._HTTPConnection(request.host, cert_file=self.cert_file, protocol=self.protocol)
elif self.protocol == 'http':
_connection = httplib.HTTPConnection(request.host)
proxy_host = self.proxy_host
proxy_port = self.proxy_port
else:
_connection = httplib.HTTPSConnection(request.host, cert_file=self.cert_file)
if self.proxy_host:
proxy_host = request.host
proxy_port = self.port
host = self.proxy_host
port = self.proxy_port
else:
host = request.host
port = self.port

if self.protocol == 'http':
_connection = httplib.HTTPConnection(host, int(port))
else:
_connection = httplib.HTTPSConnection(host, int(port), cert_file=self.cert_file)

if self.proxy_host:
_connection.set_tunnel(self.proxy_host, self.proxy_port)
_connection.set_tunnel(proxy_host, int(proxy_port))

return _connection

def send_request_headers(self, connection, request_headers):
if not sys.platform.lower().startswith('win'):
if self.proxy_host:
for i in connection._buffer:
if i.startswith("Host: "):
connection._buffer.remove(i)
connection.putheader('Host', "%s:%s" % (connection._tunnel_host, connection._tunnel_port))

for name, value in request_headers:
if value:
connection.putheader(name, value)
Expand Down
47 changes: 27 additions & 20 deletions src/azure/servicebus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,30 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#--------------------------------------------------------------------------
import ast
import httplib
import sys
import time
import urllib2
from xml.dom import minidom
import ast
import httplib
from datetime import datetime


from datetime import datetime
from xml.dom import minidom
from azure import (WindowsAzureData,
WindowsAzureError,
xml_escape,
_create_entry,
_general_error_handler,
_get_entry_properties,
_get_child_nodes,
_get_children_from_path,
_get_first_child_node_value,
_ERROR_MESSAGE_NOT_PEEK_LOCKED_ON_DELETE,
_ERROR_MESSAGE_NOT_PEEK_LOCKED_ON_UNLOCK,
_ERROR_QUEUE_NOT_FOUND,
_ERROR_TOPIC_NOT_FOUND,
_USER_AGENT_STRING,
)
from azure.http import HTTPError
from azure import (WindowsAzureError, WindowsAzureData, _general_error_handler,
_create_entry, _get_entry_properties, xml_escape,
_get_child_nodes, WindowsAzureMissingResourceError,
WindowsAzureConflictError, _get_serialization_name,
_get_children_from_path, _get_first_child_node_value,
_USER_AGENT_STRING)
import azure

#default rule name for subscription
DEFAULT_RULE_NAME='$Default'
Expand Down Expand Up @@ -173,7 +180,7 @@ def delete(self):
elif self._topic_name and self._subscription_name:
self.service_bus_service.delete_subscription_message(self._topic_name, self._subscription_name, self.broker_properties['SequenceNumber'], self.broker_properties['LockToken'])
else:
raise WindowsAzureError(azure._ERROR_MESSAGE_NOT_PEEK_LOCKED_ON_DELETE)
raise WindowsAzureError(_ERROR_MESSAGE_NOT_PEEK_LOCKED_ON_DELETE)

def unlock(self):
''' Unlocks itself if find queue name or topic name and subscription name. '''
Expand All @@ -182,7 +189,7 @@ def unlock(self):
elif self._topic_name and self._subscription_name:
self.service_bus_service.unlock_subscription_message(self._topic_name, self._subscription_name, self.broker_properties['SequenceNumber'], self.broker_properties['LockToken'])
else:
raise WindowsAzureError(azure._ERROR_MESSAGE_NOT_PEEK_LOCKED_ON_UNLOCK)
raise WindowsAzureError(_ERROR_MESSAGE_NOT_PEEK_LOCKED_ON_UNLOCK)

def add_headers(self, request):
''' add addtional headers to request for message request.'''
Expand Down Expand Up @@ -452,7 +459,7 @@ def _convert_xml_to_queue(xmlstr):
invalid_queue = False

if invalid_queue:
raise WindowsAzureError(azure._ERROR_QUEUE_NOT_FOUND)
raise WindowsAzureError(_ERROR_QUEUE_NOT_FOUND)

#extract id, updated and name value from feed entry and set them of queue.
for name, value in _get_entry_properties(xmlstr, True).iteritems():
Expand Down Expand Up @@ -513,7 +520,7 @@ def _convert_xml_to_topic(xmlstr):
invalid_topic = False

if invalid_topic:
raise WindowsAzureError(azure._ERROR_TOPIC_NOT_FOUND)
raise WindowsAzureError(_ERROR_TOPIC_NOT_FOUND)

#extract id, updated and name value from feed entry and set them of topic.
for name, value in _get_entry_properties(xmlstr, True).iteritems():
Expand Down Expand Up @@ -572,7 +579,7 @@ def _convert_xml_to_subscription(xmlstr):

return subscription

def convert_subscription_to_xml(subscription):
def _convert_subscription_to_xml(subscription):
'''
Converts a subscription object to xml to send. The order of each field of subscription
in xml is very important so we cann't simple call convert_class_to_xml.
Expand Down Expand Up @@ -602,7 +609,7 @@ def convert_subscription_to_xml(subscription):
subscription_body += '</SubscriptionDescription>'
return _create_entry(subscription_body)

def convert_rule_to_xml(rule):
def _convert_rule_to_xml(rule):
'''
Converts a rule object to xml to send. The order of each field of rule
in xml is very important so we cann't simple call convert_class_to_xml.
Expand All @@ -629,7 +636,7 @@ def convert_rule_to_xml(rule):

return _create_entry(rule_body)

def convert_topic_to_xml(topic):
def _convert_topic_to_xml(topic):
'''
Converts a topic object to xml to send. The order of each field of topic
in xml is very important so we cann't simple call convert_class_to_xml.
Expand All @@ -655,7 +662,7 @@ def convert_topic_to_xml(topic):

return _create_entry(topic_body)

def convert_queue_to_xml(queue):
def _convert_queue_to_xml(queue):
'''
Converts a queue object to xml to send. The order of each field of queue
in xml is very important so we cann't simple call convert_class_to_xml.
Expand Down
Loading