Before I start logging an issue, can I just check whether this: /static/css/test.css is expected to work with the latest Flask/Werkzeug? In short, I have an app which uses this setup (not uncommon, surely) and has worked fine with Flask==0.6.1/Werkzeug==0.6.2. With the latest versions of each, those paths now give a 404. A simpler path, eg: /static/test.css appears to work. git bisect pointed to commit 415d1e0cff681f84e90a1af00f96b42aa04e4c89 of Werkzeug, which is now quite a while ago. Before I start either raising an issue or diving in to understand the Werkzeug router, can I ask if I'm missing something? FWIW, this is only an issue in development; my live server does the obvious thing and serves static media via an Apache Alias directive. TJG
Hi, On 11/4/11 5:57 PM, Tim Golden wrote: > Before I start logging an issue, can I just check whether this: > > /static/css/test.css > > is expected to work with the latest Flask/Werkzeug? Yes. > git bisect pointed to commit 415d1e0cff681f84e90a1af00f96b42aa04e4c89 of > Werkzeug, which is now quite a while ago. Before I start either > raising an issue or diving in to understand the Werkzeug router, can > I ask if I'm missing something? This commit and the ones afterwards added the new routing ordering system which is more predictable and should be more reliable. The rule by itself cannot cause this problem but you might have a other rule with similar complexity overlapping it. Eg: /static/<path:foo> versus /<path:foo>/<path:bar>. Could you paste the rules on your url map so I can debug this? (print sorted(app.url_map.iter_rules()) Regards, Armin
Hi, On 11/4/11 8:09 PM, Armin Ronacher wrote: > Eg: /static/<path:foo> versus /<path:foo>/<path:bar>. Could you paste > the rules on your url map so I can debug this? > > (print sorted(app.url_map.iter_rules()) Please do "list" instead of sorted. sorted messes with what I was trying to debug in the first place :D Regards, Armin
On 04/11/2011 23:31, Armin Ronacher wrote: > Hi, > > On 11/4/11 8:09 PM, Armin Ronacher wrote: >> Eg: /static/<path:foo> versus /<path:foo>/<path:bar>. Could you paste >> the rules on your url map so I can debug this? >> >> (print sorted(app.url_map.iter_rules()) > Please do "list" instead of sorted. sorted messes with what I was > trying to debug in the first place :D See below. And, indeed, the 3-part category-item-book precedes the /static rule: /title/edit/ /title/edit/ /data/author/ /favicon.ico/ /robots.txt/ /whatsnew/ /choices/ /contact/ /article/ /initial/ /genres/ /logout/ /search/ /choice/ /about/ /login/ / /initial/<initial>/<book_code>/ /swatch/<type>/<range> /title/<code>/edit/ /title/<code>/edit/ /<category_code>/<item_code>/<book_code>/ /thumbnail/<code> /books.cgi/<path:rest> /whatsnew/<content_code>/ /thumblet/<code> /article/<code>/ /initial/<initial>/ /choices/<path:rest> /search/<book_code>/ /choice/<book_code>/ /static/<path:filename> /genres/<path:rest> /title/<code>/ /cover/<code> /<category_code>/<item_code>/ /<category_code>/ TJG
On 04/11/2011 19:09, Armin Ronacher wrote: >Could you paste > the rules on your url map so I can debug this? Thanks for taking the time. Rules below: /static/<path:filename> /robots.txt/ /favicon.ico/ /books.cgi/<path:rest> /genres/ /genres/<path:rest> /choices/ /choices/<path:rest> / /about/ /login/ /logout/ /contact/ /search/ /search/<book_code>/ /title/edit/ /title/<code>/edit/ /title/edit/ /title/<code>/edit/ /title/<code>/ /article/ /article/<code>/ /whatsnew/ /whatsnew/<content_code>/ /swatch/<type>/<range> /cover/<code> /thumbnail/<code> /thumblet/<code> /initial/ /initial/<initial>/ /initial/<initial>/<book_code>/ /choice/ /choice/<book_code>/ /<category_code>/ /<category_code>/<item_code>/ /<category_code>/<item_code>/<book_code>/ /data/author/ I notice that the (automatic) rule for static files has no trailing slash while the normal Flask behaviour is to redirect to a final slash. I'll try to see if that's significant once I've sent this email: c:\temp>curl --head http://localhost:5000/static/css/goodtoread.css HTTP/1.0 301 MOVED PERMANENTLY Content-Type: text/html; charset=utf-8 Content-Length: 303 Location: http://localhost:5000/static/css/goodtoread.css/ Server: Werkzeug/0.9-dev Python/2.7.1 Date: Fri, 04 Nov 2011 20:32:28 GMT c:\temp>curl --head http://localhost:5000/static/css/goodtoread.css/ HTTP/1.0 404 NOT FOUND Content-Type: text/html; charset=utf-8 Content-Length: 6463 Server: Werkzeug/0.9-dev Python/2.7.1 Date: Fri, 04 Nov 2011 20:32:07 GMT TJG
Hi, On 11/4/11 9:36 PM, Tim Golden wrote: > Thanks for taking the time. Rules below: I will check that ASAP. > I notice that the (automatic) rule for static files has no trailing > slash while the normal Flask behaviour is to redirect to a final > slash. I'll try to see if that's significant once I've sent > this email: If the rule is defined with a trailing slash we will redirect the user if it's missing. Our design principles say: trailing slash indicates more content below this resource. This is compatible with the relative URL rule. If you link to "foo" from "/bar/" it will link to "/bar/foo". In this case "/static/" is a folder but "/static/css/foo.css" is a file. No content below foo.css, as such no trailing slash. Regards, Armin
Is it being caught by the /<category_code>/ endpoint? On Fri, Nov 4, 2011 at 3:36 PM, Tim Golden <mail@timgolden.me.uk> wrote: > On 04/11/2011 19:09, Armin Ronacher wrote: >>Could you paste >> the rules on your url map so I can debug this? > > Thanks for taking the time. Rules below: > > /static/<path:filename> > /robots.txt/ > /favicon.ico/ > /books.cgi/<path:rest> > /genres/ > /genres/<path:rest> > /choices/ > /choices/<path:rest> > / > /about/ > /login/ > /logout/ > /contact/ > /search/ > /search/<book_code>/ > /title/edit/ > /title/<code>/edit/ > /title/edit/ > /title/<code>/edit/ > /title/<code>/ > /article/ > /article/<code>/ > /whatsnew/ > /whatsnew/<content_code>/ > /swatch/<type>/<range> > /cover/<code> > /thumbnail/<code> > /thumblet/<code> > /initial/ > /initial/<initial>/ > /initial/<initial>/<book_code>/ > /choice/ > /choice/<book_code>/ > /<category_code>/ > /<category_code>/<item_code>/ > /<category_code>/<item_code>/<book_code>/ > /data/author/ > > > I notice that the (automatic) rule for static files has no trailing > slash while the normal Flask behaviour is to redirect to a final > slash. I'll try to see if that's significant once I've sent > this email: > > c:\temp>curl --head http://localhost:5000/static/css/goodtoread.css > HTTP/1.0 301 MOVED PERMANENTLY > Content-Type: text/html; charset=utf-8 > Content-Length: 303 > Location: http://localhost:5000/static/css/goodtoread.css/ > Server: Werkzeug/0.9-dev Python/2.7.1 > Date: Fri, 04 Nov 2011 20:32:28 GMT > > c:\temp>curl --head http://localhost:5000/static/css/goodtoread.css/ > HTTP/1.0 404 NOT FOUND > Content-Type: text/html; charset=utf-8 > Content-Length: 6463 > Server: Werkzeug/0.9-dev Python/2.7.1 > Date: Fri, 04 Nov 2011 20:32:07 GMT > > > TJG >
Hi,
On 11/4/11 9:42 PM, Andy Wilson wrote:
> Is it being caught by the /<category_code>/ endpoint?
It should not:
from flask import Flask
app = Flask(__name__)
app.add_url_rule('/<category>/', endpoint='category')
app.add_url_rule('/<category>/<item>', endpoint='category_item')
with app.test_request_context('/static/css/foo.css') as ctx:
assert ctx.request.endpoint == 'static'
assert ctx.request.view_args == {'filename': 'css/foo.css'}
with app.test_request_context('/foo/') as ctx:
assert ctx.request.endpoint == 'category'
assert ctx.request.view_args == {'category': 'foo'}
with app.test_request_context('/foo/bar') as ctx:
assert ctx.request.endpoint == 'category_item'
assert ctx.request.view_args == {'category': 'foo', 'item': 'bar'}
That passes for me.
Regards,
Armin
On Fri, Nov 4, 2011 at 6:24 PM, Armin Ronacher <armin.ronacher@active-4.com> wrote: > Hi, > > On 11/4/11 9:42 PM, Andy Wilson wrote: >> Is it being caught by the /<category_code>/ endpoint? > It should not: > > ... > > That passes for me. > > > Regards, > Armin > Failing for me if you add the rule for /<category>/<item>/<book_code>/ from flask import Flask app = Flask(__name__) app.add_url_rule('/<category>/', endpoint='category') app.add_url_rule('/<category>/<item>/', endpoint='category_item') app.add_url_rule('/<category>/<item>/<book_code>/', endpoint='category_item_bookcode') with app.test_request_context('/static/css/foo.css') as ctx: assert ctx.request.endpoint == 'static' assert ctx.request.view_args == {'filename': 'css/foo.css'} with app.test_request_context('/foo/') as ctx: assert ctx.request.endpoint == 'category' assert ctx.request.view_args == {'category': 'foo'} with app.test_request_context('/foo/bar') as ctx: assert ctx.request.endpoint == 'category_item' assert ctx.request.view_args == {'category': 'foo', 'item': 'bar'} Maybe this is useful: with a url rule for '/<category>/<item>/<book_code>/', ctx.request.endpoint is None but with '/<category>/<item>/<book_code>', ctx.request.endpoint is 'category_item_bookcode'
>> /static/<path:filename>
...
>> /<category_code>/
>> /<category_code>/<item_code>/
>> /<category_code>/<item_code>/<book_code>/
On 04/11/2011 20:42, Andy Wilson wrote:
> Is it being caught by the /<category_code>/ endpoint?
Well I didn't think it would be (on account of /static being
first in the list) but it appears that you're right: if I
munge those /<category_code>/.../ URLs, the stylesheets
show up.
So my question now is... is there an issue with the routing
order? Or do I -- somehow -- have to rework my URL map to
allow for this.
This is not in any way a critical situation for me: my live
site is running Flask 0.6 and doesn't need to upgrade. And
in any case, the live site serves /static files via Apache.
But if I did want to upgrade, say to start using Blueprints,
I'd need to know what approach I should be using.
TJG
On Fri, Nov 4, 2011 at 16:30, Tim Golden <mail@timgolden.me.uk> wrote: > Well I didn't think it would be (on account of /static being > first in the list) but it appears that you're right: if I > munge those /<category_code>/.../ URLs, the stylesheets > show up. > That rule doesn't seem RESTful or fair enough for Flask or anything else. It's a kind of "catch-all". Am I mistaken? -- JA
On 04/11/2011 22:41, Juancarlo Añez wrote: > > > On Fri, Nov 4, 2011 at 16:30, Tim Golden <mail@timgolden.me.uk > <mailto:mail@timgolden.me.uk>> wrote: > > Well I didn't think it would be (on account of /static being > first in the list) but it appears that you're right: if I > munge those /<category_code>/.../ URLs, the stylesheets > show up. > > > That rule doesn't seem RESTful or fair enough for Flask or anything > else. It's a kind of "catch-all". It's not a catch-all; it's a kind of generic route as I have a number of categories, all of which use the same display view and differ only in the model they're presenting (/author/tim-golden, /genre/historical, /age-range/teens etc.). I don't pretend that this is the only or the best way to do this, but it does work. It can, by accident, operate as a catch-all, which is what's happening here: it's matching any three-part path which isn't caught higher up. In this case, however, it 404-s out as early as it can when it detects that what you're requesting doesn't match a known category. (Which is what's happening with the /static paths). As to whether it's RESTful or not, I don't see why it shouldn't be, although I don't pretend to be an authority on RESTfulness. Frankly, though, if someone came back and said: it's not RESTful, I wouldn't be losing too much sleep as a result. :) TJG
On 04/11/2011 16:57, Tim Golden wrote: > Before I start logging an issue, can I just check whether this: > > /static/css/test.css > > is expected to work with the latest Flask/Werkzeug? Just to be clear: I'm saying that this has worked fine for months on a production website running 0.6 but no longer does in a dev setup with newer versions of Flask/Werkzeug TJG
Le 04/11/2011 17:57, Tim Golden a écrit : > Before I start logging an issue, can I just check whether this: > > /static/css/test.css > > is expected to work with the latest Flask/Werkzeug? Hi, I assume that you let Flask handle static files? Then it’s supposed to work since it uses <path:filename> instead of just <filename> in the URL rule. (The later does not allow slashes.) Do you have another view function named "static"? Flask uses this name internally for static files. https://github.com/mitsuhiko/flask/blob/master/flask/app.py#L449 Regards, -- Simon Sapin
On 04/11/2011 17:50, Simon Sapin wrote: > Le 04/11/2011 17:57, Tim Golden a écrit : >> Before I start logging an issue, can I just check whether this: >> >> /static/css/test.css >> >> is expected to work with the latest Flask/Werkzeug? > > Hi, > > I assume that you let Flask handle static files? In dev: yes; in production, they're intercepted by an Apache Alias. > Then it’s supposed to > work since it uses<path:filename> instead of just<filename> in the URL > rule. (The later does not allow slashes.) That's what I'd understood. And this works fine for Flask 0.6, just not for later versions. (See my earlier post for a git bisect guess). > Do you have another view > function named "static"? Flask uses this name internally for static files. Didn't think of that, but no I don't TJG