Skip to content

Instantly share code, notes, and snippets.

@jparise
Created May 25, 2012 16:25

Revisions

  1. jparise created this gist May 25, 2012.
    45 changes: 45 additions & 0 deletions gistfile1.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,45 @@
    class ProtocolBufferMixin(object):
    """Protocol Buffer support for RequestHandler objects."""

    MIMETYPE = 'application/x-protobuf'

    def read_protobuf(self, message_type, data):
    """Attempts to parse a protocol buffer message from the given data."""
    # Create the message object and attempt to parse the data into it.
    try:
    message = message_type()
    if self.request.headers.get('Content-Type') == self.MIMETYPE:
    message.ParseFromString(data)
    else:
    google.protobuf.text_format.Merge(data, message)
    except Exception, e:
    logging.error("Failed to parse %s (%d bytes)" %
    (message_type.__name__, len(data)), exc_info=True)
    self.set_status(400)
    return None

    # Also make sure the message is fully initialized (i.e. all required
    # fields have been filled out).
    if not message.IsInitialized():
    logging.error("Incomplete data for %s (%d bytes)" %
    (message_type.__name__, len(data)))
    self.set_status(400)
    return None

    # At this point, we have a fully-initialized message object.
    return message

    def write_protobuf(self, message):
    """Writes a protocol buffer message to the output buffer.
    If the client's Accept: header advertises support for the protocol
    buffer MIME type, we write the message in binary form. Otherwise, we
    use the protocol buffer text format.
    """
    if self.accepts(self.MIMETYPE):
    self.set_header('Content-Type', self.MIMETYPE)
    self.write(message.SerializeToString())
    else:
    self.set_header('Content-Type', 'text/plain')
    text = google.protobuf.text_format.MessageToString(message)
    self.write(text)