Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify how to use the ext namespace and RendererEngine #12

Open
lmergner opened this issue Aug 28, 2016 · 4 comments
Open

Clarify how to use the ext namespace and RendererEngine #12

lmergner opened this issue Aug 28, 2016 · 4 comments

Comments

@lmergner
Copy link

I'm trying to build a growler-jinja extension by copying growler-jade and growler.renderer.RendererEngine. However, I'm getting an import error running from the REPL (after a pip install -e .):

>>> from growler.ext import JinjaRenderer
ImportError: No module named 'growler_ext.JinjaRenderer

I don't fully understand setuptools namespaces, so this is partly my own ignorance.

I also see that the api for subclassing RenderEngine has changed subtly. Does the growler-jade source reflect the current api?

After using node's koa framework, I'm excited to try to port my Flask app to Growler.

ubuntu 16
python 3.5.2
virtualenv 15.0.2
setuptools 26.0.0
growler 0.7.5

@akubera
Copy link
Member

akubera commented Aug 28, 2016

Hey, thanks for your interest in my little project! Yeah the growler.ext vs growler_ext is kinda hacky and not straightforward at all to implement. As it works right now, the line from growler.ext import JinjaRenderer calls a function which translates to import growler_ext.JinjaRenderer as JinjaRenderer. This is just a convenience for the user.

Your current implementation is using the MakoRenderer - so changing the contents of that file to JinjaRenderer might be the solution.

Or it might be a bug in setuptools; when installing in editable mode -e it does not create the namespace package growler_ext, so the package could not be found. I had that problem a while ago, but I thought I had fixed it; I guess it was not a universal fix.

I've been working on an 0.8 release I'll push soon, there should be many fixes with the error handling, but the extension importer has not been touched.

I'm sorry about the lack of documentation. You're probably the only other person to have written an extension, so I'm curious to hear your thoughts on what could use some work.

Thanks,
Andrew

@akubera
Copy link
Member

akubera commented Aug 28, 2016

I found and pushed my updated mako renderer code that uses the "new" RenderEngine interface - which isn't nailed down and would really appreciate some thoughts on how it could work better.

The biggest change is the class must not overload __call__ anymore, it's the render_source method that does the templating. The TEMPLATES_DIR classmemeber was removed and replaced with default_file_extensions which gives a clue to the Renderer which files to send to your render_source method.

@lmergner
Copy link
Author

I forgot to push -f my last changes. oops. Knowing that -e flag doesn't work is helpful. I need to think through the tests too. I don't know how much time I have to play around with Growler, but hopefully I can contribute something. I'd like get sqlalchemy running as middleware too.

  1. Is there a reason to distinguish between "extensions" and "middleware"?
  2. When do extensions and middleware take (req, res) and when can they have their own signatures?
  3. Does it make sense to reimplement the base class as abc.ABCMeta? I'm never sure when that's useful.
  4. I've used stevedore to write a library that dynamically loads plugins. That's an option, though setuptools doesn't add another requirement. This is my first time using setuptools, and the docs are not... great.

(Just to fully disclose, I'm not a very good programmer, so if I suggest or ask something ridiculous, please gently correct me. I am a fairly good editor and writer if you need help on the docs, though.)

@akubera
Copy link
Member

akubera commented Aug 30, 2016

Good news! It looks as though I never fully understood "modern" namespace packages. As I now understand it, since Python 3.3, any directory without an init.py file is treated as a namespace package, implicitly. This means my current method of defining growler_ext as a namespace package in setup.py is a deprecated feature.

I don't have to do anything, and as long as other projects define growler_ext in their packages parameter to setup, (i.e. setup(packages=['growler_jinja', 'growler_ext'], ...)), I will get the behavior I want.

This means you don't need growler_ext/JinjaRenderer/__init__.py but just growler_ext/JinjaRenderer.py, which I like a lot better.

And yes, this even works with -e.

The only thing to worry about with this scheme is some package adding __init__.py to their growler_ext folder - which would would ruin the package loader's dynamic loading - but I think that would just be a bug to file with the package maintainers.

It's way too late right now to commit any code with confidence, but I'll probably have some time tomorrow to finally push my changes and do a version bump.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants