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

Paths not registering when using Flask factory pattern #208

Open
petargyurov opened this issue Aug 14, 2020 · 1 comment
Open

Paths not registering when using Flask factory pattern #208

petargyurov opened this issue Aug 14, 2020 · 1 comment
Labels
enhancement New feature or request triaged Issue has been reviewed and should be pursued

Comments

@petargyurov
Copy link

petargyurov commented Aug 14, 2020

This is a really frustrating issue, briefly mentioned in #62 . When using the factory pattern to create an app, path registration does not work.

Consider this folder structure:

myproject
├──  myapp
│    ├── __init__.py
│    └──  example
│         ├── __init__.py
│         └──  endpoints.py
├──  venv 
└──  app.py

myapp/__init__.py

from flask import Flask
from flask_rebar import Rebar

rebar = Rebar()
registry = rebar.create_handler_registry()

def create_app():
  app = Flask(__name__)
  rebar.init_app(app)
  return app

myapp/example/endpoints.py

from myapp import registry
from flask_rebar import ResponseSchema
from marshmallow import fields

class TodoSchema(ResponseSchema):
    id = fields.Integer()

@registry.handles(
   rule='/todos/<id>',
   method='GET',
   response_body_schema=TodoSchema()  # for versions <= 1.7.0, use marshal_schema
)
def get_todo(id):
    return {'id': id}

app.py

from myapp import create_app

app = create_app()

if __name__ == '__main__':
	app.run()

The path /todos/<id> does not get registered.

Workaround (?)

So this is clearly some sort of import issue. I have tried creating the registry in various places but I wasn't having much luck. A weird workaround is to re-import the registry inside create_app:

from flask import Flask
from flask_rebar import Rebar

rebar = Rebar()
registry = rebar.create_handler_registry()

def create_app():
  app = Flask(__name__)
  from myapp.example.endpoints import registry  # important to import it BEFORE initialising rebar with the app
  rebar.init_app(app)
  return app

This is a nasty solution - not actually sure why it works - I need to follow up the import order to figure out exactly what is going on. Would you have to import multuple times if you had more modules (i.e.: if there was an example2 module) ?

@petargyurov
Copy link
Author

petargyurov commented Aug 14, 2020

Okay, it seems you could do from myapp.example.endpoints import get_todo instead, which then makes it similar to how you register views with Flask (see here)

I guess that isn't too bad. However, the fact that you have to do it before calling init_app is undesired.

I wonder if you could replicate Flask's registration behaviour when using Blueprints to avoid this?

@RookieRick RookieRick added enhancement New feature or request triaged Issue has been reviewed and should be pursued labels Sep 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request triaged Issue has been reviewed and should be pursued
Projects
None yet
Development

No branches or pull requests

2 participants