aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorrw <me@rwinslow.com>2014-12-16 00:32:11 -0800
committerrw <me@rwinslow.com>2015-05-12 15:40:29 -0700
commit48dfc69ee613a176f13b04c2310adb7a08fe6737 (patch)
tree9ec728d0b78951b40e42f1acb42f44520fe2bb3b /docs
parent4d213c2d06fa17bec1dc87d16d02b8d94bc4fc58 (diff)
downloadflatbuffers-48dfc69ee613a176f13b04c2310adb7a08fe6737.tar.gz
Port FlatBuffers to Python.
Implement code generation and self-contained runtime library for Python. The test suite verifies: - Correctness of generated Python code by comparing output to that of the other language ports. - The exact bytes in the Builder buffer during many scenarios. - Vtable deduplication correctness. - Edge cases for table construction, via a fuzzer derived from the Go implementation. - All code is simultaneously valid in Python 2.6, 2.7, and 3.4. The test suite includes benchmarks for: - Building 'gold' data. - Parsing 'gold' data. - Deduplicating vtables. All tests pass on this author's system for the following Python implementations: - CPython 2.6.7 - CPython 2.7.8 - CPython 3.4.2 - PyPy 2.5.0 (CPython 2.7.8 compatible)
Diffstat (limited to 'docs')
-rwxr-xr-xdocs/source/PythonUsage.md115
-rwxr-xr-xdocs/source/doxyfile1
2 files changed, 116 insertions, 0 deletions
diff --git a/docs/source/PythonUsage.md b/docs/source/PythonUsage.md
new file mode 100755
index 00000000..e20b464d
--- /dev/null
+++ b/docs/source/PythonUsage.md
@@ -0,0 +1,115 @@
+# Use in Python
+
+There's experimental support for reading FlatBuffers in Python. Generate
+code for Python with the `-p` option to `flatc`.
+
+See `py_test.py` for an example. You import the generated code, read a
+FlatBuffer binary file into a `bytearray`, which you pass to the
+`GetRootAsMonster` function:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
+ import MyGame.Example as example
+ import flatbuffers
+
+ buf = open('monster.dat', 'rb').read()
+ buf = bytearray(buf)
+ monster = example.GetRootAsMonster(buf, 0)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now you can access values like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
+ hp = monster.Hp()
+ pos = monster.Pos()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To access vectors you pass an extra index to the
+vector field accessor. Then a second method with the same name suffixed
+by `Length` let's you know the number of elements you can access:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
+ for i in xrange(monster.InventoryLength()):
+ monster.Inventory(i) # do something here
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also construct these buffers in Python using the functions found
+in the generated code, and the FlatBufferBuilder class:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
+ builder = flatbuffers.NewBuilder(0)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Create strings:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
+ s = builder.CreateString("MyMonster")
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Create a table with a struct contained therein:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
+ example.MonsterStart(builder)
+ example.MonsterAddPos(builder, example.CreateVec3(builder, 1.0, 2.0, 3.0, 3.0, 4, 5, 6))
+ example.MonsterAddHp(builder, 80)
+ example.MonsterAddName(builder, str)
+ example.MonsterAddInventory(builder, inv)
+ example.MonsterAddTest_Type(builder, 1)
+ example.MonsterAddTest(builder, mon2)
+ example.MonsterAddTest4(builder, test4s)
+ mon = example.MonsterEnd(builder)
+
+ final_flatbuffer = bulder.Output()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Unlike C++, Python does not support table creation functions like 'createMonster()'.
+This is to create the buffer without
+using temporary object allocation (since the `Vec3` is an inline component of
+`Monster`, it has to be created right where it is added, whereas the name and
+the inventory are not inline, and **must** be created outside of the table
+creation sequence).
+Structs do have convenient methods that allow you to construct them in one call.
+These also have arguments for nested structs, e.g. if a struct has a field `a`
+and a nested struct field `b` (which has fields `c` and `d`), then the arguments
+will be `a`, `c` and `d`.
+
+Vectors also use this start/end pattern to allow vectors of both scalar types
+and structs:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
+ example.MonsterStartInventoryVector(builder, 5)
+ i = 4
+ while i >= 0:
+ builder.PrependByte(byte(i))
+ i -= 1
+
+ inv = builder.EndVector(5)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The generated method 'StartInventoryVector' is provided as a convenience
+function which calls 'StartVector' with the correct element size of the vector
+type which in this case is 'ubyte' or 1 byte per vector element.
+You pass the number of elements you want to write.
+You write the elements backwards since the buffer
+is being constructed back to front. Use the correct `Prepend` call for the type,
+or `PrependUOffsetT` for offsets. You then pass `inv` to the corresponding
+`Add` call when you construct the table containing it afterwards.
+
+There are `Prepend` functions for all the scalar types. You use
+`PrependUOffset` for any previously constructed objects (such as other tables,
+strings, vectors). For structs, you use the appropriate `create` function
+in-line, as shown above in the `Monster` example.
+
+Once you're done constructing a buffer, you call `Finish` with the root object
+offset (`mon` in the example above). Your data now resides in Builder.Bytes.
+Important to note is that the real data starts at the index indicated by Head(),
+for Offset() bytes (this is because the buffer is constructed backwards).
+If you wanted to read the buffer right after creating it (using
+`GetRootAsMonster` above), the second argument, instead of `0` would thus
+also be `Head()`.
+
+## Text Parsing
+
+There currently is no support for parsing text (Schema's and JSON) directly
+from Python, though you could use the C++ parser through SWIG or ctypes. Please
+see the C++ documentation for more on text parsing.
+
diff --git a/docs/source/doxyfile b/docs/source/doxyfile
index e0ece1d2..202f47dd 100755
--- a/docs/source/doxyfile
+++ b/docs/source/doxyfile
@@ -750,6 +750,7 @@ INPUT = "FlatBuffers.md" \
"CppUsage.md" \
"GoUsage.md" \
"JavaUsage.md" \
+ "PythonUsage.md" \
"Benchmarks.md" \
"WhitePaper.md" \
"Internals.md" \