Skip to content

Instantly share code, notes, and snippets.

@dmccombs
Created April 25, 2014 13:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmccombs/11289220 to your computer and use it in GitHub Desktop.
Save dmccombs/11289220 to your computer and use it in GitHub Desktop.
diff --git example/SmartlingApiExample.py example/SmartlingApiExample.py
index 0a9d570..743ee62 100644
--- example/SmartlingApiExample.py
+++ example/SmartlingApiExample.py
@@ -38,29 +38,29 @@ class SmartlingApiExample:
self.new_name = new_name
def printMarker(self, caption):
- print "--" + caption + "-" * 40
+ print("--" + caption + "-" * 40)
def test(self):
self.printMarker("file upload")
- print self.fapi.upload(self.uploadData)
+ print(self.fapi.upload(self.uploadData))
self.printMarker("files list")
- print self.fapi.list()
+ print(self.fapi.list())
self.printMarker("file status")
- print self.fapi.status(self.uploadData.name, self.locale)
+ print(self.fapi.status(self.uploadData.name, self.locale))
self.printMarker("file from server goes here")
- print self.fapi.get(self.uploadData.name, self.locale)
+ print(self.fapi.get(self.uploadData.name, self.locale))
self.printMarker("renaming file")
- print self.fapi.rename(self.uploadData.name, self.new_name)
+ print(self.fapi.rename(self.uploadData.name, self.new_name))
self.printMarker("delete from server goes here")
- print self.fapi.delete(self.new_name)
+ print(self.fapi.delete(self.new_name))
self.printMarker("doing list again to see if it's deleted")
- print self.fapi.list()
+ print(self.fapi.list())
FILE_NAME = "java.properties"
diff --git smartlingApiSdk/FileApiBase.py smartlingApiSdk/FileApiBase.py
index b327d61..0a00207 100644
--- smartlingApiSdk/FileApiBase.py
+++ smartlingApiSdk/FileApiBase.py
@@ -15,11 +15,11 @@
#FileApi class implementation
-import httplib
-import urllib
-import urllib2
-from MultipartPostHandler import MultipartPostHandler
-from Constants import Uri, Params, ReqMethod
+import http.client
+import urllib.request, urllib.parse, urllib.error
+import urllib.request, urllib.error, urllib.parse
+from .MultipartPostHandler import MultipartPostHandler
+from .Constants import Uri, Params, ReqMethod
class FileApiBase:
@@ -36,18 +36,18 @@ class FileApiBase:
def uploadMultipart(self, params):
self.addApiKeys(params)
- params[Params.FILE] = open(params[Params.FILE_PATH], 'rb')
+ params[Params.FILE] = open(params[Params.FILE_PATH], 'r')
del params[Params.FILE_PATH] # no need in extra field in POST
- opener = urllib2.build_opener(MultipartPostHandler)
- urllib2.install_opener(opener)
- req = urllib2.Request('https://' + self.host + Uri.UPLOAD, params)
- response = urllib2.urlopen(req).read().strip()
+ opener = urllib.request.build_opener(MultipartPostHandler)
+ urllib.request.install_opener(opener)
+ req = urllib.request.Request('https://' + self.host + Uri.UPLOAD, params)
+ response = urllib.request.urlopen(req).read().strip()
return response
def command(self, method, uri, params):
self.addApiKeys(params)
- params_encoded = urllib.urlencode(params)
- conn = httplib.HTTPSConnection(self.host)
+ params_encoded = urllib.parse.urlencode(params)
+ conn = http.client.HTTPSConnection(self.host)
conn.request(method, uri, params_encoded, self.headers)
response = conn.getresponse()
data = response.read()
diff --git smartlingApiSdk/MultipartPostHandler.py smartlingApiSdk/MultipartPostHandler.py
index feb1991..c374c96 100644
--- smartlingApiSdk/MultipartPostHandler.py
+++ smartlingApiSdk/MultipartPostHandler.py
@@ -13,11 +13,12 @@
* limitations under the License.
'''
-import mimetools
+import io
import mimetypes
+import os
import sys
-import urllib
-import urllib2
+import urllib.request, urllib.parse, urllib.error
+import urllib.request, urllib.error, urllib.parse
class Callable:
@@ -25,44 +26,82 @@ class Callable:
self.__call__ = anycallable
-class MultipartPostHandler(urllib2.BaseHandler):
- handler_order = urllib2.HTTPHandler.handler_order - 10 # needs to run first
+class MultipartPostHandler(urllib.request.BaseHandler):
+ handler_order = urllib.request.HTTPHandler.handler_order - 10 # needs to run first
# Controls how sequences are uncoded. If true, elements may be given multiple values by
# assigning a sequence.
doseq = 1
+ _counter = 0
+ _prefix = None
+
+ # Code from Python stdlib mimetools.choose_boundary
+ # This was removed from the python lib in python 3
+ def _get_next_counter(self):
+ self._counter += 1
+ return self._counter
+
+ def choose_boundary(self):
+ """
+ Return a string usable as a multipart boundary.
+
+ The string chosen is unique within a single program run, and
+ incorporates the user id (if available), process id (if available),
+ and current time. So it's very unlikely the returned string appears
+ in message text, but there's no guarantee.
+
+ The boundary contains dots so you have to quote it in the header.
+ """
+ import time
+ if self._prefix is None:
+ import socket
+ try:
+ hostid = socket.gethostbyname(socket.gethostname())
+ except socket.gaierror:
+ hostid = '127.0.0.1'
+ try:
+ uid = repr(os.getuid())
+ except AttributeError:
+ uid = '1'
+ try:
+ pid = repr(os.getpid())
+ except AttributeError:
+ pid = '1'
+ self._prefix = hostid + '.' + uid + '.' + pid
+ return "%s.%.3f.%d" % (self._prefix, time.time(),
+ self._get_next_counter())
def http_request(self, request):
- data = request.get_data()
+ data = request.data
if data is not None and type(data) != str:
v_files = []
v_vars = []
try:
- for(key, value) in data.items():
- if type(value) == file:
+ for(key, value) in list(data.items()):
+ if isinstance(value, io.IOBase):
v_files.append((key, value))
else:
v_vars.append((key, value))
except TypeError:
systype, value, traceback = sys.exc_info()
- raise TypeError("not a valid non-string sequence or mapping object"), traceback
+ raise TypeError("not a valid non-string sequence or mapping object")(traceback)
if len(v_files) == 0:
- data = urllib.urlencode(v_vars, self.doseq)
+ data = urllib.parse.urlencode(v_vars, self.doseq)
else:
boundary, data = self.multipart_encode(v_vars, v_files)
contenttype = 'multipart/form-data; boundary=%s' % boundary
if(request.has_header('Content-Type')
and request.get_header('Content-Type').find('multipart/form-data') != 0):
- print "Replacing %s with %s" % (request.get_header('content-type'), 'multipart/form-data')
+ print("Replacing %s with %s" % (request.get_header('content-type'), 'multipart/form-data'))
request.add_unredirected_header('Content-Type', contenttype)
- request.add_data(data)
+ request.data = data.encode('UTF-8')
return request
- def multipart_encode(vars, files, boundary=None, buffer=None):
+ def multipart_encode(self, vars, files, boundary=None, buffer=None):
if boundary is None:
- boundary = mimetools.choose_boundary()
+ boundary = self.choose_boundary()
if buffer is None:
buffer = ''
for(key, value) in vars:
@@ -79,6 +118,5 @@ class MultipartPostHandler(urllib2.BaseHandler):
buffer += '\r\n' + fd.read() + '\r\n'
buffer += '--%s--\r\n\r\n' % boundary
return boundary, buffer
- multipart_encode = Callable(multipart_encode)
https_request = http_request
diff --git smartlingApiSdk/SmartlingFileApi.py smartlingApiSdk/SmartlingFileApi.py
index 3a7686c..eadf593 100644
--- smartlingApiSdk/SmartlingFileApi.py
+++ smartlingApiSdk/SmartlingFileApi.py
@@ -15,7 +15,7 @@
#FileApi class implementation
-from FileApiBase import FileApiBase
+from .FileApiBase import FileApiBase
class SmartlingFileApi(FileApiBase):
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment