Using defaults with app.add_url_rule in Flask
flask, python
Solution
It turns out I need to register two endpoints when using `defaults`.
Because `{'instid': None}` is passed into `get()` in my ContactAPI view as a kwarg, I need to tell Flask to set `instid` to None when the URL `/contact` is hit.
When I hit `/contact/1`, I need to use `<int:instid>`. To do this, I need to remove the `defaults` kwarg in my call to `add_url_rule()`.
manager.py
from xxx import ContactAPI
from xxx.models import Contact
# self.app is my Flask app
# self.session is SQLAlchemy Session
api_name = 'contact'
instance_endpoint = '/%s/<int:instid>' % api_name
collection_endpoint = '/%s' % api_name
methods = ['GET']
api_view = ContactAPI.as_view(api_name, self.session,
Contact, app)
self.app.add_url_rule(instance_endpoint, methods=methods,
view_func=api_view)
self.app.add_url_rule(collection_endpoint, methods=methods,
defaults={'instid': None},
view_func=api_view)
Relevant Werkzeug docs: http://werkzeug.pocoo.org/docs/routing/#werkzeug.routing.Rule
Thanks to `asdf` in the #flask IRC channel for pointing this out.
Problem
I am setting a url endpoint with the following: manager.py ``` from xxx import ContactAPI from xxx.models import Contact # self.app is my Flask app # self.session is SQLAlchemy Session api_name = 'contact' instance_endpoint = '/%s/<int:instid>' % api_name methods = ['GET'] api_view = ContactAPI.as_view(api_name, self.session, Contact, app) self.app.add_url_rule(instance_endpoint, methods=methods, defaults={'instid': None}, view_func=api_view) ``` And overriding `get()` in my ContactAPI class: views.py ``` from flask.views import MethodView class ContactAPI(MethodView): def __init__(self, session, model, app, *args, **kwargs): super(ContactAPI, self).__init__(*args, **kwargs) def get(self, instid): print instid ``` When I hit the URL `/contact/1` I get `instid` printed as `None`. When I remove the `defaults={'instid': None},` line from manager.py, I get `instid` printed as 1. Why is having the defaults line in my call to `add_url_rule` overriding what I'm putting in my URL?