An example of a protobuf based web service.
Last active
December 23, 2015 18:19
-
-
Save ericmoritz/6675109 to your computer and use it in GitHub Desktop.
A simple protobuf based web service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*.pyc | |
*~ | |
.env/ | |
static/ | |
data/ | |
*_pb2.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Right(v) { | |
return { | |
'bind': function(f) { return f(v); }, | |
'is_right': true, | |
'is_left': false, | |
'either': function(_, rf) { return rf(v) }, | |
} | |
} | |
function Left(v) { | |
return { | |
'bind': function(f) { return Left(v); }, | |
'is_right': false, | |
'is_left': true, | |
'either': function(lf, _) { return lf(v) }, | |
} | |
} | |
function catchEither(f) { | |
try { | |
return Right(f()); | |
} catch(err) { | |
return Left(err); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from things_pb2 import Person, Animal | |
people = { | |
"em": {"name": "Eric", "age": 33}, | |
"jh": {"name": "Jonathan"}, | |
"sl": {"name": "Steven"}, | |
"fc": {"name": "Frankln Clinton"}, | |
} | |
animals = { | |
"dog": {"type": "dog"}, | |
"chop": {"type": "dog", "name": "Chop", "owner_key": 'fc'}, | |
} | |
def _person_msg(p, key, data): | |
p.key = key | |
for key, value in data.items(): | |
setattr(p, key, value) | |
return p | |
def _animal_msg(a, key, data): | |
a = Animal() | |
a.key = key | |
for key, value in data.items(): | |
setattr(a, key, value) | |
# denormalize the owner | |
if key == 'owner_key': | |
_person_msg(a.owner, value, people[value]) | |
return a | |
def write_msg(bucket, key, msg): | |
with open('data/{bucket}/{key}'.format(**locals()), 'wb') as fh: | |
fh.write(msg.SerializeToString()) | |
for key, value in people.items(): | |
write_msg( | |
"people", | |
key, | |
_person_msg(Person(), key, value)) | |
for key, value in animals.items(): | |
write_msg( | |
"animals", | |
key, | |
_animal_msg(Animal(), key, value)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<script src="/static/Long.min.js"></script> | |
<script src="/static/ByteBuffer.min.js"></script> | |
<script src="/static/ProtoBuf.min.js"></script> | |
<script src="/static/jquery.min.js"></script> | |
<script src="either.js"></script> | |
<script src="main.js"></script> | |
</head> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var ProtoBuf = dcodeIO.ProtoBuf; | |
var builder = ProtoBuf.protoFromFile("things.proto") | |
var Person = builder.build("things.Person"); | |
var Animal = builder.build("things.Animal"); | |
function display(obj) { | |
document.write(JSON.stringify(obj) + "<br/>"); | |
} | |
function logError(err) { | |
console.error(err.toString()); | |
} | |
function handlePerson(bin) { | |
catchEither( | |
function() { return Person.decode(bin) } | |
) | |
.either(logError, display); | |
} | |
function handleAnimal(bin) { | |
catchEither( | |
function() { return Animal.decode(bin) } | |
) | |
.either(logError, display); | |
} | |
function main() { | |
jQuery.get("data/people/em", handlePerson); | |
jQuery.get("data/people/fc", handlePerson); | |
jQuery.get("data/people/jh", handlePerson); | |
jQuery.get("data/people/sl", handlePerson); | |
jQuery.get("data/animals/chop", handlePerson); // oops not a person | |
jQuery.get("data/animals/chop", handleAnimal); | |
} | |
jQuery(document).ready(main); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.PHONY: clean build | |
build: static data things_pb2.py | |
clean: | |
rm -f *~ *.pyc *_pb2.py | |
rm -rf data/ | |
rm -rf static/ | |
server: build | |
python -m SimpleHTTPServer | |
static: | |
mkdir -p static | |
curl -o static/Long.min.js https://raw.github.com/dcodeIO/Long.js/master/Long.min.js | |
curl -o static/ByteBuffer.min.js https://raw.github.com/dcodeIO/ByteBuffer.js/master/ByteBuffer.min.js | |
curl -o static/ProtoBuf.min.js https://raw.github.com/dcodeIO/ProtoBuf.js/master/ProtoBuf.min.js | |
curl -o static/jquery.min.js http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js | |
data: things_pb2.py | |
mkdir -p data/people | |
mkdir -p data/animals | |
python generate_data.py | |
things_pb2.py: | |
protoc --python_out=. things.proto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package things; | |
message Person { | |
required string key = 1; | |
required string name = 2; | |
optional uint32 age = 3; | |
} | |
message Animal { | |
required string key = 1; | |
required string type = 2; | |
optional string name = 3; | |
optional string owner_key = 4; | |
optional Person owner = 5; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment