Idea: Optional Cython speed up for ApiStar


I was wondering what do you think about using Cython to Optionally speed up ApiStar,
by using Cython Pure mode no *.py file needs to be touched, only progressively adding *.pxd files,
PXD is markup with type annotations and no code, if a PXD is not present it still works ok,
the more PXD the more speed up, the dependency on Cython can be 100% Optional,
big projects like Kivy and some scientific stuff use Cython since a long time ago,
even just using Cython without any PXD already gives a x2 ~ x3 speed up,
the work to be done is a tiny change on and then commit PXD files when possible…

  • What do you think?. :blush:


Very nice idea!

I wonder how much gain will we have when running some sample APIStar app on Cython using this approach?

Augmenting pure Python modules with PXDs sounds great and as there is a large overlap with Mypy typing, we can also think about PXD generation.


I gave a try and there some issues to take into account:

  • apistar uses inspect module which is well known not to work correctly and more concretely asyncio.iscoroutinefuncion which always gives False when the func is cyfunction compiled with Cython. Besides the handlers must be decorated with cython@bind(True) or parameters inspectors won’t work at all. I have some early stuff in a branch but not yet implemented the compile all *.py and *.pxf *.pxd which is easy to setup but let’s see if it compiles and runs test


A non async version would be a start. I did some stuff templating C++ code from python AST. Cython source code is very coupled and code generation isn’t that good, Cython’s Engine seems somewhat unusable so templating looks for me an resonable way to generate .pxd files for annotating pure Python code.

Applying your considerations maybe we can manage an usable cython generator from mypy.

Then I’d love to see your initial implementation working and maybe I could even contribute.


I was wondering what @tom thinks about the idea ?.. :stuck_out_tongue_closed_eyes:


IMHO this project does not look like the creators though that once upon a time this was going to become a Cython project.We use extensively Cython right now, and the only thing you must do is to not compile handlers, that is, drop them in a somehow module that the compiler skips or on, the rest of the code it’s up top you. If you really need to do Cython on the handler, create a helper, compile it, and make the handler a simpler caller to the opitimized stub.

If creators are fin with it and want to includo cythonized code as Falcon or Hug Frameworks, it is really obvious to do and in my branch I already use compiled handlers. If I get to compile all the code and passing tests I will recall for this. The compilation is optional as long as Cython is no installed.


I’d be happy to see forks take this on. It’s not something I want to have in the core project, given that the maintainance overhead it would add would take away from other feature work.


There ara some minor incompatibilities, not a disruption of errors, we in our team we compiled tornado and it’s workling flawlessly and I can tell you their code base was huge and unaware of Cython at all.


Fair enough. I could consider PRs, but it’s not something I’d commit to accepting without seeing how the trade-off looks. Where would I be looking in the hug or falcon source to see the differences?


So, what do you think of this approach?, I created a Git repo, it has APIStar as Git Submodule,
the idea is to depend only on APIStar and Cython releases (setup_requires),
create a custom that compiles APIStar to Binary on install, and start adding *.PXD,
we can try compiling each Push on Travis, if anyone already has PXD sent them,
it does not take time of APIStar core devs so they can focus on important stuff and new features,
it does not duplicates the effort into another clone fork (because submodule is like a symlink),
no fragmentation, because we dont have any APIStar code,
just depend on it, we can polish the implementation on the go,
in the end it should be a compiling setup script and a bunch of PXD on a package,
open access to contribute to anyone who want to help make APIStar faster!.
(just comment here or on the repo itself or send PR directly).

  • Should it be Git Submodule or Subtree?.
  • What do you think bad idea? good idea?.
  • Anyone want to join the project?


@tom they in Falcon started as Cython-Compatible first, so basically they compile everything and everything should be compilable. In APIStar I see a lot of inspect module usage which is well known to not work properly with cyfunctions. In fact I already realized that handlers not marked as cython.bind(True) decorator won’t work as it tries to inspect its parameters. That’s the most I saw.


Maybe if annotations were used instead of inspect then Cython implemented functions coud work as expected? Going in the same direction of Falcon. Even code like the following one would be a lot easier to do. @danigosa if you put your code in @juancarlospaco repository we can get a more detailed picture even if a fork would be better suited.

In the Cython’s Mypy proposal their implications don’t seems to affect us, so looks like we are good to go in this area of producing .pxd headers for pure Python.


Yeah it might work with pxd headers, in fact it can work even without them (just by marking handlers with cython.bind(True) decorators.