Skip to content

Commit

Permalink
rpclib.model.binary.Attachment is deprecated in favor of rpclib.model…
Browse files Browse the repository at this point in the history
….binary.ByteArray
  • Loading branch information
plq committed Sep 14, 2011
1 parent 80d3274 commit 8297c76
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 217 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.rst
@@ -1,6 +1,13 @@
Changelog
=========

rpclib-2.3.3-beta
-----------------
* Added MAX_CONTENT_LENGTH = 2 * 1024 * 1024 and BLOCK_LENGTH = 8 * 1024
constants to rpclib.server.wsgi module.
* rpclib.model.binary.Attachment is deprecated, and is replaced by ByteArray.
The native format of ByteArray is an iterable of strings.

rpclib-2.3.2-beta
-----------------
* Limited support for sqlalchemy.orm.relationship (no string arguments)
Expand Down
77 changes: 0 additions & 77 deletions doc/source/pages/binaryfiles.rst

This file was deleted.

30 changes: 19 additions & 11 deletions examples/binary_http.py
Expand Up @@ -24,30 +24,37 @@
from tempfile import mkstemp

from rpclib.application import Application
from rpclib.decorator import rpc
from rpclib.decorator import srpc
from rpclib.interface.wsdl import Wsdl11
from rpclib.model.binary import Attachment
from rpclib.model.binary import ByteArray
from rpclib.model.fault import Fault
from rpclib.model.primitive import String
from rpclib.protocol.http import HttpRpc
from rpclib.service import ServiceBase
from rpclib.server.wsgi import WsgiApplication

class DocumentArchiver(ServiceBase):
@srpc(Attachment, _returns=String)
def put(document):
'''This method accepts an Attachment object, and returns
the filename of the archived file
@rpc(ByteArray, _returns=String)
def put(ctx, content):
'''This method accepts an Attachment object, and returns the filename
of the archived file
'''
if content is None:
raise Fault("Client.BadRequest")

fd, fname = mkstemp()
os.close(fd)

document.file_name = fname
document.save_to_file()
f = open(fname, 'wb')

for chunk in content:
f.write(chunk)
f.close()

return fname

@srpc(String, _returns=Attachment)
@srpc(String, _returns=ByteArray)
def get(file_path):
'''This method loads a document from the specified file path
and returns it. If the path isn't found, an exception is
Expand All @@ -57,12 +64,14 @@ def get(file_path):
if not os.path.exists(file_path):
raise Fault("Client.FileName", "File '%s' not found" % file_path)

document = Attachment(file_name=file_path)
document = open(file_path, 'rb').read()


# the service automatically loads the data from the file.
# alternatively, The data could be manually loaded into memory
# and loaded into the Attachment like:
# document = Attachment(data=data_from_file)
return document
return [document]

if __name__=='__main__':
try:
Expand All @@ -74,7 +83,6 @@ def get(file_path):
interface=Wsdl11(), in_protocol=HttpRpc(), out_protocol=HttpRpc())

logging.basicConfig(level=logging.DEBUG)
logging.getLogger('rpclib.protocol.soap.soap11').setLevel(logging.DEBUG)

server = make_server('127.0.0.1', 7789, WsgiApplication(application))
print "listening to http://127.0.0.1:7789"
Expand Down
33 changes: 19 additions & 14 deletions examples/binary_soap.py
Expand Up @@ -24,30 +24,38 @@
from tempfile import mkstemp

from rpclib.application import Application
from rpclib.decorator import rpc
from rpclib.decorator import srpc
from rpclib.interface.wsdl import Wsdl11
from rpclib.model.binary import Attachment
from rpclib.model.binary import ByteArray
from rpclib.model.fault import Fault
from rpclib.model.primitive import String
from rpclib.protocol.soap import Soap11
from rpclib.service import ServiceBase
from rpclib.server.wsgi import WsgiApplication

class DocumentArchiver(ServiceBase):
@srpc(Attachment, _returns=String)
def put(document):
'''This method accepts an Attachment object, and returns
the filename of the archived file
@rpc(ByteArray, _returns=String)
def put(ctx, content):
'''This method accepts an ByteArray object, and returns the filename
of the archived file
'''

if content is None:
raise Fault("Client.BadRequest")

fd, fname = mkstemp()
os.close(fd)

document.file_name = fname
document.save_to_file()
f = open(fname, 'wb')

for chunk in content:
f.write(chunk)
f.close()

return fname

@srpc(String, _returns=Attachment)
@srpc(String, _returns=ByteArray)
def get(file_path):
'''This method loads a document from the specified file path
and returns it. If the path isn't found, an exception is
Expand All @@ -57,12 +65,9 @@ def get(file_path):
if not os.path.exists(file_path):
raise Fault("Client.FileName", "File '%s' not found" % file_path)

document = Attachment(file_name=file_path)
# the service automatically loads the data from the file.
# alternatively, The data could be manually loaded into memory
# and loaded into the Attachment like:
# document = Attachment(data=data_from_file)
return document
document = open(file_path, 'rb').read()

return [document]

if __name__=='__main__':
try:
Expand Down
61 changes: 0 additions & 61 deletions examples/helloworld_attach.py

This file was deleted.

1 change: 1 addition & 0 deletions src/rpclib/model/__init__.py
Expand Up @@ -26,3 +26,4 @@

from _base import nillable_dict
from _base import nillable_string
from _base import nillable_iterable
22 changes: 20 additions & 2 deletions src/rpclib/model/_base.py
Expand Up @@ -43,6 +43,16 @@ def wrapper(cls, string):
return func(cls, string)
return wrapper

def nillable_iterable(func):
"""Decorator that retuns [] if input is None."""

def wrapper(cls, string):
if string is None:
return []
else:
return func(cls, string)
return wrapper

class ModelBase(object):
"""The base class for type markers. It defines the model interface for the
interface generators to use and also manages class customizations that are
Expand Down Expand Up @@ -129,11 +139,19 @@ def get_type_name_ns(cls, app):
@classmethod
@nillable_string
def to_string(cls, value):
"""Returns str(value). This should be overridden if this is not
enough."""
"""Returns str(value). This should be overridden if this is not enough.
"""

return str(value)

@classmethod
@nillable_iterable
def to_string_iterable(cls, value):
"""Returns the result of :func:`to_string` in a list. This method should
be overridden if this is not enough."""

return [cls.to_string(value)]

@classmethod
@nillable_string
def to_dict(cls, value):
Expand Down
53 changes: 53 additions & 0 deletions src/rpclib/model/binary.py
Expand Up @@ -21,9 +21,62 @@

from cStringIO import StringIO
from rpclib.model import nillable_string
from rpclib.model import nillable_iterable
from rpclib.model import ModelBase

class ByteArray(ModelBase):
"""Handles anything other than ascii or unicode-encoded data. Every protocol
has a different way to handle arbitrary data. E.g. xml-based protocols
encode this as base64, while HttpRpc just hands it over.
Its native python format is an iterable of strings.
"""

__type_name__ = 'base64Binary'
__namespace__ = "http://www.w3.org/2001/XMLSchema"

@classmethod
@nillable_string
def from_string(cls, value):
return [value]

@classmethod
@nillable_string
def to_string(cls, value):
return ''.join(value)

@classmethod
@nillable_iterable
def to_string_iterable(cls, value):
"""Returns the result of :func:`to_string` in a list. This method should
be overridden if this is not enough."""

return [cls.to_string(value)]

@classmethod
@nillable_string
def to_base64(cls, value):
ostream = StringIO()
istream = StringIO(''.join(value))
base64.encode(istream, ostream)
ostream.seek(0)

return [ostream.read()]

@classmethod
@nillable_string
def from_base64(cls, value):
istream = StringIO(''.join(value))
ostream = StringIO()

base64.decode(istream, ostream)
ostream.seek(0)

return [ostream.read()]

class Attachment(ModelBase):
"""DEPRECATED! Use ByteArray instead."""

__type_name__ = 'base64Binary'
__namespace__ = "http://www.w3.org/2001/XMLSchema"

Expand Down

0 comments on commit 8297c76

Please sign in to comment.