def test_file_value(self): dbe = _DictDocumentChild.default_binary_encoding beh = binary_encoding_handlers[dbe] # Prepare data v = File.Value( name='some_file.bin', type='application/octet-stream', ) file_data = ''.join([chr(x) for x in range(0xff)]) v.data = beh(file_data) class SomeService(ServiceBase): @srpc(File, _returns=File) def some_call(p): print(p) print(type(p)) assert isinstance(p, File.Value) assert p.data == [file_data] assert p.type == v.type assert p.name == v.name return p d = get_object_as_dict(v, File, ignore_wrappers=False) assert d[File.get_type_name()]['name'] == v.name assert d[File.get_type_name()]['type'] == v.type assert d[File.get_type_name()]['data'] == v.data ctx = _dry_me([SomeService], {"some_call": {'p': d}}) s = ''.join(ctx.out_string) d = serializer.dumps( { "some_callResponse": { "some_callResult": { 'name': v.name, 'type': v.type, 'data': v.data, } } }, **dumps_kwargs) print(serializer.loads(s)) print(serializer.loads(d)) print(v) assert serializer.loads(s) == serializer.loads(d)
def download_file(ctx, project_name, version, file_name): repository_path = os.path.abspath(os.path.join(FILES_PATH)) file_path = os.path.join(repository_path, project_name, version, file_name) file_path = os.path.abspath(file_path) if not file_path.startswith(repository_path): # This request tried to read data from where it's not supposed to raise RequestNotAllowed(repr([project_name, version, file_name])) return File.Value(name=file_name, path=file_path)
class FileServices(ServiceBase): @rpc(Mandatory.Unicode, _returns=ByteArray) def get(ctx, file_name): path = os.path.join(os.path.abspath('./files'), file_name) if not path.startswith(os.path.abspath('./files')): raise ValidationError(file_name) try: f = open(path, 'r') except IOError: raise ResourceNotFoundError(file_name) ctx.transport.resp_headers['Content-Disposition'] = ( 'attachment; filename=%s;' % file_name) data = f.read(BLOCK_SIZE) while len(data) > 0: yield data data = f.read(BLOCK_SIZE) f.close() @rpc(Unicode, Unicode, File.customize(min_occurs=1, nullable=False), _returns=Unicode) def add(ctx, person_type, action, file): logger.info("Person Type: %r" % person_type) logger.info("Action: %r" % action) path = os.path.join(os.path.abspath('./files'), file.name) if not path.startswith(os.path.abspath('./files')): raise ValidationError(file.name) f = open(path, 'w') # if this fails, the client will see an # internal error. try: for data in file.data: f.write(data) logger.debug("File written: %r" % file.name) f.close() except: f.close() os.remove(file.name) logger.debug("File removed: %r" % file.name) raise # again, the client will see an internal error. return "Tamam."
def test_file_value(self): dbe = _DictDocumentChild.default_binary_encoding beh = binary_encoding_handlers[dbe] # Prepare data v = File.Value( name='some_file.bin', type='application/octet-stream', ) file_data = ''.join([chr(x) for x in range(0xff)]) v.data = beh(file_data) class SomeService(ServiceBase): @srpc(File, _returns=File) def some_call(p): print(p) print(type(p)) assert isinstance(p, File.Value) assert p.data == [file_data] assert p.type == v.type assert p.name == v.name return p d = get_object_as_dict(v, File, ignore_wrappers=False) assert d[File.get_type_name()]['name'] == v.name assert d[File.get_type_name()]['type'] == v.type assert d[File.get_type_name()]['data'] == v.data ctx = _dry_me([SomeService], {"some_call": {'p': d}}) s = ''.join(ctx.out_string) d = serializer.dumps({"some_callResponse": {"some_callResult": { 'name': v.name, 'type': v.type, 'data': v.data, }}}, **dumps_kwargs) print(serializer.loads(s)) print(serializer.loads(d)) print(v) assert serializer.loads(s) == serializer.loads(d)
def test_file_value(self): dbe = _DictDocumentChild.default_binary_encoding beh = binary_encoding_handlers[dbe] # Prepare data v = File.Value( name='some_file.bin', type='application/octet-stream', ) file_data = bytes(bytearray(range(0xff))) v.data = (file_data, ) beh([file_data]) if _DictDocumentChild.text_based: test_data = beh(v.data).decode('latin1') else: test_data = beh(v.data) print(repr(v.data)) class SomeService(Service): @srpc(File, _returns=File) def some_call(p): print(p) print(type(p)) assert isinstance(p, File.Value) assert p.data == (file_data, ) assert p.type == v.type assert p.name == v.name return p d = get_object_as_dict(v, File, protocol=_DictDocumentChild, ignore_wrappers=False) ctx = _dry_me([SomeService], {"some_call": {'p': d}}) s = b''.join(ctx.out_string) d = self.dumps({ "some_callResponse": { "some_callResult": { 'name': v.name, 'type': v.type, 'data': test_data, } } }) print(self.loads(s)) print(self.loads(d)) print(v) assert self.loads(s) == self.loads(d)
def decompose_incoming_envelope(self, prot, ctx, message): """This function is only called by the HttpRpc protocol to have the wsgi environment parsed into ``ctx.in_body_doc`` and ``ctx.in_header_doc``. """ params = {} wsgi_env = ctx.in_document if self.has_patterns: # http://legacy.python.org/dev/peps/pep-0333/#url-reconstruction domain = wsgi_env.get('HTTP_HOST', None) if domain is None: domain = wsgi_env['SERVER_NAME'] else: domain = domain.partition(':')[0] # strip port info params = self.match_pattern( ctx, wsgi_env.get('REQUEST_METHOD', ''), wsgi_env.get('PATH_INFO', ''), domain, ) if ctx.method_request_string is None: ctx.method_request_string = '{%s}%s' % (prot.app.interface.get_tns( ), wsgi_env['PATH_INFO'].split('/')[-1]) logger.debug("%sMethod name: %r%s" % (LIGHT_GREEN, ctx.method_request_string, END_COLOR)) ctx.in_header_doc = _get_http_headers(wsgi_env) ctx.in_body_doc = _parse_qs(wsgi_env['QUERY_STRING']) for k, v in params.items(): if k in ctx.in_body_doc: ctx.in_body_doc[k].extend(v) else: ctx.in_body_doc[k] = list(v) verb = wsgi_env['REQUEST_METHOD'].upper() if verb in ('POST', 'PUT', 'PATCH'): stream, form, files = parse_form_data( wsgi_env, stream_factory=prot.stream_factory) for k, v in form.lists(): val = ctx.in_body_doc.get(k, []) val.extend(v) ctx.in_body_doc[k] = val for k, v in files.items(): val = ctx.in_body_doc.get(k, []) mime_type = v.headers.get('Content-Type', 'application/octet-stream') path = getattr(v.stream, 'name', None) if path is None: val.append( File.Value(name=v.filename, type=mime_type, data=[v.stream.getvalue()])) else: v.stream.seek(0) val.append( File.Value(name=v.filename, type=mime_type, path=path, handle=v.stream)) ctx.in_body_doc[k] = val for k, v in ctx.in_body_doc.items(): if v == ['']: ctx.in_body_doc[k] = [None]
def file_from_string(cls, value, suggested_encoding=None): encoding = cls.Attributes.encoding if encoding is None: encoding = suggested_encoding return File.Value(data=binary_decoding_handlers[encoding](value))
def file_from_string(cls, value, suggested_encoding=None): encoding = cls.Attributes.encoding if encoding is BINARY_ENCODING_USE_DEFAULT: encoding = suggested_encoding return File.Value(data=binary_decoding_handlers[encoding](value))
def decompose_incoming_envelope(self, prot, ctx, message): """This function is only called by the HttpRpc protocol to have the wsgi environment parsed into ``ctx.in_body_doc`` and ``ctx.in_header_doc``. """ if self.has_patterns: from werkzeug.exceptions import NotFound if self._map_adapter is None: self.generate_map_adapter(ctx) try: #If PATH_INFO matches a url, Set method_request_string to mrs mrs, params = self._map_adapter.match( ctx.in_document["PATH_INFO"], ctx.in_document["REQUEST_METHOD"]) ctx.method_request_string = mrs except NotFound: # Else set method_request_string normally params = {} ctx.method_request_string = '{%s}%s' % ( prot.app.interface.get_tns(), ctx.in_document['PATH_INFO'].split('/')[-1]) else: params = {} ctx.method_request_string = '{%s}%s' % (prot.app.interface.get_tns( ), ctx.in_document['PATH_INFO'].split('/')[-1]) logger.debug("%sMethod name: %r%s" % (LIGHT_GREEN, ctx.method_request_string, END_COLOR)) ctx.in_header_doc = _get_http_headers(ctx.in_document) ctx.in_body_doc = parse_qs(ctx.in_document['QUERY_STRING']) for k, v in params.items(): if k in ctx.in_body_doc: ctx.in_body_doc[k].append(v) else: ctx.in_body_doc[k] = [v] if ctx.in_document['REQUEST_METHOD'].upper() in ('POST', 'PUT', 'PATCH'): stream, form, files = parse_form_data( ctx.in_document, stream_factory=prot.stream_factory) for k, v in form.lists(): val = ctx.in_body_doc.get(k, []) val.extend(v) ctx.in_body_doc[k] = val for k, v in files.items(): val = ctx.in_body_doc.get(k, []) mime_type = v.headers.get('Content-Type', 'application/octet-stream') path = getattr(v.stream, 'name', None) if path is None: val.append( File.Value(name=v.filename, type=mime_type, data=[v.stream.getvalue()])) else: v.stream.seek(0) val.append( File.Value(name=v.filename, type=mime_type, path=path, handle=v.stream)) ctx.in_body_doc[k] = val
class PlaceManagerService(ServiceBase): @rpc(Mandatory.UnsignedInteger32, _returns=Place) def get_place(ctx, place_id): return ctx.udc.session.query(Place).filter_by(id=place_id).one() @rpc(Place, _returns=UnsignedInteger32) def put_place(ctx, place): if place.id is None: ctx.udc.session.add(place) ctx.udc.session.flush() # so that we get the place.id value else: if ctx.udc.session.query(Place).get(place.id) is None: # this is to prevent the client from setting the primary key # of a new object instead of the database's own primary-key # generator. # Instead of raising an exception, you can also choose to # ignore the primary key set by the client by silently doing # place.id = None raise ResourceNotFoundError('place.id=%d' % place.id) else: ctx.udc.session.merge(place) return place.id @rpc(Mandatory.UnsignedInteger32) def del_place(ctx, place_id): count = ctx.udc.session.query(Place).filter_by(id=place_id).count() if count == 0: raise ResourceNotFoundError(place_id) ctx.udc.session.query(Place).filter_by(id=place_id).delete() @rpc(_returns=Iterable(Place)) def get_all_places(ctx): return ctx.udc.session.query(Place) @rpc(Mandatory.UnsignedInteger32, UnsignedInteger32, UnsignedInteger32, _returns=Iterable(Place)) def get_places_by_category_id(ctx, category_id, from_id=0, elements=None): places = ctx.udc.session.query(Place).filter_by( category_id=category_id) if from_id is not None: places = [place for place in places if place.id >= from_id] for place in places: place.rating = -1.0 if place.rating == 0.0 else place.rating return _partition_places(places, elements) @rpc(Mandatory.UnsignedInteger32, Decimal, Decimal, Decimal, UnsignedInteger32, UnsignedInteger32, _returns=Iterable(Place)) def get_near_places_by_category_id(ctx, category_id, lat, lng, radius, from_id=0, elements=None): places = ctx.udc.session.query(Place).filter_by( category_id=category_id) places = places.order_by(asc(Place.id)) if from_id is not None: places = [place for place in places if place.id >= from_id] # Filter just near places places = [ place for place in places if _are_points_closed(place.lat, place.lng, lat, lng, radius) ] # Just places id greater than from_id return _partition_places(places, elements) @rpc(Mandatory.Unicode, Mandatory.UnsignedInteger32, _returns=Boolean) def gplaces_id_exists_in_category(ctx, gplaces_id, category_id): return ctx.udc.session.query(Place).filter_by( category_id=category_id, gplaces_id=gplaces_id).count() > 0 @rpc(Unicode, File(min_occurs=1, nullable=False), _returns=Unicode) def upload_image(ctx, image_name, image_file): image_name = image_name.replace( ' ', '_') + '_' + datetime.datetime.now().strftime( "%d-%m-%y_%H.%m") + '.jpg' path = os.path.join(os.path.abspath('/srv/images'), image_name) if not path.startswith(os.path.abspath('/srv/images')): raise ValidationError(image_file) f = open(path, 'wb') try: for data in image_file.data: f.write(base64.b64decode(data)) logger.debug("File written: %r" % image_name) f.close() except: f.close() os.remove(image_name) logger.debug("File removed: %r" % image_name) raise # again, the client will see an internal error. # Watch out the port! url = 'http://' + socket.gethostbyname( socket.gethostname()) + ':8080/images/' + image_name return url
class AppDocument(SmevModel): RequestCode = Unicode(type_name="RequestCode") BinaryData = File(type_name="BinaryData", encoding=BINARY_ENCODING_BASE64)