New type: FileType. Supports file inputs in forms + documents and demonstrate it in the demo. Should solve issue #4.

This commit is contained in:
Christophe de Vienne 2012-08-23 23:22:44 +02:00
parent 53669cb935
commit 3f3b0a08df
7 changed files with 62 additions and 23 deletions

View File

@ -8,6 +8,8 @@ Changes
* String types handling is clearer. * String types handling is clearer.
* New FileType type.
* Supports cross-referenced types. * Supports cross-referenced types.
* Various bugfixes. * Various bugfixes.

View File

@ -50,6 +50,11 @@ The native types are :
A time (:py:class:`datetime.time`) A time (:py:class:`datetime.time`)
- .. wsme:type:: Filetype
A file (:py:class:`wsme.types.Filetype`). Currently FileType is
supported only as input type on protocols that accept form inputs.
- Arrays -- This is a special case. When stating a list - Arrays -- This is a special case. When stating a list
datatype, always state its content type as the unique element datatype, always state its content type as the unique element
of a list. Example:: of a list. Example::

View File

@ -1,7 +0,0 @@
[app:main]
paste.app_factory = demo:app_factory
[server:main]
use = egg:PasteScript#wsgiutils
host = 127.0.0.1
port = 8989

View File

@ -8,11 +8,13 @@ To run it::
Then:: Then::
paster serve demo.cfg python demo.py
""" """
from wsme import WSRoot, expose, validate from wsme import WSRoot, expose, validate
from wsme.wsgi import adapt from wsme.types import FileType
import bottle
from six import u from six import u
@ -31,6 +33,11 @@ class DemoRoot(WSRoot):
def multiply(self, a, b): def multiply(self, a, b):
return a * b return a * b
@expose(unicode)
@validate(FileType)
def echofile(self, afile):
return unicode(afile.value)
@expose(unicode) @expose(unicode)
def helloworld(self): def helloworld(self):
return u"こんにちは世界 (<- Hello World in Japanese !)" return u"こんにちは世界 (<- Hello World in Japanese !)"
@ -68,17 +75,17 @@ class DemoRoot(WSRoot):
return persons return persons
def app_factory(global_config, **local_conf): root = DemoRoot(webpath='/ws')
root = DemoRoot()
root.addprotocol('soap', root.addprotocol('soap',
tns='http://example.com/demo', tns='http://example.com/demo',
typenamespace='http://example.com/demo/types', typenamespace='http://example.com/demo/types',
baseURL='http://127.0.0.1:8989/', baseURL='http://127.0.0.1:8989/ws/',
) )
root.addprotocol('restjson') root.addprotocol('restjson')
return adapt(root) bottle.mount('/ws/', root.wsgiapp())
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
bottle.run()

View File

@ -4,9 +4,7 @@ setup(name='demo',
install_requires=[ install_requires=[
'WSME', 'WSME',
'WSME-Soap', 'WSME-Soap',
'PasteScript', 'Bottle',
'PasteDeploy',
'WSGIUtils',
'Pygments', 'Pygments',
], ],
package=['demo']) package=['demo'])

View File

@ -1,10 +1,11 @@
import cgi
import datetime import datetime
import re import re
from simplegeneric import generic from simplegeneric import generic
from wsme.types import iscomplex, list_attributes, Unset from wsme.types import iscomplex, list_attributes, Unset
from wsme.types import UserType, ArrayType, DictType from wsme.types import UserType, ArrayType, DictType, FileType
from wsme.utils import parse_isodate, parse_isotime, parse_isodatetime from wsme.utils import parse_isodate, parse_isotime, parse_isodatetime
@ -31,6 +32,13 @@ def datetime_from_param(datatype, value):
return parse_isodatetime(value) if value else None return parse_isodatetime(value) if value else None
@from_param.when_object(FileType)
def filetype_from_param(datatype, value):
if isinstance(value, cgi.FieldStorage):
return FileType(fieldstorage=value)
return FileType(content=value)
@from_param.when_type(UserType) @from_param.when_type(UserType)
def usertype_from_param(datatype, value): def usertype_from_param(datatype, value):
return datatype.frombasetype( return datatype.frombasetype(

View File

@ -140,6 +140,32 @@ class Enum(UserType):
return value return value
class FileType(object):
def __init__(self, filename=None, file=None, content=None,
contenttype=None, fieldstorage=None):
self.filename = filename
self._file = file
self._content = content
self.contenttype = contenttype
if fieldstorage is not None:
if fieldstorage.file:
self._file = fieldstorage.file
self.filename = fieldstorage.filename
self.contenttype = fieldstorage.type
else:
self._content = fieldstorage.value
@property
def file(self):
return self._file
@property
def value(self):
if self._content is None and self._file:
self._content = self._file.read()
return self._content
class UnsetType(object): class UnsetType(object):
if sys.version < '3': if sys.version < '3':
def __nonzero__(self): def __nonzero__(self):
@ -154,7 +180,7 @@ Unset = UnsetType()
pod_types = six.integer_types + ( pod_types = six.integer_types + (
bytes, text, float, bool) bytes, text, float, bool)
dt_types = (datetime.date, datetime.time, datetime.datetime) dt_types = (datetime.date, datetime.time, datetime.datetime)
extra_types = (binary, decimal.Decimal) extra_types = (binary, decimal.Decimal, FileType)
native_types = pod_types + dt_types + extra_types native_types = pod_types + dt_types + extra_types